<?php

namespace App\Filament\Support;

use Closure;
use Filament\Actions\Action;
use Filament\Support\Enums\Width;
use Filament\Tables\Contracts\HasTable;
use Illuminate\Contracts\View\View;

/**
 * The shared "Print 80mm" header action used on every report surface.
 *
 * Renders the active filtered dataset into a compact receipt layout designed
 * for 80mm thermal POS printers (see
 * resources/views/filament/pages/reports/partials/receipt.blade.php): the
 * action opens a preview modal and the modal's Print button targets only the
 * receipt area via @media print rules, so the browser's print dialog hands
 * the printer nothing but the 80mm slip.
 *
 * The payload resolver receives the Livewire component that owns the table
 * (the report page or the resource's list page), so the receipt ALWAYS
 * reflects the table's currently applied filters — it is built from
 * `getTableQueryForExport()` / `getFilteredSortedTableQuery()` at the moment
 * the modal opens, never from an unfiltered snapshot.
 *
 * Payload shape (see the Blade partial):
 *
 *   [
 *     'title' => string,        // e.g. "Sales Report"
 *     'meta' => string,         // e.g. "Period: This Month"
 *     'rows' => [['label' => string, 'value' => string], ...],
 *     'totals' => [['label' => string, 'value' => string], ...],  // optional
 *     'footer' => string,       // optional
 *   ]
 */
final class ThermalReceipt
{
    /**
     * @param  Closure(HasTable): array<string, mixed>  $payloadResolver
     * @param  Closure(): bool | null  $authorize
     */
    public static function action(string $name, Closure $payloadResolver, ?Closure $authorize = null): Action
    {
        $action = Action::make($name)
            ->label('Print 80mm')
            ->icon('heroicon-m-printer')
            ->color('gray')
            ->modalWidth(Width::Medium)
            ->modalHeading('Receipt Preview')
            ->modalSubmitAction(false)
            ->modalCancelActionLabel('Close')
            ->modalContent(fn (HasTable $livewire): View => view(
                'filament.pages.reports.partials.receipt',
                $payloadResolver($livewire),
            ));

        if ($authorize !== null) {
            $action->authorize($authorize);
        }

        return $action;
    }
}
