<?php

namespace App\Filament\Concerns;

use App\Models\Consignment;
use App\Models\DeliveryNote;
use App\Models\Invoice;
use App\Services\InvoiceService;
use Filament\Notifications\Notification;
use Filament\Actions\Action;
use Filament\Actions\ActionGroup;

/**
 * HasDocumentActions
 *
 * Reusable document generation actions for any Filament table
 * that shows Consignment records.
 *
 * Usage in a RelationManager or Resource table:
 *   ...self::documentActions()   (in RelationManager)
 *   ...self::getDocumentActions() (in a static Table class)
 */
trait HasDocumentActions
{
    public static function documentActions(): array
    {
        return [
            ActionGroup::make(self::buildDocumentActions())
                ->label('Actions')
                ->icon('heroicon-o-ellipsis-vertical')
                ->color('gray')
                ->button(),
        ];
    }

    // For use in non-trait static table classes
    public static function getDocumentActions(): array
    {
        return self::buildDocumentActions();
    }

    private static function buildDocumentActions(): array
    {
        return [

            // ── Invoice ───────────────────────────────────────────

            Action::make('generate_invoice')
                ->label('Regenerate Invoice')
                ->icon('heroicon-o-arrow-path')
                ->color('warning')
                ->visible(fn (): bool =>
                    auth()->user()?->hasPermissionTo('print_documents') ?? false
                )
                ->requiresConfirmation()
                ->modalHeading('Regenerate Invoice')
                ->modalDescription(
                    'This will recalculate and replace the existing invoice. ' .
                    'Use if rates or cargo data changed after the consignment was created.'
                )
                ->modalSubmitActionLabel('Regenerate')
                ->action(function (Consignment $record): void {
                    // Step 1: Hard delete any existing invoice from DB
                    Invoice::where('consignment_id', $record->id)->delete();

                    // Step 2: Clear Laravel's relationship cache on this instance
                    $record->unsetRelation('invoice');

                    // Step 3: Force fresh load of shipment
                    $record->unsetRelation('shipment');

                    // Step 4: Generate fresh invoice
                    app(InvoiceService::class)->generateForConsignment($record);

                    Notification::make()
                        ->title('Invoice generated successfully')
                        ->success()
                        ->send();
                })
                ->successRedirectUrl(fn (Consignment $record): string =>
                    route('documents.print', ['invoice', $record->id])
                ),

            // ── Delivery Note — locked once goods are delivered ────

            // Pre-delivery: can generate (or regenerate before release)
            Action::make('generate_dn')
                ->label('Generate Delivery Note')
                ->icon('heroicon-o-clipboard-document-check')
                ->color('info')
                ->visible(fn (Consignment $record): bool =>
                    $record->status !== 'delivered' &&
                    (auth()->user()?->hasPermissionTo('print_documents') ?? false)
                )
                ->requiresConfirmation()
                ->modalHeading('Generate Delivery Note')
                ->modalDescription(
                    'This will generate (or replace) the delivery note for this consignee.'
                )
                ->modalSubmitActionLabel('Generate')
                ->action(function (Consignment $record): void {
                    DeliveryNote::where('consignment_id', $record->id)->delete();
                    $record->unsetRelation('deliveryNote');
                    $record->unsetRelation('shipment');
                    app(InvoiceService::class)->generateDeliveryNote($record);

                    Notification::make()
                        ->title('Delivery note generated')
                        ->success()
                        ->send();
                })
                ->successRedirectUrl(fn (Consignment $record): string =>
                    route('documents.print', ['delivery-note', $record->id])
                ),

            // Post-delivery: read-only print link — no regeneration allowed
            Action::make('view_dn')
                ->label('View Delivery Note')
                ->icon('heroicon-o-document-check')
                ->color('gray')
                ->visible(fn (Consignment $record): bool =>
                    $record->status === 'delivered' &&
                    (bool) $record->deliveryNote
                )
                ->url(fn (Consignment $record): string =>
                    route('documents.print', ['delivery-note', $record->id])
                )
                ->openUrlInNewTab(),
        ];
    }
}