<?php

namespace App\Livewire\Customers;

use App\Models\Address;
use App\Models\City;
use App\Models\Contact;
use App\Models\Customer;
use App\Models\Merchant;
use App\Models\Province;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Layout;
use Livewire\Component;

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

    // General Information
    public $name;

    public $notes;

    // Contact Information
    public $phone;

    public $email;

    // Address Information
    public $provinces;

    public $cities;

    public $province_id;

    public $city_id;

    public $commune;

    public $quarter;

    public $description;

    // UI state
    public $general_loading = false;

    public $contact_loading = false;

    public $address_loading = false;

    public $general_success = false;

    public $contact_success = false;

    public $address_success = false;

    public $general_success_message = '';

    public $contact_success_message = '';

    public $address_success_message = '';

    public $general_error = false;

    public $contact_error = false;

    public $address_error = false;

    public $general_error_message = '';

    public $contact_error_message = '';

    public $address_error_message = '';

    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'notes' => ['nullable', 'string', 'max:1000'],
            'phone' => ['required', 'string', 'max:20'],
            'email' => ['nullable', 'email', 'max:255'],
            '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'],
        ];
    }

    public function mount(Customer $customer)
    {
        // Ensure customer belongs to current merchant (prevents cross-tenant edits)
        // No merchant filtering needed for single-tenant app

        $this->customer = $customer;

        // Load general information
        $this->name = $customer->name;
        $this->notes = $customer->notes;

        // Load contact information
        $this->phone = $customer->contact?->phone ?? '';
        $this->email = $customer->contact?->email ?? '';

        // Load address information
        $this->provinces = Province::orderBy('name')->get()->map(function ($province) {
            return (object) ['id' => $province->id, 'name' => $province->name];
        });

        $this->province_id = $customer->address?->province_id ?? null;
        $this->city_id = $customer->address?->city_id ?? null;
        $this->commune = $customer->address?->commune ?? null;
        $this->quarter = $customer->address?->quarter ?? null;
        $this->description = $customer->address?->description ?? null;

        // Load cities if province is selected
        if ($this->province_id) {
            $this->cities = City::where('province_id', $this->province_id)
                ->orderBy('name')
                ->get()
                ->map(function ($city) {
                    return (object) ['id' => $city->id, 'name' => $city->name];
                });
        } else {
            $this->cities = collect();
        }
    }

    public function updatedProvinceId($provinceId): void
    {
        $this->cities = $provinceId ? City::where('province_id', $provinceId)
            ->orderBy('name')
            ->get()
            ->map(function ($city) {
                return (object) ['id' => $city->id, 'name' => $city->name];
            }) : collect();

        // Clear deeper fields when province changes
        $this->reset(['city_id', 'commune', 'quarter', 'description']);
    }

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

        $this->general_loading = true;
        $this->general_success = false;
        $this->general_error = false;
        $this->general_success_message = '';
        $this->general_error_message = '';

        try {
            $this->customer->update([
                'name' => $this->name,
                'notes' => $this->notes,
            ]);

            $this->general_success = true;
            $this->general_success_message = 'Informations générales mises à jour avec succès';
        } catch (\Throwable $e) {
            report($e);
            $this->general_error = true;
            $this->general_error_message = 'Une erreur est survenue lors de la mise à jour des informations générales.';
        } finally {
            $this->general_loading = false;
        }
    }

    public function saveContact()
    {
        $this->resetErrorBag();
        $this->validate([
            'phone' => ['required', 'string', 'max:20'],
            'email' => ['nullable', 'email', 'max:255'],
        ]);

        $this->contact_loading = true;
        $this->contact_success = false;
        $this->contact_error = false;
        $this->contact_success_message = '';
        $this->contact_error_message = '';

        try {
            DB::transaction(function () {
                // Update or create contact record
                if ($this->customer->contact) {
                    $this->customer->contact->update([
                        'phone' => $this->phone,
                        'email' => $this->email,
                    ]);
                } else {
                    $contact = Contact::create([
                        'phone' => $this->phone,
                        'email' => $this->email,
                    ]);
                    $this->customer->update(['contact_id' => $contact->id]);
                }
            });

            $this->contact_success = true;
            $this->contact_success_message = 'Informations de contact mises à jour avec succès';
        } catch (\Throwable $e) {
            report($e);
            $this->contact_error = true;
            $this->contact_error_message = 'Une erreur est survenue lors de la mise à jour des informations de contact.';
        } finally {
            $this->contact_loading = false;
        }
    }

    public function saveAddress()
    {
        $this->resetErrorBag();
        $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'],
        ]);

        $this->address_loading = true;
        $this->address_success = false;
        $this->address_error = false;
        $this->address_success_message = '';
        $this->address_error_message = '';

        try {
            DB::transaction(function () {
                // Update or create address record
                if ($this->customer->address) {
                    $this->customer->address->update([
                        'province_id' => $this->province_id,
                        'city_id' => $this->city_id,
                        'commune' => $this->commune,
                        'quarter' => $this->quarter,
                        'description' => $this->description,
                    ]);
                } else {
                    $address = Address::create([
                        'province_id' => $this->province_id,
                        'city_id' => $this->city_id,
                        'commune' => $this->commune,
                        'quarter' => $this->quarter,
                        'description' => $this->description,
                    ]);
                    $this->customer->update(['address_id' => $address->id]);
                }
            });

            $this->address_success = true;
            $this->address_success_message = 'Adresse mise à jour avec succès';
        } catch (\Throwable $e) {
            report($e);
            $this->address_error = true;
            $this->address_error_message = 'Une erreur est survenue lors de la mise à jour de l\'adresse.';
        } finally {
            $this->address_loading = false;
        }
    }

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