<?php

namespace App\Http\Livewire\Calls;

use App\Models\Call;
use App\Models\CallTranslation;
use App\Models\Locations\Location;
use Illuminate\Support\Facades\App;
use Livewire\Component;
use WireUi\Traits\WireUiActions;

class Edit extends Component
{
    use WireUiActions;

    public Call $call;

    public string $content = '';
    public ?string $till = null;
    public ?int $tagId = null;
    public bool $isPublic = false;

    // Location fields
    public $country  = null;
    public $division = null;
    public $city     = null;
    public $district = null;

    public bool $showModal = false;
    public bool $showDeleteConfirm = false;
    public bool $compact = false;

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

    protected function messages(): array
    {
        return [
            'till.required'       => __('Expire date is required.'),
            'till.date'           => __('Expire date must be a valid date.'),
            'till.after'          => __('Expire date must be in the future.'),
            'till.before_or_equal'=> __('Expire date exceeds the maximum allowed period.'),
        ];
    }

    public function getTillMaxDays(): ?int
    {
        $callableType = $this->call->callable_type ?? session('activeProfileType');
        if ($callableType && $callableType !== \App\Models\User::class) {
            return timebank_config('calls.till_max_days_non_user');
        }
        return timebank_config('calls.till_max_days');
    }

protected function rules(): array
    {
        $tillMaxDays = $this->getTillMaxDays();
        $tillRule = 'required|date|after:today';
        if ($tillMaxDays !== null) {
            $tillRule .= '|before_or_equal:' . now()->addDays($tillMaxDays)->format('Y-m-d');
        }

        return [
            'content' => ['required', 'string', 'max:' . timebank_config('calls.content_max_input', 200)],
            'till'    => $tillRule,
            'tagId'   => 'required|integer|exists:taggable_tags,tag_id',
            'country' => 'required|integer|exists:countries,id',
            'city'    => 'nullable|integer|exists:cities,id',
            'district'=> 'nullable|integer|exists:districts,id',
        ];
    }

    public function openModal(): void
    {
        $this->resetValidation();

        // Pre-fill from existing call
        $this->tagId     = $this->call->tag_id;
        $this->content   = $this->call->translations->where('locale', App::getLocale())->first()?->content
            ?? $this->call->translations->first()?->content
            ?? '';
        $this->till      = $this->call->till?->format('Y-m-d');
        $this->isPublic = (bool) $this->call->is_public;

        $location = $this->call->location;
        $this->country  = $location?->country_id;
        $this->division = $location?->division_id;
        $this->city     = $location?->city_id;
        $this->district = $location?->district_id;

        $this->showModal = true;
    }

    public function callTagSelected(int $tagId): void
    {
        $this->tagId = $tagId;
        $this->resetValidation('tagId');
    }

    public function callTagCleared(): void
    {
        $this->tagId = null;
    }

    public function countryToParent($value): void  { $this->country  = $value ?: null; }
    public function divisionToParent($value): void { $this->division = $value ?: null; }
    public function cityToParent($value): void     { $this->city     = $value ?: null; }
    public function districtToParent($value): void { $this->district = $value ?: null; }

    public function confirmDelete(): void
    {
        $this->showDeleteConfirm = true;
    }

    public function delete(): void
    {
        $activeProfile = getActiveProfile();
        if (!$activeProfile ||
            get_class($activeProfile) !== $this->call->callable_type ||
            $activeProfile->id !== $this->call->callable_id) {
            abort(403);
        }

        $this->call->unsearchable();
        $this->call->translations()->delete();
        $this->call->delete();

        $this->redirect(route('home'));
    }

    public function save(): void
    {
        // Only the callable owner may edit
        $activeProfile = getActiveProfile();
        if (!$activeProfile ||
            get_class($activeProfile) !== $this->call->callable_type ||
            $activeProfile->id !== $this->call->callable_id) {
            abort(403);
        }

        $this->validate();

        // Resolve or create a standalone Location record
        $locationId = null;
        if ($this->country || $this->city) {
            $attributes = array_filter([
                'country_id'  => $this->country  ?: null,
                'division_id' => $this->division ?: null,
                'city_id'     => $this->city     ?: null,
                'district_id' => $this->district ?: null,
            ]);
            $location = Location::whereNull('locatable_id')
                ->whereNull('locatable_type')
                ->where($attributes)
                ->first();
            if (!$location) {
                $location = new Location($attributes);
                $location->save();
            }
            $locationId = $location->id;
        }

        $this->call->update([
            'tag_id'      => $this->tagId,
            'location_id' => $locationId,
            'till'        => $this->till ?: null,
            'is_public'  => $this->isPublic,
        ]);

        // Update or create translation for current locale
        CallTranslation::updateOrCreate(
            ['call_id' => $this->call->id, 'locale' => App::getLocale()],
            ['content' => $this->content ?: null]
        );

        $this->call->searchable();

        $this->showModal = false;

        $this->notification()->success(
            title: __('Saved'),
            description: __('Your Call has been updated.')
        );

        $this->redirect(request()->header('Referer') ?: route('call.show', ['id' => $this->call->id]));
    }

    public function render()
    {
        return view('livewire.calls.edit', [
            'profileName' => $this->call->callable?->name ?? '',
        ]);
    }
}
