<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpReceiptPaymentQueries;

use App\Business\Report\QueryCenterService;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Resources\Concerns\HasDberpExportAction;
use App\Filament\Resources\DberpPurchaseOrders\DberpPurchaseOrderResource;
use App\Filament\Resources\DberpReceiptPaymentQueries\Pages\ListDberpReceiptPaymentQueries;
use App\Filament\Resources\DberpSalesOrders\DberpSalesOrderResource;
use App\Models\DberpDictionaryItem;
use App\Models\DberpEmployee;
use App\Models\DberpReceiptPaymentQuery;
use App\Services\DberpPermissionService;
use App\Support\DberpFilamentMasterDataSelectOptions;
use App\Support\DberpNumberFormatter;
use App\Support\DberpReceiptPaymentQuerySourceUrlResolver;
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 DberpReceiptPaymentQueryResource extends Resource
{
    use HasDberpExportAction;
    use InteractsWithDberpPermissions;

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

    protected static ?string $recordTitleAttribute = 'code';

    protected static ?int $navigationSort = 60;

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

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

    public static function table(Table $table): Table
    {
        return $table
            ->defaultSort('business_time', 'desc')
            ->columns([
                TextColumn::make('direction')->label(__('dberp.fields.direction'))->badge()->formatStateUsing(fn (?string $state): string => __('dberp.options.receipt_payment_direction')[$state] ?? (string) $state),
                TextColumn::make('code')
                    ->label(__('dberp.fields.document_code'))
                    ->searchable()
                    ->url(fn (?DberpReceiptPaymentQuery $record): ?string => DberpReceiptPaymentQuerySourceUrlResolver::editUrlOrNull($record)),
                TextColumn::make('status')->label(__('dberp.fields.status'))->badge()->formatStateUsing(fn (?string $state): string => __('dberp.options.common_document_status')[$state] ?? (string) $state),
                TextColumn::make('customer.name')->label(__('dberp.fields.customer')),
                TextColumn::make('supplier.name')->label(__('dberp.fields.supplier')),
                TextColumn::make('paymentMethodItem.label')->label(__('dberp.fields.payment_method')),
                TextColumn::make('amount')->label(__('dberp.fields.amount'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::money($state)),
                TextColumn::make('salesOrder.code')
                    ->label(__('dberp.fields.sales_order_code'))
                    ->url(fn (DberpReceiptPaymentQuery $record): ?string => $record->sales_order_id
                        ? DberpSalesOrderResource::getUrl('edit', ['record' => (int) $record->sales_order_id])
                        : null)
                    ->placeholder('—'),
                TextColumn::make('purchaseOrder.code')
                    ->label(__('dberp.fields.purchase_order_code'))
                    ->url(fn (DberpReceiptPaymentQuery $record): ?string => $record->purchase_order_id
                        ? DberpPurchaseOrderResource::getUrl('edit', ['record' => (int) $record->purchase_order_id])
                        : null)
                    ->placeholder('—'),
                TextColumn::make('handlerEmployee.name')->label(__('dberp.fields.handler_employee')),
                TextColumn::make('business_time')->label(__('dberp.fields.business_time'))->dateTime(),
                TextColumn::make('effective_at')->label(__('dberp.fields.effective_at'))->dateTime()->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('voided_at')->label(__('dberp.fields.voided_at'))->dateTime()->toggleable(isToggledHiddenByDefault: true),
                TextColumn::make('remark')->label(__('dberp.fields.remark'))->limit(40)->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                SelectFilter::make('direction')->label(__('dberp.fields.direction'))->options(__('dberp.options.receipt_payment_direction')),
                SelectFilter::make('status')->label(__('dberp.fields.status'))->options(__('dberp.options.common_document_status')),
                SelectFilter::make('customer_id')->label(__('dberp.fields.customer'))->options(fn (): array => DberpFilamentMasterDataSelectOptions::customers()),
                SelectFilter::make('supplier_id')->label(__('dberp.fields.supplier'))->options(fn (): array => DberpFilamentMasterDataSelectOptions::suppliers()),
                SelectFilter::make('payment_method_item_id')->label(__('dberp.fields.payment_method'))->options(fn (): array => DberpDictionaryItem::query()->whereHas('type', fn (Builder $typeQuery) => $typeQuery->where('code', 'payment_method'))->orderBy('sort_order')->orderBy('id')->pluck('label', 'id')->all()),
                SelectFilter::make('handler_employee_id')->label(__('dberp.fields.handler_employee'))->options(fn (): array => DberpEmployee::selectOptionsForFilament()),
                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('receipt-payment-query'),
            ])
            ->recordActions([
                Action::make('view_source')
                    ->label(__('dberp.actions.view_source_document'))
                    ->url(fn (DberpReceiptPaymentQuery $record): ?string => DberpReceiptPaymentQuerySourceUrlResolver::editUrl($record))
                    ->visible(fn (DberpReceiptPaymentQuery $record): bool => DberpReceiptPaymentQuerySourceUrlResolver::hasEditUrl($record)),
            ]);
    }

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

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

    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.receipt_payment_query.label');
    }

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