<?php

namespace App\Livewire\Templates;

use App\Livewire\Campaigns\EmailTemplateGallery;
use App\Models\EmailTemplate;
use App\Traits\AuthorizesWorkspaceActions;
use Illuminate\Support\Facades\Log;
use Livewire\Attributes\Computed;
use Livewire\Attributes\On;
use Livewire\Component;

/**
 * Reusable template picker — embedded inside any composer that wants
 * an "Insert Template" button.
 *
 * Mounts in a closed state. Parent toggles it open by dispatching
 * `open-template-picker`. When the agent picks a template, this
 * component dispatches `template-inserted` with the rendered HTML
 * payload; the parent composer listens and replaces its body editor
 * content. The picker stays guard-railed to the workspace's
 * forWorkspace() scope so platform + workspace-owned templates both
 * show up here.
 */
class TemplatePicker extends Component
{
    use AuthorizesWorkspaceActions;

    public bool $isOpen = false;
    public string $search = '';
    public string $category = 'all';

    /**
     * #[On] is the Livewire 3 way to subscribe to dispatched events.
     * The legacy `protected $listeners = [...]` array technically
     * still works but had inconsistent behaviour when this component
     * was embedded as a child of another Livewire component (modal
     * appeared briefly then collapsed on the next parent re-render).
     * The attribute-based listener is what Livewire 3 wires through
     * its component lifecycle correctly.
     */
    #[On('open-template-picker')]
    public function open(): void
    {
        // [DIAG] Confirms the open-template-picker event reached the
        // picker server-side. If this line is missing from logs when
        // the customer clicks the Template icon, the dispatch never
        // arrived (Alpine event didn't fire, OR Livewire wasn't
        // listening because wire:key/embedding broke).
        Log::info('TemplatePicker.open', [
            'workspace_id' => auth()->check() ? auth()->user()->active_workspace_id : null,
            'user_id'      => auth()->id(),
        ]);

        if (!$this->authorizeWorkspaceAction('view')) {
            Log::warning('TemplatePicker.open denied — workspace authorize failed');
            return;
        }
        $this->isOpen = true;
        $this->search = '';
        $this->category = 'all';
    }

    public function close(): void
    {
        $this->isOpen = false;
    }

    #[Computed]
    public function templates()
    {
        if (!$this->isOpen) {
            return collect();
        }

        $workspaceId = auth()->user()->active_workspace_id;

        $query = EmailTemplate::forWorkspace($workspaceId);
        if ($this->category !== 'all') {
            $query->where('category', $this->category);
        }
        if ($this->search !== '') {
            $query->where('name', 'like', '%' . $this->search . '%');
        }

        return $query->orderByDesc('usage_count')->orderBy('name')->limit(50)->get();
    }

    #[Computed]
    public function categories(): array
    {
        return EmailTemplateGallery::categories();
    }

    /**
     * The agent picked a template. Render its blocks JSON to HTML and
     * emit it to the parent. We also bump the usage_count so the
     * "Most used templates" sort actually reflects real picks.
     *
     * The parent composer is expected to be a Livewire component that
     * has a #[On('template-inserted')] listener — see ComposeEmail and
     * ReplyComposer for the canonical handlers.
     */
    public function pick(int $id): void
    {
        // [DIAG] Stamp the pick so we can correlate the dispatch with
        // what the browser receives. If this fires but the editor
        // doesn't update, the bridge between Livewire→browser→Quill
        // is the suspect. If THIS doesn't fire, the click handler in
        // the picker view isn't wired correctly.
        Log::info('TemplatePicker.pick: clicked', [
            'template_id'  => $id,
            'workspace_id' => auth()->user()->active_workspace_id,
        ]);

        $workspaceId = auth()->user()->active_workspace_id;
        $template = EmailTemplate::forWorkspace($workspaceId)->find($id);
        if (!$template) {
            Log::warning('TemplatePicker.pick: template not found', ['template_id' => $id]);
            $this->close();
            return;
        }

        // incrementUsage is defined on the model and counts even
        // platform-default templates so the "most used" sort works
        // workspace-by-workspace via the cached column.
        $template->incrementUsage();

        $html = EmailTemplateGallery::renderBlocksPreview($template->blocks ?? []);

        Log::info('TemplatePicker.pick: dispatching template-inserted', [
            'template_id'  => $id,
            'html_length'  => strlen($html),
            'subject'      => $template->name,
        ]);

        $this->dispatch('template-inserted',
            html: $html,
            subject: $template->name,
            templateId: $template->id,
        );

        $this->close();
    }

    public function render()
    {
        return view('livewire.templates.picker');
    }
}
