<?php

namespace App\Livewire\Website;

use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Website\Models\WebsiteMenu;
use App\Domain\Website\Models\WebsiteMenuItem;
use App\Domain\Website\Models\WebsitePage;
use App\Domain\Website\Services\WebsiteMenuService;
use Livewire\Attributes\Url;
use Livewire\Component;

class MenuManager extends Component
{
    #[Url]
    public string $menuKey = 'primary';

    public bool $showForm = false;

    public ?int $editingId = null;

    public ?int $parentId = null;

    public string $label = '';

    public string $label_en = '';

    public string $link_type = 'page';

    public ?int $website_page_id = null;

    public string $url = '';

    public string $anchor = '';

    public string $icon = '';

    public bool $open_in_new_tab = false;

    public bool $is_visible = true;

    public bool $highlight = false;

    public function mount(): void
    {
        $this->authorize('settings.manage');
    }

    protected function rules(): array
    {
        return [
            'label' => 'required|string|max:255',
            'label_en' => 'nullable|string|max:255',
            'link_type' => 'required|in:page,url,anchor,route,none',
            'website_page_id' => 'nullable|integer|exists:website_pages,id',
            'url' => ['nullable', 'string', 'max:500', 'regex:/^\s*(https?:\/\/|mailto:|tel:|\/(?!\/)|#|\?)/i'],
            'anchor' => 'nullable|string|max:120',
            'icon' => 'nullable|string|max:60',
        ];
    }

    protected function messages(): array
    {
        return [
            'label.required' => __('نص العنصر مطلوب'),
            'link_type.required' => __('نوع الرابط مطلوب'),
            'link_type.in' => __('نوع الرابط غير صالح'),
            'website_page_id.exists' => __('الصفحة المختارة غير موجودة'),
            'url.max' => __('الرابط طويل جدًا'),
            'url.regex' => __('الرابط غير صالح. استخدم رابطًا يبدأ بـ https:// أو مسارًا داخليًا يبدأ بـ /'),
        ];
    }

    public function addItem(?int $parentId = null): void
    {
        $this->resetForm();
        $this->parentId = $parentId;
        $this->showForm = true;
    }

    public function edit(int $id): void
    {
        $item = WebsiteMenuItem::findOrFail($id);

        $this->editingId = $item->id;
        $this->parentId = $item->parent_id;
        $this->label = $item->label ?? '';
        $this->label_en = $item->label_en ?? '';
        $this->link_type = $item->link_type;
        $this->website_page_id = $item->website_page_id;
        $this->url = $item->url ?? '';
        $this->anchor = $item->anchor ?? '';
        $this->icon = $item->icon ?? '';
        $this->open_in_new_tab = $item->open_in_new_tab;
        $this->is_visible = $item->is_visible;
        $this->highlight = $item->highlight;
        $this->showForm = true;
    }

    public function save(WebsiteMenuService $service): void
    {
        $this->authorize('settings.manage');
        $data = $this->validate();

        $data += [
            'open_in_new_tab' => $this->open_in_new_tab,
            'is_visible' => $this->is_visible,
            'highlight' => $this->highlight,
        ];

        try {
            if ($this->editingId) {
                $service->updateItem(WebsiteMenuItem::findOrFail($this->editingId), $data);
                session()->flash('success', __('تم تحديث العنصر'));
            } else {
                $menu = $service->getOrCreate($this->menuKey);
                $parent = $this->parentId ? WebsiteMenuItem::find($this->parentId) : null;
                $service->addItem($menu, $data, $parent);
                session()->flash('success', __('تمت إضافة العنصر'));
            }

            $this->showForm = false;
            $this->resetForm();
        } catch (DomainException $e) {
            $this->addError('label', $e->getMessage());
        }
    }

    public function delete(int $id, WebsiteMenuService $service): void
    {
        $this->authorize('settings.manage');
        $service->deleteItem(WebsiteMenuItem::findOrFail($id));
        session()->flash('success', __('تم حذف العنصر'));
    }

    public function move(int $id, int $direction, WebsiteMenuService $service): void
    {
        $this->authorize('settings.manage');
        $service->move(WebsiteMenuItem::findOrFail($id), $direction);
    }

    public function toggleVisible(int $id, WebsiteMenuService $service): void
    {
        $this->authorize('settings.manage');
        $item = WebsiteMenuItem::findOrFail($id);
        $service->updateItem($item, ['is_visible' => ! $item->is_visible]);
    }

    private function resetForm(): void
    {
        $this->reset([
            'editingId', 'parentId', 'label', 'label_en', 'website_page_id',
            'url', 'anchor', 'icon', 'open_in_new_tab', 'highlight',
        ]);
        $this->link_type = 'page';
        $this->is_visible = true;
        $this->resetErrorBag();
    }

    public function render(WebsiteMenuService $service)
    {
        $menu = $service->getOrCreate($this->menuKey);

        return view('livewire.website.menu-manager', [
            'menu' => $menu,
            'items' => $menu->items()->with('childrenRecursive')->get(),
            'pages' => WebsitePage::orderBy('sort_order')->get(),
            'menuKeys' => WebsiteMenuService::KEYS,
        ]);
    }
}
