<?php

namespace App\Components\Dsar;

use App\Models\Contact\Hub\ContactMessageAttachment;
use App\Models\Document\Document;
use App\Models\Dsar\DsarEvidenceItem;
use App\Models\Solicitor\Solicitor;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;

class EvidenceViewer extends Component
{
    use AuthorizesRequests;

    public ?ContactMessageAttachment $attachment = null;
    public ?Document $document = null;

    /** Exposed as a reactive Livewire property so Alpine's $wire.itemsData stays current after confirm/dismiss/save. */
    public array $itemsData = [];

    public ?int    $dsarId      = null;
    public ?string $filterState = null; // null | confirmed | dismissed | unreviewed

    // Human annotation form (populated from JS via dispatch)
    public bool    $showAddForm  = false;
    public ?int    $addPage      = null;
    public ?string $addQuote     = null;
    public ?array  $addBbox      = null;
    public string  $addCategory  = 'other';
    public string  $addSeverity  = 'medium';
    public string  $addComment   = '';

    public array $categories = [
        'physical_abuse'        => 'Physical Abuse',
        'emotional_abuse'       => 'Emotional Abuse',
        'financial_abuse'       => 'Financial Abuse',
        'neglect'               => 'Neglect',
        'drug_alcohol'          => 'Drug / Alcohol',
        'self_harm_suicide'     => 'Self-Harm / Suicide',
        'care_history'          => 'Care History',
        'medication_error'      => 'Medication Error',
        'documentation_failure' => 'Documentation Failure',
        'safeguarding'          => 'Safeguarding',
        'other'                 => 'Other',
    ];

    public function mount(
        ?ContactMessageAttachment $attachment = null,
        ?Document $document = null,
        ?int $dsarId = null,
    ): void {
        $this->attachment = $attachment;
        $this->document   = $document;
        $this->dsarId     = $dsarId;
    }

    private function findItem(int $itemId): DsarEvidenceItem
    {
        if ($this->attachment) {
            return DsarEvidenceItem::where('contact_message_attachment_id', $this->attachment->id)->findOrFail($itemId);
        }
        return DsarEvidenceItem::where('document_id', $this->document->id)->findOrFail($itemId);
    }

    public function confirm(int $itemId): void
    {
        $item = $this->findItem($itemId);
        $item->update(['confirmed_at' => now(), 'dismissed_at' => null]);
        $this->dispatch('evidenceItemUpdated');
    }

    public function dismiss(int $itemId): void
    {
        $item = $this->findItem($itemId);
        $item->update(['dismissed_at' => now(), 'confirmed_at' => null]);
        $this->dispatch('evidenceItemUpdated');
    }

    public function saveNote(int $itemId, string $note): void
    {
        $item = $this->findItem($itemId);
        $item->update(['human_notes' => $note]);
    }

    public function openAddForm(?int $page, ?string $quote, ?array $bbox): void
    {
        $this->addPage     = $page;
        $this->addQuote    = $quote;
        $this->addBbox     = $bbox;
        $this->addCategory = 'other';
        $this->addSeverity = 'medium';
        $this->addComment  = '';
        $this->showAddForm = true;
    }

    public function saveEvidence(): void
    {
        $this->validate([
            'addCategory' => 'required|string',
            'addSeverity' => 'required|in:high,medium,low',
            'addComment'  => 'required|string|min:3',
        ]);

        DsarEvidenceItem::create([
            'solicitor_id'                  => app(Solicitor::class)?->id,
            'contact_message_attachment_id' => $this->attachment?->id,
            'document_id'                   => $this->document?->id,
            'dsar_id'                       => $this->dsarId,
            'page'                          => $this->addPage,
            'quote'                         => $this->addQuote,
            'bbox'                          => $this->addBbox,
            'category'                      => $this->addCategory,
            'severity'                      => $this->addSeverity,
            'comment'                       => $this->addComment,
            'source'                        => 'human',
        ]);

        $this->showAddForm = false;
        $this->dispatch('evidenceItemUpdated');
    }

    public function cancelAdd(): void
    {
        $this->showAddForm = false;
    }

    public function deleteItem(int $itemId): void
    {
        $item = $this->findItem($itemId);
        abort_if($item->source !== 'human', 403);
        $item->delete();
        $this->dispatch('evidenceItemUpdated');
    }

    public function render()
    {
        $source = $this->attachment
            ? $this->attachment->evidenceItems()
            : $this->document->evidenceItems();

        $query = $source->orderBy('page')->orderBy('id');

        if ($this->filterState === 'confirmed') {
            $query->confirmed();
        } elseif ($this->filterState === 'dismissed') {
            $query->dismissed();
        } elseif ($this->filterState === 'unreviewed') {
            $query->unreviewed();
        }

        $items = $query->get();

        // Populate the reactive Livewire property so Alpine can read $wire.itemsData
        $this->itemsData = $items->map(fn ($item) => [
            'id'       => $item->id,
            'page'     => $item->page,
            'quote'    => $item->quote,
            'bbox'     => $item->bbox,
            'category' => $item->category,
            'colour'   => DsarEvidenceItem::categoryColour($item->category),
            'severity' => $item->severity,
            'comment'  => $item->comment,
            'source'   => $item->source,
            'state'    => $item->isConfirmed() ? 'confirmed' : ($item->isDismissed() ? 'dismissed' : 'unreviewed'),
        ])->values()->toArray();

        return view('components.dsar.evidence-viewer', [
            'items' => $items, // used by the PHP add-form rendering only
        ]);
    }
}
