<?php

namespace App\Http\Livewire\Locations;

use App\Models\Locations\City;
use App\Models\Locations\Country;
use App\Models\Locations\District;
use App\Models\Locations\Location;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use WireUi\Traits\WireUiActions;

class UpdateProfileLocationForm extends Component
{
    use WireUiActions;


    public $state;
    public $country;
    public $division;
    public $city;
    public $district;
    public $validateCountry = true;
    public $validateDivision = true;
    public $validateCity = true;

    protected $listeners = ['countryToParent', 'divisionToParent', 'cityToParent', 'districtToParent'];

    public function rules()
    {
        return [
        'country' => 'required_if:validateCountry,true|integer',
        'division' => 'required_if:validateDivision,true|nullable|integer',
        'city' => 'required_if:validateCity,true|nullable|integer',
        'district' => 'nullable|integer'
        ];
    }

    /**
    * Prepare the component.
    *
    * @return void
    */
    public function mount()
    {
        $this->state = session('activeProfileType')::find(session('activeProfileId'))
            ->load([
                // 'locations',
                'locations.country',
                'locations.division',
                'locations.city',
                'locations.district']);

            if ($this->state->locations->isNotEmpty()) {
            if ($this->state->locations->first()->country) {
                // For now we only use a single location. In the future this can become an array of locations.
                $this->country = $this->state->locations->first()->country->id;
                $this->dispatch('countryToChildren', $this->country);
            }


            if ($this->state->locations->first()->division) {
                // For now we only use a single location. In the future this can become an array of locations.
                $this->division = $this->state->locations->first()->division->id;
            }


            if ($this->state->locations->first()->city) {
                // For now we only use a single location. In the future this can become an array of locations.
                $this->city = $this->state->locations->first()->city->id;

                // In case a location has a city without a country in the db:
                if (!$this->state->locations->first()->country) {
                    $this->country = City::find($this->city)->country_id;
                }
            }

            if ($this->state->locations->first()->district) {
                // For now we only use a single location. In the future this can become an array of locations.
                $this->district = $this->state->locations->first()->district->id;

                // In case a location has a district without a city in the db:
                if (!$this->state->locations->first()->city) {
                    $this->city = District::find($this->district)->city_id;
                }
            }
        }

        $this->setValidationOptions();
    }


    public function countryToParent($value)
    {
        $this->country = $value;
        $this->setValidationOptions();
    }


    public function divisionToParent($value)
    {
        $this->division = $value;
        $this->setValidationOptions();
    }


    public function cityToParent($value)
    {
        $this->city = $value;
        $this->setValidationOptions();
    }


    public function districtToParent($value)
    {
        $this->district = $value;
        $this->setValidationOptions();
    }


    public function emitLocationToChildren()
    {
        $this->dispatch('countryToChildren', $this->country);
        $this->dispatch('divisionToChildren', $this->division);
        $this->dispatch('cityToChildren', $this->city);
        $this->dispatch('districtToChildren', $this->district);
    }


    public function setValidationOptions()
    {

        $this->validateCountry = $this->validateDivision = $this->validateCity = true;

        // In case no cities or divisions for selected country are seeded in database
        if ($this->country) {

            $countDivisions = Country::find($this->country)->divisions()->count();

            $countCities = Country::find($this->country)->cities()->count();

            if ($countDivisions > 0 && $countCities < 1) {
                $this->validateDivision = true;
                $this->validateCity = false;
            } elseif ($countDivisions < 1 && $countCities > 1) {
                $this->validateDivision = false;
                $this->validateCity = true;
            } elseif ($countDivisions < 1 && $countCities < 1) {
                $this->validateDivision = false;
                $this->validateCity = false;
            } elseif ($countDivisions > 0 && $countCities > 0) {
                $this->validateDivision = false;
                $this->validateCity = true;
            }

        }
        // In case no country is selected, no need to show other validation errors
        if (!$this->country) {
            $this->validateCountry = true;
            $this->validateDivision = $this->validateCity = false;
        }
    }



    public function updateProfileInformation()
    {
        $this->validate();

        // Use a transaction.
        DB::transaction(function (): void {

            $activeProfile = getActiveProfile();

            // CRITICAL SECURITY: Validate user has ownership/access to this profile
            \App\Helpers\ProfileAuthorizationHelper::authorize($activeProfile);

            // For now we only use a single location. In the future this can become an array of locations.
            if ($this->state->locations && $this->state->locations->isNotEmpty()) {
                $location = Location::find($this->state->locations->first()->id);
            } else {
                $location = new Location();
                $activeProfile->locations()->save($location); // create a new location
            }
            // Set country, division, and city IDs on the location
            $location->country_id = $this->country;
            $location->division_id = $this->division;
            $location->city_id = $this->city;
            $location->district_id = $this->district;


            // Save the location with the updated relationship IDs
            $location->save();
            $activeProfile->touch(); // Observer catches this and reindexes search index


            $this->dispatch('saved');
        });
    }



    public function render()
    {
        return view('livewire.locations.update-profile-location-form');
    }
}
