<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpSupplierSettlementQueries;

use App\Business\Report\QueryCenterService;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Resources\Concerns\HasDberpExportAction;
use App\Filament\Resources\DberpSupplierSettlementQueries\Pages\ListDberpSupplierSettlementQueries;
use App\Models\DberpSettlementEntry;
use App\Models\DberpSupplier;
use App\Services\DberpPermissionService;
use App\Support\DberpNumberFormatter;
use App\Support\DberpSettlementEntrySourceUrlResolver;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Builder;
use UnitEnum;

class DberpSupplierSettlementQueryResource extends Resource
{
    use HasDberpExportAction;
    use InteractsWithDberpPermissions;

    protected static ?string $model = DberpSettlementEntry::class;

    protected static ?string $recordTitleAttribute = 'document_number';

    protected static ?int $navigationSort = 40;

    public static function form(Schema $schema): Schema
    {
        return $schema->components([]);
    }

    public static function getEloquentQuery(): Builder
    {
        return app(QueryCenterService::class)->supplierSettlementQuery();
    }

    public static function table(Table $table): Table
    {
        return $table
            ->defaultSort('business_time', 'desc')
            ->columns([
                TextColumn::make('supplier.name')->label(__('dberp.fields.supplier'))->searchable(),
                TextColumn::make('change_type')->label(__('dberp.fields.change_type'))->badge()->formatStateUsing(fn (?string $state): string => __('dberp.options.settlement_change_type')[$state] ?? (string) $state),
                TextColumn::make('source_type')->label(__('dberp.fields.source_type'))->formatStateUsing(fn (?string $state): string => __('dberp.options.settlement_source_type')[$state] ?? (string) $state),
                TextColumn::make('document_number')
                    ->label(__('dberp.fields.document_code'))
                    ->searchable()
                    ->url(fn (?DberpSettlementEntry $record): ?string => DberpSettlementEntrySourceUrlResolver::editUrlOrNull($record)),
                TextColumn::make('change_amount')->label(__('dberp.fields.change_amount'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::money($state)),
                TextColumn::make('balance_after')->label(__('dberp.fields.balance_after'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::money($state)),
                TextColumn::make('business_time')->label(__('dberp.fields.business_time'))->dateTime(),
                TextColumn::make('remark')->label(__('dberp.fields.remark'))->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('supplier_id')->label(__('dberp.fields.supplier'))->options(fn (): array => DberpSupplier::query()->orderBy('sort_order')->orderBy('id')->pluck('name', 'id')->all())->query(fn (Builder $query, array $data): Builder => ($data['value'] ?? null) ? $query->where('counterparty_id', (int) $data['value']) : $query),
                SelectFilter::make('change_type')->label(__('dberp.fields.change_type'))->options(__('dberp.options.settlement_change_type')),
                SelectFilter::make('source_type')->label(__('dberp.fields.source_type'))->options(__('dberp.options.settlement_source_type')),
                Filter::make('business_time')
                    ->schema([
                        DatePicker::make('from')->label(__('dberp.fields.date_from')),
                        DatePicker::make('until')->label(__('dberp.fields.date_until')),
                    ])
                    ->query(function (Builder $query, array $data): Builder {
                        return $query
                            ->when($data['from'] ?? null, fn (Builder $builder, $date): Builder => $builder->whereDate('business_time', '>=', $date))
                            ->when($data['until'] ?? null, fn (Builder $builder, $date): Builder => $builder->whereDate('business_time', '<=', $date));
                    }),
            ])
            ->headerActions([
                static::makeExportAction('supplier-settlement-query'),
            ])
            ->recordActions([
                Action::make('view_source')
                    ->label(__('dberp.actions.view_source_document'))
                    ->url(fn (DberpSettlementEntry $record): ?string => DberpSettlementEntrySourceUrlResolver::editUrl($record))
                    ->visible(fn (DberpSettlementEntry $record): bool => DberpSettlementEntrySourceUrlResolver::hasEditUrl($record)),
            ]);
    }

    public static function getPages(): array
    {
        return ['index' => ListDberpSupplierSettlementQueries::route('/')];
    }

    public static function canViewAny(): bool
    {
        return static::allowsPermission(DberpPermissionService::VIEW_SUPPLIER_PAYABLE);
    }

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

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

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

    public static function getPluralModelLabel(): string
    {
        return __('dberp.resources.supplier_settlement_query.plural');
    }
}
