<?php

declare(strict_types=1);

namespace App\Filament\Pages;

use App\Business\Settlement\SettlementAgingAnalysisService;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Pages\Concerns\HasDberpAnalysisPageCsvExport;
use App\Filament\Pages\Concerns\InteractsWithDberpReportPage;
use App\Models\DberpCustomer;
use App\Models\DberpSupplier;
use App\Services\DberpPermissionService;
use App\Support\DberpSettlementEntryFilamentSupport;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Pages\Page;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\Form;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Schema;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Facades\Auth;
use UnitEnum;

/**
 * @property-read Schema $form
 */
final class DberpSettlementAgingAnalysisPage extends Page
{
    use HasDberpAnalysisPageCsvExport;
    use InteractsWithDberpPermissions;
    use InteractsWithDberpReportPage;

    private const REPORT_KEY = 'settlement-aging-analysis';

    protected static ?string $slug = 'settlement-aging-analysis';

    protected static ?int $navigationSort = 50;

    protected string $view = 'filament.pages.dberp-settlement-aging-analysis-page';

    /**
     * @var array<string, mixed>|null
     */
    public ?array $data = [];

    /**
     * @var list<array<string, mixed>>
     */
    public array $rows = [];

    /**
     * @var array<string, float>
     */
    public array $totals = [];

    public function mount(): void
    {
        $this->form->fill([
            'settlement_side' => 'receivable',
            'counterparty_id' => null,
            'as_of_date' => now()->toDateString(),
        ]);

        $this->refreshAnalysis();
    }

    public static function getNavigationGroup(): string|UnitEnum|null
    {
        return __('dberp.nav.business_query');
    }

    public static function getNavigationLabel(): string
    {
        return __('dberp.resources.settlement_aging_analysis.label');
    }

    public static function getNavigationIcon(): string|BackedEnum|Htmlable|null
    {
        return null;
    }

    public static function canAccess(): bool
    {
        return Auth::check() && self::allowsPermission(DberpPermissionService::NAV_SETTLEMENT_AGING_ANALYSIS);
    }

    public function getTitle(): string|Htmlable
    {
        return __('dberp.resources.settlement_aging_analysis.label');
    }

    protected function reportExportKey(): string
    {
        return self::REPORT_KEY;
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Form::make([
                    Select::make('settlement_side')
                        ->label(__('dberp.fields.settlement_side'))
                        ->options(__('dberp.options.settlement_business_side'))
                        ->default('receivable')
                        ->required()
                        ->live()
                        ->afterStateUpdated(fn (callable $set): mixed => $set('counterparty_id', null)),
                    Select::make('counterparty_id')
                        ->label(__('dberp.fields.counterparty'))
                        ->options(function (Get $get): array {
                            return $get('settlement_side') === 'payable'
                                ? DberpSupplier::query()->where('is_enabled', true)->orderBy('sort_order')->orderBy('id')->pluck('name', 'id')->all()
                                : DberpCustomer::query()->where('is_enabled', true)->orderBy('sort_order')->orderBy('id')->pluck('name', 'id')->all();
                        })
                        ->searchable()
                        ->preload()
                        ->nullable(),
                    DatePicker::make('as_of_date')
                        ->label(__('dberp.fields.as_of_date'))
                        ->default(now()->toDateString())
                        ->helperText(__('dberp.resources.settlement_aging_analysis.as_of_hint'))
                        ->required(),
                ])
                    ->columns(3)
                    ->livewireSubmitHandler('refreshAnalysis')
                    ->footer([
                        Actions::make([
                            Action::make('refreshAnalysis')
                                ->label(__('dberp.actions.refresh_analysis'))
                                ->submit('refreshAnalysis'),
                        ]),
                    ]),
            ])
            ->statePath('data');
    }

    public function refreshAnalysis(): void
    {
        $analysis = app(SettlementAgingAnalysisService::class)->analyze($this->form->getState());
        $this->rows = $analysis['rows'];
        $this->totals = $analysis['totals'];
    }

    public function counterpartyDetailUrl(int $counterpartyId): string
    {
        $state = $this->form->getState();

        if (($state['settlement_side'] ?? 'receivable') === 'payable') {
            return DberpSettlementEntryFilamentSupport::supplierPayablesUrl([
                'supplier_id' => ['value' => $counterpartyId],
            ]);
        }

        return DberpSettlementEntryFilamentSupport::customerReceivablesUrl([
            'customer_id' => ['value' => $counterpartyId],
        ]);
    }
}
