<?php

namespace App\Components\Template;

use App\Enum\Contact\MessageChannel;
use App\Models\Contact\ContactCategory;
use App\Models\Contact\ContactTemplate;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithPagination;

class Index extends Component {
    use WithPagination;
    use AuthorizesRequests;

    public $showCategoryForm = false;
    public $newCategoryName;

    /* Category panel state */
    public bool $showCategoryPanel = false;
    public ?int $editingCategoryId = null;
    public ?string $categoryName = null;

    /* Filters */
    public ?string $filterChannel = null;
    public ?int $filterCategoryId = null;
    public ?string $filterActive = null;
    public ?string $search = null;

    protected string $paginationTheme = 'bootstrap';

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

    public function updatingSearch(): void {
        $this->resetPage();
    }

    public function updatingFilterChannel(): void {
        $this->resetPage();
    }

    public function updatingFilterCategoryId(): void {
        $this->resetPage();
    }

    public function updatingFilterActive(): void {
        $this->resetPage();
    }

    /* ---------- Category CRUD ---------- */

    public function openCategoryPanel(): void {
        $this->showCategoryPanel = true;
        $this->cancelCategoryEdit();
    }

    public function cancelCategoryEdit(): void {
        $this->editingCategoryId = null;
        $this->categoryName = null;
        $this->resetErrorBag(['categoryName']);
    }

    public function closeCategoryPanel(): void {
        $this->showCategoryPanel = false;
        $this->cancelCategoryEdit();
    }

    public function newCategory(): void {
        $this->authorize('templates.create');
        $this->editingCategoryId = 0;
        $this->categoryName = '';
        $this->resetErrorBag(['categoryName']);
    }

    public function editCategory(int $id): void {
        $this->authorize('templates.edit');
        $cat = ContactCategory::findOrFail($id);
        $this->editingCategoryId = $cat->id;
        $this->categoryName = $cat->name;
        $this->resetErrorBag(['categoryName']);
    }

    public function saveCategory(): void {
        $this->authorize($this->editingCategoryId ? 'templates.edit' : 'templates.create');

        $this->validate([
            'categoryName' => [
                'required',
                'string',
                'max:100',
                Rule::unique('contact_categories', 'name')
                    ->ignore($this->editingCategoryId ?: null),
            ],
        ]);

        if ($this->editingCategoryId) {
            ContactCategory::findOrFail($this->editingCategoryId)
                ->update(['name' => $this->categoryName]);
            session()->flash('category_msg', 'Category updated.');
        } else {
            ContactCategory::create(['name' => $this->categoryName]);
            session()->flash('category_msg', 'Category added.');
        }

        $this->cancelCategoryEdit();
    }

    public function deleteCategory(int $id): void {
        $this->authorize('templates.delete');

        $category = ContactCategory::withCount('templates')->findOrFail($id);

        if ($category->templates_count > 0) {
            $this->addError(
                'categoryName',
                "Cannot delete \"{$category->name}\" — {$category->templates_count} template(s) are still assigned to it."
            );
            return;
        }

        $category->delete();
        session()->flash('category_msg', 'Category deleted.');

        if ($this->filterCategoryId === $id) {
            $this->filterCategoryId = null;
            $this->resetPage();
        }
    }

    /* ---------- Template actions (unchanged) ---------- */

    public function deleteTemplate(int $id): void {
        $this->authorize('templates.delete');
        ContactTemplate::destroy($id);
    }

    public function duplicate(int $id): void {
        $this->authorize('templates.create');
        $template = ContactTemplate::findOrFail($id);

        $copy = $template->replicate(['slug']);
        $copy->slug = (string)\Illuminate\Support\Str::uuid();
        $copy->name = $template->name . ' (copy)';
        $copy->key = $template->key ? $template->key . '_copy_' . substr(md5(uniqid()), 0, 6) : null;
        $copy->is_active = false;
        $copy->save();
    }

    public function toggleActive(int $id): void {
        $this->authorize('templates.edit');
        $template = ContactTemplate::findOrFail($id);
        $template->is_active = !$template->is_active;
        $template->save();
    }

    public function render() {
        $templates = ContactTemplate::query()
            ->with(['category', 'defaultSenderEmail', 'defaultSmsSender'])
            ->withCount('triggers')
            ->when($this->filterChannel, fn($q) => $q->where('channel', $this->filterChannel))
            ->when($this->filterCategoryId, fn($q) => $q->where('category_id', $this->filterCategoryId))
            ->when($this->filterActive !== null && $this->filterActive !== '', function ($q) {
                $q->where('is_active', $this->filterActive === '1');
            })
            ->when($this->search, fn($q) => $q->where(function ($w) {
                $w->where('name', 'like', "%{$this->search}%")
                    ->orWhere('key', 'like', "%{$this->search}%")
                    ->orWhere('subject', 'like', "%{$this->search}%");
            }))
            ->orderBy('channel')
            ->orderBy('name')
            ->paginate(20);

        $categories = ContactCategory::withCount('templates')
            ->orderBy('name')
            ->get();

        return view('components.template.index', [
            'templates' => $templates,
            'categories' => $categories,
            'channels' => MessageChannel::cases(),
        ]);
    }
}
