<?php

namespace App\Livewire\Branches;

use App\Domain\Identity\Models\Branch;
use App\Domain\Identity\Services\BranchService;
use App\Domain\Shared\Exceptions\DomainException;
use App\Models\User;
use Illuminate\Validation\Rule;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('إدارة الفرع')]
class BranchForm extends Component
{
    public ?Branch $branch = null;
    public bool $editing = false;

    public string $name = '';
    public string $name_ar = '';
    public string $code = '';
    public string $phone = '';
    public string $email = '';
    public string $address = '';
    public string $city = '';
    public ?string $latitude = null;
    public ?string $longitude = null;
    public ?int $manager_id = null;
    public bool $is_main = false;
    public bool $is_active = true;

    // Operating hours
    public array $operating_hours = [];

    public function mount(?Branch $branch = null): void
    {
        $days = ['saturday', 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday'];

        if ($branch && $branch->exists) {
            $this->authorize('branches.update');
            $this->branch = $branch;
            $this->editing = true;
            $this->name = $branch->name;
            $this->name_ar = $branch->name_ar;
            $this->code = $branch->code;
            $this->phone = $branch->phone ?? '';
            $this->email = $branch->email ?? '';
            $this->address = $branch->address ?? '';
            $this->city = $branch->city ?? '';
            $this->latitude = $branch->latitude;
            $this->longitude = $branch->longitude;
            $this->manager_id = $branch->manager_id;
            $this->is_main = $branch->is_main;
            $this->is_active = $branch->is_active;
            $this->operating_hours = $branch->operating_hours ?? [];
        } else {
            $this->authorize('branches.create');
        }

        // Initialize empty operating hours structure
        foreach ($days as $day) {
            if (!isset($this->operating_hours[$day])) {
                $this->operating_hours[$day] = ['open' => '08:00', 'close' => '22:00', 'closed' => false];
            }
        }
    }

    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'name_ar' => 'required|string|max:255',
            'code' => 'required|string|max:10',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:255',
            'address' => 'nullable|string',
            'city' => 'nullable|string|max:100',
            'latitude' => 'nullable|numeric|between:-90,90',
            'longitude' => 'nullable|numeric|between:-180,180',
            // exists:users,id is a raw query: no global scope reaches it, so it
            // accepted a user id from another academy while the picker below
            // only ever showed this one's. No branch clause on purpose — branch
            // management is cross-branch by definition and a branch's manager
            // need not already sit in it.
            'manager_id' => ['nullable', Rule::exists('users', 'id')
                ->where('academy_id', app('current_academy')->id)
                ->whereNull('deleted_at')],
            'is_main' => 'boolean',
            'is_active' => 'boolean',
        ];
    }

    public function messages(): array
    {
        return [
            'name.required' => 'اسم الفرع بالإنجليزية مطلوب',
            'name_ar.required' => 'اسم الفرع بالعربية مطلوب',
            'code.required' => 'كود الفرع مطلوب',
            'code.max' => 'كود الفرع يجب ألا يتجاوز 20 حرف',
            'email.email' => 'صيغة البريد الإلكتروني غير صحيحة',
            'latitude.between' => 'خط العرض يجب أن يكون بين -90 و 90',
            'longitude.between' => 'خط الطول يجب أن يكون بين -180 و 180',
        ];
    }

    public function save(BranchService $branchService): void
    {
        // Re-checked at the write: the route's permission middleware is not
        // persistent, so it does not run on the Livewire update request that
        // carries this call.
        $this->authorize($this->editing ? 'branches.update' : 'branches.create');

        $this->validate();

        $hours = collect($this->operating_hours)
            ->reject(fn ($h) => $h['closed'] ?? false)
            ->map(fn ($h) => ['open' => $h['open'], 'close' => $h['close']])
            ->toArray();

        $data = [
            'name' => $this->name,
            'name_ar' => $this->name_ar,
            'code' => $this->code,
            'phone' => $this->phone ?: null,
            'email' => $this->email ?: null,
            'address' => $this->address ?: null,
            'city' => $this->city ?: null,
            'latitude' => $this->latitude ? (float) $this->latitude : null,
            'longitude' => $this->longitude ? (float) $this->longitude : null,
            'manager_id' => $this->manager_id,
            'is_main' => $this->is_main,
            'is_active' => $this->is_active,
            'operating_hours' => $hours ?: null,
        ];

        try {
            if ($this->editing) {
                $branchService->update($this->branch, $data, auth()->user());
                session()->flash('success', 'تم تحديث الفرع بنجاح');
            } else {
                $branchService->create($data, auth()->user());
                session()->flash('success', 'تم إنشاء الفرع بنجاح');
            }

            $this->redirect(route('branches.list'), navigate: true);
        } catch (DomainException $e) {
            session()->flash('error', $e->getMessage());
        }
    }

    public function render()
    {
        return view('livewire.branches.branch-form', [
            'managers' => User::where('status', 'active')->orderBy('name_ar')->get(['id', 'name', 'name_ar']),
        ]);
    }
}
