<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpSupplierPurchaseRankings;

use App\Business\Report\PurchaseReportService;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Resources\Concerns\HasDberpExportAction;
use App\Filament\Resources\DberpPurchaseOrders\DberpPurchaseOrderResource;
use App\Filament\Resources\DberpSupplierPurchaseRankings\Pages\ListDberpSupplierPurchaseRankings;
use App\Filament\Resources\DberpSuppliers\DberpSupplierResource;
use App\Models\DberpEmployee;
use App\Models\DberpProductCategory;
use App\Models\DberpSupplier;
use App\Services\DberpPermissionService;
use App\Support\DberpFilamentMasterDataSelectOptions;
use App\Support\DberpNumberFormatter;
use App\Support\DberpPurchaseStatisticsFilamentSupport;
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 DberpSupplierPurchaseRankingResource extends Resource
{
    use HasDberpExportAction;
    use InteractsWithDberpPermissions;

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

    protected static ?string $recordTitleAttribute = 'name';

    protected static ?int $navigationSort = 120;

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

    public static function getEloquentQuery(): Builder
    {
        $query = app(PurchaseReportService::class)->supplierRankingQuery();

        /** @var Builder $query */
        return $query;
    }

    public static function table(Table $table): Table
    {
        $filterQueryPassthrough = fn (Builder $query, array $data): Builder => $query;

        return $table
            ->columns([
                TextColumn::make('ranking_serial')
                    ->label(__('dberp.fields.ranking_position'))
                    ->numeric()
                    ->state(fn (ListDberpSupplierPurchaseRankings $livewire, DberpSupplier $record): int => $livewire->computeSupplierPurchaseRankingRank($record)),
                TextColumn::make('code')->label(__('dberp.fields.supplier_code'))->searchable(),
                TextColumn::make('name')
                    ->label(__('dberp.fields.supplier_name'))
                    ->searchable()
                    ->url(fn (DberpSupplier $record): ?string => DberpSupplierResource::canEdit($record)
                        ? DberpSupplierResource::getUrl('edit', ['record' => $record])
                        : null),
                TextColumn::make('order_count')->label(__('dberp.fields.order_count'))->numeric(),
                TextColumn::make('purchase_amount')->label(__('dberp.fields.purchase_amount'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::money($state)),
                TextColumn::make('paid_amount_total')->label(__('dberp.fields.paid_amount'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::money($state)),
            ])
            ->filters([
                Filter::make('business_time')
                    ->schema([
                        DatePicker::make('from')->label(__('dberp.fields.date_from')),
                        DatePicker::make('until')->label(__('dberp.fields.date_until')),
                    ])
                    ->query($filterQueryPassthrough),
                SelectFilter::make('status')
                    ->label(__('dberp.fields.status'))
                    ->options(__('dberp.options.purchase_order_status'))
                    ->query($filterQueryPassthrough),
                SelectFilter::make('handler_employee_id')
                    ->label(__('dberp.fields.handler_employee'))
                    ->options(fn (): array => DberpEmployee::selectOptionsForFilament())
                    ->searchable()
                    ->preload()
                    ->query($filterQueryPassthrough),
                SelectFilter::make('supplier_id')
                    ->label(__('dberp.fields.supplier'))
                    ->options(fn (): array => DberpSupplier::query()->orderBy('sort_order')->orderBy('id')->pluck('name', 'id')->all())
                    ->query($filterQueryPassthrough),
                SelectFilter::make('category_id')
                    ->label(__('dberp.fields.category'))
                    ->options(fn (): array => DberpProductCategory::query()->orderBy('sort_order')->orderBy('id')->pluck('name', 'id')->all())
                    ->query($filterQueryPassthrough),
                SelectFilter::make('product_id')
                    ->label(__('dberp.fields.product'))
                    ->options(fn (): array => DberpFilamentMasterDataSelectOptions::products())
                    ->query($filterQueryPassthrough),
            ])
            ->headerActions([
                static::makeExportAction('supplier-purchase-ranking'),
            ])
            ->recordActions([
                Action::make('view_supplier')
                    ->label(__('dberp.resources.supplier_purchase_ranking.link_view_supplier'))
                    ->url(fn (DberpSupplier $record): string => DberpSupplierResource::getUrl('edit', ['record' => $record]))
                    ->visible(fn (DberpSupplier $record): bool => DberpSupplierResource::canEdit($record)),
                Action::make('view_purchase_orders')
                    ->label(__('dberp.resources.supplier_purchase_ranking.link_purchase_orders'))
                    ->url(fn (DberpSupplier $record, ListDberpSupplierPurchaseRankings $livewire): string => DberpPurchaseStatisticsFilamentSupport::purchaseOrderIndexUrlForSupplierRanking(
                        $record,
                        is_array($livewire->tableFilters) ? $livewire->tableFilters : [],
                    ))
                    ->visible(fn (): bool => DberpPurchaseOrderResource::canViewAny()),
            ])
            ->defaultSort('purchase_amount', 'desc');
    }

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

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

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

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

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

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