<?php

namespace App\Livewire\Merchant;

use App\Models\{Setting, Province, City};
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Validate;
use Livewire\Component;

#[Layout('layouts.dashboard')]
class Edit extends Component
{
    // General
    #[Validate('required|string|max:255')]
    public string $merchant_name = '';
    #[Validate('nullable|string|max:255')]
    public ?string $merchant_slogan = null;
    #[Validate('required|string|max:255')]
    public string $merchant_type = '';
    #[Validate('nullable|string|max:255')]
    public ?string $merchant_cnop = null;

    // Contact
    #[Validate('required|string|max:255')]
    public string $merchant_phone = '';
    #[Validate('required|email|max:255')]
    public string $merchant_email = '';

    // Address
    #[Validate('required|exists:provinces,id')]
    public ?int $merchant_province_id = null;
    #[Validate('required|exists:cities,id')]
    public ?int $merchant_city_id = null;
    #[Validate('nullable|string|max:500')]
    public ?string $merchant_address = null;
    #[Validate('nullable|numeric')]
    public $merchant_latitude = null;
    #[Validate('nullable|numeric')]
    public $merchant_longitude = null;

    // UI state
    public array $provinces = [];
    public array $cities = [];
    public bool $successGeneral = false;
    public bool $successContact = false;
    public bool $successAddress = false;
    public bool $loadingGeneral = false;
    public bool $loadingContact = false;
    public bool $loadingAddress = false;
    public bool $locationLoading = false;
    public bool $disabled = false;

    public function mount(): void
    {
        $this->loadProvinces();
        $settings = Setting::first();
        $this->disabled = isMerchantActive();

        if ($settings) {
            $this->merchant_name = (string) $settings->merchant_name;
            $this->merchant_slogan = $settings->merchant_slogan;
            $this->merchant_type = (string) $settings->merchant_type;
            $this->merchant_cnop = $settings->merchant_cnop;

            $this->merchant_phone = (string) $settings->merchant_phone;
            $this->merchant_email = (string) $settings->merchant_email;

            $this->merchant_province_id = $settings->merchant_province_id;
            $this->merchant_address = $settings->merchant_address;
            $this->merchant_latitude = $settings->merchant_latitude;
            $this->merchant_longitude = $settings->merchant_longitude;
            if ($this->merchant_province_id) {
                $this->loadCities();
                $this->merchant_city_id = $settings->merchant_city_id;
            }
        }
    }

    public function loadProvinces(): void
    {
        $this->provinces = Province::orderBy('name')
            ->get(['id', 'name'])
            ->map(fn($p) => (object) ['id' => $p->id, 'name' => $p->name])
            ->all();
    }

    public function loadCities(): void
    {
        if ($this->merchant_province_id) {
            $this->cities = City::where('province_id', $this->merchant_province_id)
                ->orderBy('name')
                ->get(['id', 'name'])
                ->map(fn($c) => (object) ['id' => $c->id, 'name' => $c->name])
                ->all();
        } else {
            $this->cities = [];
        }
        $this->merchant_city_id = null;
    }

    public function updatedMerchantProvinceId(): void
    {
        $this->merchant_city_id = null;
        $this->loadCities();
    }

    // Saves
    public function saveGeneral(): void
    {
        if ($this->disabled) {
            return;
        }
        $this->resetErrorBag();
        $this->validateOnly('merchant_name');
        $this->validateOnly('merchant_type');
        $this->validateOnly('merchant_slogan');
        $this->validateOnly('merchant_cnop');
        $this->loadingGeneral = true;
        try {
            DB::transaction(function () {
                $settings = Setting::first();
                $payload = [
                    'merchant_name' => $this->merchant_name,
                    'merchant_slogan' => $this->merchant_slogan,
                    'merchant_type' => $this->merchant_type,
                    'merchant_cnop' => $this->merchant_cnop,
                ];
                $settings ? $settings->update($payload) : Setting::create($payload);
            });
            $this->successGeneral = true;
        } finally {
            $this->loadingGeneral = false;
        }
    }

    public function saveContact(): void
    {
        if ($this->disabled) {
            return;
        }
        $this->resetErrorBag();
        $this->validateOnly('merchant_phone');
        $this->validateOnly('merchant_email');
        $this->loadingContact = true;
        try {
            DB::transaction(function () {
                $settings = Setting::first();
                $payload = [
                    'merchant_phone' => $this->merchant_phone,
                    'merchant_email' => $this->merchant_email,
                ];
                if ($settings) {
                    $settings->update($payload);
                } else {
                    Setting::create($payload + [
                        'merchant_name' => 'Ma Pharmacie',
                        'merchant_type' => 'pharmacy',
                        'merchant_status' => true,
                        'has_active_subscription' => false,
                    ]);
                }
            });
            $this->successContact = true;
        } finally {
            $this->loadingContact = false;
        }
    }

    public function saveAddress(): void
    {
        if ($this->disabled) {
            return;
        }
        $this->resetErrorBag();
        $this->validateOnly('merchant_province_id');
        $this->validateOnly('merchant_city_id');
        $this->validateOnly('merchant_address');
        $this->validateOnly('merchant_latitude');
        $this->validateOnly('merchant_longitude');
        $this->loadingAddress = true;
        try {
            DB::transaction(function () {
                $settings = Setting::first();
                $payload = [
                    'merchant_province_id' => $this->merchant_province_id,
                    'merchant_city_id' => $this->merchant_city_id,
                    'merchant_address' => $this->merchant_address,
                    'merchant_latitude' => $this->merchant_latitude,
                    'merchant_longitude' => $this->merchant_longitude,
                ];
                $settings ? $settings->update($payload) : Setting::create($payload);
            });
            $this->successAddress = true;
        } finally {
            $this->loadingAddress = false;
        }
    }

    public function render(): \Illuminate\Contracts\View\View
    {
        $merchantTypes = collect(\App\Models\Merchant::MERCHANT_TYPES)
            ->map(fn($t) => (object) ['id' => $t['id'], 'name' => $t['name']]);
        return view('livewire.merchant.edit', compact('merchantTypes'));
    }
}
