<?php

namespace App\Livewire\Suppliers;

use App\Models\Address;
use App\Models\City;
use App\Models\Contact;
use App\Models\Province;
use App\Models\Supplier;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.dashboard')]
class Edit extends Component
{
    public Supplier $supplier;

    // General
    public string $name = '';

    public ?string $contact_person = null;

    public ?string $notes = null;

    // Contact
    public ?string $phone = null;

    public ?string $email = null;

    public ?string $whatsapp = null;

    public ?string $website = null;

    // Address
    public array $provinces = [];

    public array $cities = [];

    public ?int $province_id = null;

    public ?int $city_id = null;

    public ?string $commune = null;

    public ?string $quarter = null;

    public ?string $description = null;

    // UI
    public bool $loading = false;

    public bool $successGeneral = false;

    public bool $successContact = false;

    public bool $successLocation = false;

    public function mount(Supplier $supplier): void
    {
        $this->supplier = $supplier->load(['contact', 'address']);

        // General
        $this->name = (string) $supplier->name;
        $this->contact_person = $supplier->contact_person;
        $this->notes = $supplier->notes;

        // Contact
        if ($supplier->contact) {
            $this->phone = $supplier->contact->phone;
            $this->email = $supplier->contact->email;
            $this->whatsapp = $supplier->contact->whatsapp;
            $this->website = $supplier->contact->website;
        }

        // Provinces list for selects
        $this->provinces = Province::orderBy('name')
            ->get(['id', 'name'])
            ->map(fn ($p) => ['id' => $p->id, 'name' => $p->name])
            ->toArray();

        // Address
        if ($supplier->address) {
            $this->province_id = $supplier->address->province_id;
            $this->city_id = $supplier->address->city_id;
            $this->commune = $supplier->address->commune;
            $this->quarter = $supplier->address->quarter;
            $this->description = $supplier->address->description;
        }

        $this->loadCities();
    }

    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->province_id) {
            $this->cities = City::where('province_id', $this->province_id)
                ->orderBy('name')
                ->get(['id', 'name'])
                ->map(fn($c) => (object) ['id' => $c->id, 'name' => $c->name])
                ->all();
        } else {
            $this->cities = [];
        }
        $this->city_id = null;
    }

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

    public function saveGeneral(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'name' => ['required', 'string', 'max:255'],
                'contact_person' => ['nullable', 'string', 'max:255'],
                'notes' => ['nullable', 'string', 'max:1000'],
            ]);

            $data = [
                'name' => $this->name,
                'contact_person' => $this->contact_person,
                'notes' => $this->notes,
            ];

            if ($this->name !== $this->supplier->name && method_exists($this->supplier, 'generateSlug')) {
                $data['slug'] = Supplier::generateSlug($this->name);
            }

            $this->supplier->update($data);
            $this->successGeneral = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_general', "Une erreur est survenue lors de l'enregistrement des informations générales.");
        } finally {
            $this->loading = false;
        }
    }

    public function saveContact(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'phone' => ['nullable', 'string', 'max:255'],
                'email' => ['nullable', 'email', 'max:255'],
                'whatsapp' => ['nullable', 'string', 'max:255'],
                'website' => ['nullable', 'string', 'max:255'],
            ]);

            $contactData = [
                'phone' => $this->phone,
                'email' => $this->email,
                'whatsapp' => $this->whatsapp,
                'website' => $this->website,
            ];

            $contact = $this->supplier->contact;
            if (! $contact) {
                $contact = Contact::create($contactData);
                $this->supplier->update(['contact_id' => $contact->id]);
            } else {
                $contact->update($contactData);
            }
            $this->successContact = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_contact', "Une erreur est survenue lors de l'enregistrement des informations de contact.");
        } finally {
            $this->loading = false;
        }
    }

    public function saveLocation(): void
    {
        $this->resetErrorBag();
        $this->loading = true;
        try {
            $this->validate([
                'province_id' => ['nullable', 'exists:provinces,id'],
                'city_id' => ['nullable', 'exists:cities,id'],
                'commune' => ['nullable', 'string', 'max:255'],
                'quarter' => ['nullable', 'string', 'max:255'],
                'description' => ['nullable', 'string', 'max:500'],
            ]);

            $addressData = [
                'province_id' => $this->province_id,
                'city_id' => $this->city_id,
                'commune' => $this->commune,
                'quarter' => $this->quarter,
                'description' => $this->description,
            ];

            $address = $this->supplier->address;
            if (! $address) {
                $address = Address::create($addressData);
                $this->supplier->update(['address_id' => $address->id]);
            } else {
                $address->update($addressData);
            }
            $this->successLocation = true;
        } catch (\Throwable $e) {
            report($e);
            $this->addError('error_location', "Une erreur est survenue lors de l'enregistrement de la localisation.");
        } finally {
            $this->loading = false;
        }
    }

    public function render(): \Illuminate\Contracts\View\View
    {
        return view('livewire.suppliers.edit');
    }
}
