<?php

namespace App\Components;

use App\Models\Dsar\Dsar;
use App\Services\HistoryService;
use App\Services\PdfService;
use App\Services\PrintQueueService;
use Illuminate\Support\Facades\Storage;
use Livewire\Component;

class PrintQueueManager extends Component {

    public array $selectedItems = [];
    public bool $selectAll = false;

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

    public function updatedSelectAll(bool $value): void {
        $ids = app(PrintQueueService::class)->all()->pluck('id')->map(fn ($id) => (string) $id)->toArray();
        $this->selectedItems = $value ? $ids : [];
    }

    public function updatedSelectedItems(): void {
        $total = app(PrintQueueService::class)->all()->count();
        $this->selectAll = $total > 0 && count($this->selectedItems) === $total;
    }

    public function removeItem(PrintQueueService $service, int $id) {
        $this->authorize('print-queue.manage');
        $service->remove($id);
        $this->selectedItems = array_values(array_filter($this->selectedItems, fn ($i) => (int) $i !== $id));
        $this->updatedSelectedItems();
    }

    public function printSelected(PrintQueueService $printQueue, PdfService $pdf, HistoryService $history) {
        $this->authorize('print-queue.manage');

        if (empty($this->selectedItems)) {
            return;
        }

        $selectedIds = array_map('intval', $this->selectedItems);
        $all = $printQueue->all();
        $items = $all->whereIn('id', $selectedIds)->values();

        $paths = $items->map(function ($item) {
            if ($item->file_path) {
                return $item->file_path;
            }

            return $item->document->owner->getDocumentStoragePath() . $item->document->file_name;
        })->filter()->values()->toArray();

        $outputPath = 'temp/print-queue-' . now()->format('YmdHis') . '.pdf';

        $pdf->merge($paths, $outputPath);

        $printQueue->removeMany($selectedIds);

        // Mark any DSAR owners with 'needs posting' status as posted
        $items->each(function ($item) use ($history) {
            $owner = $item->owner;
            if ($owner instanceof Dsar && $owner->status === 'needs posting') {
                $owner->update([
                    'status'    => 'sent',
                    'posted_at' => now(),
                ]);
                $history->add($owner, 'DSAR to "' . ($owner->institution?->display_name ?? 'Unknown') . '" marked as posted via print queue', [
                    'institution' => $owner->institution?->display_name,
                    'posted_at'   => now()->toDateTimeString(),
                ]);
            }
        });

        $this->selectedItems = [];
        $this->selectAll = false;

        return response()->streamDownload(function () use ($outputPath) {
            echo Storage::get($outputPath);
            Storage::delete($outputPath);
        }, 'print-queue.pdf', ['Content-Type' => 'application/pdf']);
    }

    public function placeholder() {
        return <<<'HTML'
        <div class="row">
            <div class="col-12">
                <div class="card">
                    <div class="card-body">
                        <div class="placeholder-glow">
                            <span class="placeholder col-12 mb-2"></span>
                            <span class="placeholder col-12 mb-2"></span>
                            <span class="placeholder col-8"></span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        HTML;
    }

    public function render(PrintQueueService $service) {
        $queueItems = $service->all()->map(function ($item) {
            $isDsar = $item->owner instanceof \App\Models\Dsar\Dsar;

            if ($item->file_path) {
                $typeLabel = $isDsar ? 'DSAR' : 'File';
                $client    = $isDsar ? ($item->owner->claim?->client?->fullName ?? '—') : '—';
                $docName   = $isDsar
                    ? ($item->owner->institution?->display_name ?? basename($item->file_path))
                    : basename($item->file_path);
            } else {
                $typeLabel = $item->document?->type?->display_name ?? '—';
                $client    = $item->document?->owner?->nameFull ?? '—';
                $docName   = $item->document?->display_name ?? $item->document?->file_name ?? '—';
            }

            return [
                'id'          => $item->id,
                'file_path'   => $item->file_path,
                'doc_name'    => $docName,
                'type_label'  => $typeLabel,
                'client'      => $client,
                'user'        => $item->user ? $item->user->name_first . ' ' . $item->user->name_last : '—',
                'created_at'  => $item->created_at?->format('d M Y H:i'),
                'preview_url' => route('print-queue.preview', $item->id),
            ];
        })->all();

        return view('components.print-queue-manager', compact('queueItems'));
    }
}
