<?php

namespace App\Components\Contact;

use App\Jobs\Synapse\ClassifyInboundEmailJob;
use App\Models\Contact\Hub\ContactMessage;
use App\Models\Contact\Hub\ContactMessageAttachment;
use App\Models\Dsar\Dsar;
use App\Models\Solicitor\Solicitor;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

class InboxTriage extends Component
{
    use AuthorizesRequests, WithPagination;

    // Active triage tab
    #[Url]
    public string $tab = 'dsar_evidence';

    // Open message in right panel
    #[Url]
    public ?int $messageId = null;

    // Search within the active tab list
    public string $search = '';

    // Show actioned / dismissed items too
    public bool $showActioned = false;

    // DSAR link search (unknown tab)
    public string $dsarSearch = '';

    // ── Actions ──────────────────────────────────────────────────────────────

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

    public function setTab(string $tab): void
    {
        $this->tab      = $tab;
        $this->messageId = null;
        $this->search    = '';
        $this->dsarSearch = '';
        $this->resetPage();
    }

    public function openMessage(int $id): void
    {
        $this->messageId = $id;
        $this->dsarSearch = '';

        // Auto-progress from pending → in_progress
        ContactMessage::where('id', $id)
            ->where('triage_status', 'pending')
            ->update(['triage_status' => 'in_progress']);
    }

    public function markActioned(int $id): void
    {
        $this->authorizeMessage($id);

        ContactMessage::where('id', $id)->update(['triage_status' => 'actioned']);

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

    public function dismiss(int $id): void
    {
        $this->authorizeMessage($id);

        ContactMessage::where('id', $id)->update(['triage_status' => 'dismissed']);

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

    public function linkToDsar(int $messageId, int $dsarId): void
    {
        $this->authorizeMessage($messageId);

        $solicitorId = app(Solicitor::class)->id;

        // Verify DSAR belongs to this solicitor
        $dsar = Dsar::withoutGlobalScopes()
            ->where('id', $dsarId)
            ->whereHas('claim', fn ($q) => $q->where('solicitor_id', $solicitorId))
            ->first();

        if (!$dsar) {
            return;
        }

        ContactMessage::where('id', $messageId)->update([
            'messageable_type' => Dsar::class,
            'messageable_id'   => $dsar->id,
            'triage_queue'     => 'dsar_evidence',
            'triage_status'    => 'pending',
        ]);

        $this->tab        = 'dsar_evidence';
        $this->messageId  = $messageId;
        $this->dsarSearch = '';
    }

    public function unlinkFromDsar(int $id): void
    {
        $this->authorizeMessage($id);

        ContactMessage::where('id', $id)->update([
            'messageable_type' => null,
            'messageable_id'   => null,
            'triage_queue'     => 'unknown',
            'triage_status'    => 'pending',
        ]);

        $this->tab       = 'unknown';
        $this->messageId = $id;
    }

    public function reclassify(int $id): void
    {
        $this->authorizeMessage($id);
        ClassifyInboundEmailJob::dispatch($id, force: true);
    }

    public function saveAttachmentNote(int $attachmentId, string $text): void
    {
        $attachment = ContactMessageAttachment::whereHas('message', function ($q) {
            $q->where('solicitor_id', app(Solicitor::class)->id);
        })->findOrFail($attachmentId);

        $attachment->update([
            'extracted_text'    => trim($text),
            'extraction_status' => 'manual',
        ]);
    }

    public function updatedSearch(): void
    {
        $this->resetPage();
        $this->messageId = null;
    }

    // ── Render ───────────────────────────────────────────────────────────────

    public function render()
    {
        $solicitorId = app(Solicitor::class)->id;

        // Tab counts (pending + in_progress only)
        $counts = ContactMessage::inbound()
            ->where('solicitor_id', $solicitorId)
            ->whereIn('triage_status', ['pending', 'in_progress'])
            ->whereIn('triage_queue', ['dsar_evidence', 'dsar_updates', 'dsar_needs_research', 'unknown'])
            ->selectRaw('triage_queue, count(*) as total')
            ->groupBy('triage_queue')
            ->pluck('total', 'triage_queue');

        $messages = ContactMessage::inbound()
            ->where('solicitor_id', $solicitorId)
            ->where('triage_queue', $this->tab)
            ->when(
                !$this->showActioned,
                fn ($q) => $q->whereIn('triage_status', ['pending', 'in_progress']),
                fn ($q) => $q->whereIn('triage_status', ['pending', 'in_progress', 'actioned', 'dismissed'])
            )
            ->when($this->search, fn ($q) => $q->where(function ($q) {
                $q->where('subject', 'like', "%{$this->search}%")
                  ->orWhere('from_email', 'like', "%{$this->search}%")
                  ->orWhere('body_text', 'like', "%{$this->search}%");
            }))
            ->withCount('attachments')
            ->orderByRaw("FIELD(triage_status, 'in_progress', 'pending', 'actioned', 'dismissed')")
            ->orderByDesc('created_at')
            ->paginate(30);

        $openMessage = $this->messageId
            ? ContactMessage::with(['attachments', 'messageable'])
                ->where('solicitor_id', $solicitorId)
                ->find($this->messageId)
            : null;

        // DSAR search results for the "link to DSAR" panel (unknown tab)
        $dsarResults = [];
        if ($this->tab === 'unknown' && $openMessage && strlen($this->dsarSearch) >= 2) {
            $dsarResults = Dsar::withoutGlobalScopes()
                ->whereHas('claim', fn ($q) => $q->where('solicitor_id', $solicitorId))
                ->where('status', '!=', 'completed')
                ->where(function ($q) {
                    $q->where('reference', 'like', "%{$this->dsarSearch}%")
                      ->orWhereHas('claim.client', fn ($q) => $q->where('name_first', 'like', "%{$this->dsarSearch}%")
                          ->orWhere('name_last', 'like', "%{$this->dsarSearch}%"));
                })
                ->with(['claim.client', 'institution'])
                ->limit(8)
                ->get();
        }

        return view('components.contact.inbox-triage', [
            'counts'      => $counts,
            'messages'    => $messages,
            'openMessage' => $openMessage,
            'dsarResults' => $dsarResults,
        ]);
    }

    // ── Helpers ──────────────────────────────────────────────────────────────

    private function authorizeMessage(int $id): void
    {
        ContactMessage::where('id', $id)
            ->where('solicitor_id', app(Solicitor::class)->id)
            ->firstOrFail();
    }
}
