<?php

namespace App\Filament\Resources\SalesOrderResource\Pages;

use App\Filament\Resources\InvoiceResource\Pages\ViewInvoice;
use App\Filament\Resources\SalesOrderResource;
use App\Filament\Support\StatusLookup;
use App\Models\Lookups\Status;
use App\Models\Sales\SalesOrder;
use App\Models\Sales\SalesOrderItem;
use App\Services\AppSettings;
use App\Services\CurrentContext;
use App\Services\VatSettings;
use App\Support\Quantity;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
use Filament\Infolists\Components\IconEntry;
use Filament\Infolists\Components\RepeatableEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Resources\Pages\ViewRecord;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;

/**
 * The order as a whole: what was asked for (including the exact wording of any
 * custom item), when it is due, what has been paid in advance, and — once
 * converted — which invoice it became.
 */
class ViewSalesOrder extends ViewRecord
{
    protected static string $resource = SalesOrderResource::class;

    protected function getHeaderActions(): array
    {
        return [
            EditAction::make()->visible(fn (SalesOrder $record): bool => SalesOrderResource::canEdit($record)),
            SalesOrderResource::addPaymentAction(),
            SalesOrderResource::convertAction(),
            SalesOrderResource::cancelAction(),
            Action::make('openInvoice')
                ->label('Open invoice')
                ->icon(Heroicon::OutlinedDocumentText)
                ->color('gray')
                ->visible(fn (SalesOrder $record): bool => $record->isConverted() && $record->invoice !== null)
                ->url(fn (SalesOrder $record): string => ViewInvoice::getUrl(['record' => $record->converted_invoice_id])),
        ];
    }

    public function infolist(Schema $schema): Schema
    {
        $warningDays = app(AppSettings::class)->salesOrderDeadlineWarningDays();

        return $schema->components([
            Section::make()->schema([
                TextEntry::make('order_number')->label('Order #')->badge(),
                TextEntry::make('customer.business_name')->label('Customer')->placeholder('—'),
                TextEntry::make('customer.phone')->label('Phone')->placeholder('—'),
                TextEntry::make('branch.name')->label('Branch')->placeholder('—'),
                TextEntry::make('status.name')
                    ->label('Status')
                    ->badge()
                    ->color(fn (SalesOrder $record): string => StatusLookup::colorOf(Status::CTX_SALES_ORDER, $record->status?->code ?? '')),
                TextEntry::make('paymentStatus.name')
                    ->label('Payment status')
                    ->badge()
                    ->color(fn (SalesOrder $record): string => StatusLookup::colorOf(Status::CTX_INVOICE_PAYMENT, $record->paymentStatus?->code ?? '')),
                TextEntry::make('order_date')->label('Ordered')->date(),
                TextEntry::make('deadline_date')
                    ->label('Delivery deadline')
                    ->date()
                    ->placeholder('—')
                    ->badge()
                    ->color(fn (SalesOrder $record): string => SalesOrderResource::deadlineColor($record, $warningDays))
                    ->helperText(fn (SalesOrder $record): ?string => SalesOrderResource::deadlineNote($record)),
                TextEntry::make('rep.full_name')->label('Sales rep')->placeholder('—'),
                TextEntry::make('creator.name')->label('Taken by')->placeholder('—'),
                TextEntry::make('invoice.invoice_number')
                    ->label('Invoiced as')
                    ->badge()->color('success')
                    ->placeholder('—')
                    ->visible(fn (SalesOrder $record): bool => $record->isConverted()),
                TextEntry::make('note')->columnSpanFull()->placeholder('—'),
            ])->columns(3),

            Section::make('Items')->schema([
                RepeatableEntry::make('items')
                    ->schema([
                        IconEntry::make('is_custom')
                            ->label('Custom')
                            ->boolean()
                            ->trueIcon(Heroicon::OutlinedSparkles)
                            ->falseIcon(Heroicon::OutlinedCube)
                            ->trueColor('warning')
                            ->falseColor('gray'),
                        TextEntry::make('product_name')->label('Item'),
                        TextEntry::make('quantity')
                            ->formatStateUsing(fn ($state, SalesOrderItem $record): string => Quantity::format($state, $record->unit)),
                        TextEntry::make('unit_price')->money(fn () => app(CurrentContext::class)->currencyCode()),
                        TextEntry::make('discount_amount')->money(fn () => app(CurrentContext::class)->currencyCode()),
                        TextEntry::make('vat_amount')->money(fn () => app(CurrentContext::class)->currencyCode())
                            ->visible(fn (): bool => app(VatSettings::class)->enabled()),
                        TextEntry::make('line_total')->money(fn () => app(CurrentContext::class)->currencyCode()),
                        // The two fields that make a custom order fulfillable —
                        // shown full-width and only when there is something in
                        // them, so catalog lines stay compact.
                        TextEntry::make('custom_description')
                            ->label('Description')
                            ->columnSpanFull()
                            ->visible(fn ($state): bool => filled($state)),
                        TextEntry::make('custom_specification')
                            ->label('Exact details from the customer')
                            ->columnSpanFull()
                            ->visible(fn ($state): bool => filled($state)),
                    ])
                    ->columns(7)
                    ->columnSpanFull(),
            ]),

            Section::make('Advance payments')
                ->schema([
                    RepeatableEntry::make('payments')
                        ->schema([
                            TextEntry::make('method')->badge(),
                            TextEntry::make('amount')->money(fn () => app(CurrentContext::class)->currencyCode()),
                            TextEntry::make('received_at')->label('Received')->date()->placeholder('—'),
                            TextEntry::make('reference')->placeholder('—'),
                            TextEntry::make('creditNote.cn_number')->label('Credit note')->placeholder('—'),
                            TextEntry::make('cheque_number')->label('Cheque #')->placeholder('—'),
                            TextEntry::make('cheque_bank')->label('Bank')->placeholder('—'),
                            TextEntry::make('cheque_branch')->label('Branch')->placeholder('—'),
                            TextEntry::make('cheque_date')->label('Cheque date')->date()->placeholder('—'),
                            TextEntry::make('custom_fields')
                                ->label('Details')
                                ->formatStateUsing(fn (mixed $state): ?string => static::formatCustomFields($state))
                                ->placeholder('—'),
                        ])
                        ->columns(5)
                        ->columnSpanFull(),
                ])
                ->visible(fn (SalesOrder $record): bool => $record->payments->isNotEmpty()),

            Section::make('Totals')->schema([
                TextEntry::make('subtotal')->money(fn () => app(CurrentContext::class)->currencyCode()),
                TextEntry::make('discount')->money(fn () => app(CurrentContext::class)->currencyCode()),
                TextEntry::make('vat_total')->label('VAT')->money(fn () => app(CurrentContext::class)->currencyCode())
                    ->visible(fn (): bool => app(VatSettings::class)->enabled()),
                TextEntry::make('net_total')->label('Order value')->money(fn () => app(CurrentContext::class)->currencyCode())->weight('bold'),
                TextEntry::make('advance_paid')->label('Paid')->money(fn () => app(CurrentContext::class)->currencyCode()),
                TextEntry::make('balance')->money(fn () => app(CurrentContext::class)->currencyCode()),
            ])->columns(3),
        ]);
    }

    /**
     * Custom-method tender details as one readable line — "Approval code: ABC,
     * Bank branch: X" — instead of a raw JSON blob.
     */
    public static function formatCustomFields(mixed $state): ?string
    {
        if (! is_array($state) || $state === []) {
            return null;
        }

        return collect($state)
            ->map(fn (mixed $value, mixed $key): string => ucwords(str_replace('_', ' ', (string) $key)).': '.$value)
            ->join(', ');
    }
}
