<?php

namespace App\Livewire\Ad\PostAd;

use Livewire\Component;
use App\Models\Ad;
use App\Models\City;
use App\Models\Category;
use App\Models\PriceType;
use App\Models\AdCondition;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;
use Illuminate\Support\Str;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Livewire\Attributes\On;
use Livewire\Attributes\Rule;

abstract class BaseAdDetail extends Component implements HasForms
{
    use InteractsWithForms;

    public $id;
    public $ad;
    public $showMainCategories = true;
    public $categories = [];
    #[Rule('required', message: 'messages.t_select_main_category_error')]
    public $parent_category = null;
    public $title = '';
    #[Rule('required', message: 'messages.t_select_ad_category_error')]
    public $category_id = '';
    public $description = '';
    public $price;
    public $price_type_id;
    public $condition_id;
    public bool $display_phone;
    public $phone_number;
    public $type;
    public $for_sale_by;
    public $tags = [];
    public $disable_condition = false;
    public $disable_price_type = false;
    public $price_suffix;
    public $offer_price;

    public function mount($id = null)
    {
        $this->id = $id;
        $this->loadCategories();

        if ($this->id) {
            $this->loadAdDetails($this->id);
            $this->checkRequiredFieldsFilled();
        } else {
            $this->dispatch('required-fields-filled', isFilled: false);
        }
    }

    protected function loadCategories()
    {
        $this->categories = Category::with('subcategories')->whereNull('parent_id')->get();
    }

    protected function loadAdDetails($id)
    {
        $this->ad = Ad::find($id);
        if ($this->ad) {
            $this->fillAdDetails();
        }
    }

    protected function fillAdDetails()
    {
        $this->title = $this->ad->title;
        $this->description = $this->ad->description;
        $this->price = $this->ad->price;
        $this->type = $this->ad->type;
        $this->for_sale_by = $this->ad->for_sale_by;
        $this->tags = $this->ad->tags ? $this->ad->tags : [];
        $this->price_type_id = $this->ad->price_type_id;
        $this->display_phone = $this->ad->display_phone;
        $this->phone_number = $this->ad->phone_number;
        $this->condition_id = $this->ad->condition_id;
        $this->price_suffix = $this->ad->price_suffix;
        $this->offer_price = $this->ad->offer_price;

        if ($this->ad->category_id) {
            $this->category_id = $this->ad->category_id;
            if ($this->ad->category) {
                $this->parent_category = $this->ad->category->parent_id;
                $this->showMainCategories = false;
                $this->disable_condition = $this->ad->adType?->disable_condition;
                $this->disable_price_type = $this->ad->adType?->disable_price_type;
            }
        }
    }

    public function selectCategory($categoryId)
    {
        $this->parent_category = $categoryId;
        $this->showMainCategories = false;
        $this->category_id = '';
    }

    protected function updateAdSlug(Ad $ad, $title)
    {
        $ad->slug = Str::slug(Str::limit($title, 138)) . '-' . substr($ad->id, 0, 8);
        $ad->save();
    }

    public function updateLocation($ad, $value)
    {
        $category = Category::find($value);
        if (($category && $category->default_location == false) && ($category && $category->disable_location == false)) {
            $this->dispatch('enable-location');
        } else {
            if ($category->default_location) {
                $this->updateLocationFromCityId($ad, $category->location_details);
            }
            if ($category->disable_location) {
                $this->dispatch('hide-location');
            }
        }
    }

    protected function updateLocationFromCityId($ad, $locationDetails)
    {
        if (isset($locationDetails['city_id'])) {
            $cityDetail = City::with('state', 'country')->find($locationDetails['city_id']);
            if ($cityDetail) {
                $ad->update([
                    'latitude' => $cityDetail->latitude,
                    'longitude' => $cityDetail->longitude,
                    'location_name' => $cityDetail->name . ' - ' . $cityDetail->state->name,
                    'location_display_name' => "{$cityDetail->name}, {$cityDetail->state->name}, {$cityDetail->country->name}",
                    'city' => $cityDetail->name,
                    'state' => $cityDetail->state->name,
                    'country' => $cityDetail->country->name
                ]);
                $this->dispatch('hide-location');
            }
        }
    }

    public function getRequiredFieldsProperty()
    {
        $requiredFields = [];
        $rules = $this->getRules();
        foreach ($rules as $field => $rule) {
            if (is_array($rule) && in_array('required', $rule)) {
                $requiredFields[] = $field;
            } elseif ($rule == 'required') {
                $requiredFields[] = $field;
            }
        }
        return $requiredFields;
    }

    abstract public function checkRequiredFieldsFilled();

    #[On('next-clicked')]
    public function next()
    {
        $this->validate();
        if (!$this->parent_category) {
            $this->addError('parent_category', __('messages.t_select_main_category'));
            return;
        }
        // $this->dispatch('next-step');

        $this->dispatch('validate-dynamic-fields');
    }

    public function getCurrentCategory()
    {
        if ($this->id) {
            return Category::whereHas('ads', fn($query) => $query->whereId($this->id))->first();
        }
    }

    abstract public function titleInput();
    abstract public function detailForm();
    abstract public function businessSpecificForm();
    abstract public function updated($name, $value);
    abstract public function save();

    public function render()
    {
        return view('livewire.ad.post-ad.ad-detail');
    }
}
