<?php

use App\Enums\QrCodeType;
use App\Models\QrCode;
use App\Models\QrCodeScan;
use Flux\Flux;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

return new #[Title('QR Codes')] class extends Component {
    use WithPagination;

    #[Url(as: 'q')]
    public string $search = '';

    #[Url(as: 'type')]
    public string $typeFilter = 'all';

    #[Url(as: 'status')]
    public string $statusFilter = 'all';

    #[Url(as: 'per_page')]
    public int $perPage = 50;

    /**
     * Reset pagination whenever the search term changes.
     */
    public function updatingSearch(): void
    {
        $this->resetPage();
    }

    /**
     * Reset pagination whenever the type filter changes.
     */
    public function updatingTypeFilter(): void
    {
        $this->resetPage();
    }

    /**
     * Reset pagination whenever the status filter changes.
     */
    public function updatingStatusFilter(): void
    {
        $this->resetPage();
    }

    /**
     * Reset pagination whenever the per-page selection changes.
     */
    public function updatingPerPage(): void
    {
        $this->resetPage();
    }

    /**
     * Toggle a QR code between active and inactive.
     */
    public function toggleActive(int $qrCodeId): void
    {
        $qrCode = QrCode::query()->findOrFail($qrCodeId);

        $qrCode->update(['is_active' => ! $qrCode->is_active]);

        Flux::toast(
            variant: 'success',
            text: $qrCode->is_active ? __('QR code activated.') : __('QR code deactivated.'),
        );
    }

    /**
     * Soft-delete a QR code. Printed copies keep pointing at the short code
     * indefinitely, so this never hard-deletes the row.
     */
    public function delete(int $qrCodeId): void
    {
        QrCode::query()->findOrFail($qrCodeId)->delete();

        Flux::toast(variant: 'success', text: __('QR code deleted.'));
    }

    /**
     * @return LengthAwarePaginator<int, QrCode>
     */
    #[Computed]
    public function codes(): LengthAwarePaginator
    {
        return QrCode::query()
            ->withCount(['scans as human_scan_count' => fn ($query) => $query->humans()])
            ->when($this->search !== '', function ($query) {
                $query->where(function ($query) {
                    $query->where('name', 'like', "%{$this->search}%")
                        ->orWhere('short_code', 'like', "%{$this->search}%")
                        ->orWhere('target_url', 'like', "%{$this->search}%");
                });
            })
            ->when($this->normalizedType() !== 'all', fn ($query) => $query->where('type', $this->normalizedType()))
            ->when($this->normalizedStatus() !== 'all', fn ($query) => $query->where('is_active', $this->normalizedStatus() === 'active'))
            ->latest()
            ->paginate($this->normalizedPerPage());
    }

    /**
     * Stats are computed over the whole table, unaffected by the current
     * filter/search.
     *
     * @return array<string, int>
     */
    #[Computed]
    public function stats(): array
    {
        return [
            'total' => QrCode::query()->count(),
            'active' => QrCode::query()->active()->count(),
            'scans' => QrCodeScan::query()->humans()->whereHas('qrCode')->count(),
            'today' => QrCodeScan::query()->humans()->whereHas('qrCode')->whereDate('scanned_at', now())->count(),
        ];
    }

    /**
     * Map a QR code type to a Flux badge color. `QrCodeType` is owned by
     * another part of this feature and doesn't expose a `badgeColor()` of
     * its own, so the mapping lives here instead.
     */
    public function typeBadgeColor(QrCodeType $type): string
    {
        return match ($type) {
            QrCodeType::Url => 'blue',
            QrCodeType::Text => 'zinc',
            QrCodeType::VCard => 'purple',
            QrCodeType::Wifi => 'sky',
            QrCodeType::Email => 'amber',
            QrCodeType::Phone => 'green',
            QrCodeType::Sms => 'pink',
        };
    }

    /**
     * Any unrecognised type value silently falls back to "all".
     */
    private function normalizedType(): string
    {
        return $this->typeFilter === 'all' || QrCodeType::tryFrom($this->typeFilter) !== null
            ? $this->typeFilter
            : 'all';
    }

    /**
     * Any unrecognised status value silently falls back to "all".
     */
    private function normalizedStatus(): string
    {
        return in_array($this->statusFilter, ['all', 'active', 'inactive'], true) ? $this->statusFilter : 'all';
    }

    /**
     * Any unrecognised per-page value falls back to the default of 50.
     */
    private function normalizedPerPage(): int
    {
        return in_array($this->perPage, [25, 50, 100], true) ? $this->perPage : 50;
    }

    protected function view($data = [])
    {
        return app('view')->file('/Users/dineshmali/code/pushpvatikaflorist1/storage/framework/views/livewire/views/c8f390f4.blade.php', $data);
    }
}; 