<?php

declare(strict_types=1);

namespace App\Filament\Resources\DberpPurchasePriceReferences;

use App\Business\Report\PurchaseReportService;
use App\Filament\Concerns\InteractsWithDberpPermissions;
use App\Filament\Resources\Concerns\HasDberpExportAction;
use App\Filament\Resources\DberpProducts\DberpProductResource;
use App\Filament\Resources\DberpPurchaseOrders\DberpPurchaseOrderResource;
use App\Filament\Resources\DberpPurchasePriceReferences\Pages\ListDberpPurchasePriceReferences;
use App\Filament\Resources\DberpSuppliers\DberpSupplierResource;
use App\Models\DberpPurchasePriceReferenceSnapshot;
use App\Services\DberpPermissionService;
use App\Support\DberpNumberFormatter;
use App\Support\DberpProductSkuSelectOptions;
use BackedEnum;
use Filament\Actions\Action;
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 Illuminate\Database\Eloquent\Model;
use UnitEnum;

class DberpPurchasePriceReferenceResource extends Resource
{
    use HasDberpExportAction;
    use InteractsWithDberpPermissions;

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

    protected static ?string $recordTitleAttribute = 'scope_key';

    protected static ?int $navigationSort = 140;

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

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

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                TextColumn::make('scope_type')
                    ->label(__('dberp.fields.scope_type'))
                    ->badge()
                    ->formatStateUsing(fn (?string $state): string => __('dberp.options.purchase_price_reference_scope_type')[$state] ?? (string) $state),
                TextColumn::make('supplier.name')->label(__('dberp.fields.supplier'))->searchable(),
                TextColumn::make('product.name')->label(__('dberp.fields.product'))->searchable(),
                TextColumn::make('latest_transaction_unit_price')->label(__('dberp.fields.latest_transaction_unit_price'))->formatStateUsing(fn ($state): string => DberpNumberFormatter::price($state)),
                TextColumn::make('latest_transaction_date')->label(__('dberp.fields.latest_transaction_date'))->date(),
                TextColumn::make('latest_receipt_date')->label(__('dberp.fields.latest_receipt_date'))->date(),
                TextColumn::make('latest_lead_time_days')->label(__('dberp.fields.latest_lead_time_days'))->numeric(),
                TextColumn::make('refreshed_at')->label(__('dberp.fields.refreshed_at'))->dateTime(),
            ])
            ->filters([
                SelectFilter::make('scope_type')->label(__('dberp.fields.scope_type'))->options(__('dberp.options.purchase_price_reference_scope_type')),
                SelectFilter::make('supplier_id')
                    ->label(__('dberp.fields.supplier'))
                    ->relationship('supplier', 'name')
                    ->searchable()
                    ->preload(),
                DberpProductSkuSelectOptions::configureProductRelationshipTableFilter(
                    SelectFilter::make('product_id')
                        ->label(__('dberp.fields.product')),
                )
                    ->searchable()
                    ->preload(),
                Filter::make('is_stale')
                    ->label(__('dberp.fields.is_stale'))
                    ->query(fn (Builder $query): Builder => PurchaseReportService::applyIsStalePriceReferenceConstraint($query)),
            ])
            ->headerActions([
                static::makeExportAction('purchase-price-reference'),
            ])
            ->recordActions([
                Action::make('link_purchase_order')
                    ->label(__('dberp.resources.purchase_price_reference.link_purchase_order'))
                    ->url(function (DberpPurchasePriceReferenceSnapshot $record): ?string {
                        $order = $record->latestPurchaseOrder;

                        return $order !== null && DberpPurchaseOrderResource::canView($order)
                            ? DberpPurchaseOrderResource::getUrl('edit', ['record' => $order])
                            : null;
                    })
                    ->visible(fn (DberpPurchasePriceReferenceSnapshot $record): bool => $record->latest_purchase_order_id !== null
                        && $record->latestPurchaseOrder !== null
                        && DberpPurchaseOrderResource::canView($record->latestPurchaseOrder)),
                Action::make('link_product')
                    ->label(__('dberp.resources.purchase_price_reference.link_product'))
                    ->url(fn (DberpPurchasePriceReferenceSnapshot $record): ?string => $record->product !== null && DberpProductResource::canEdit($record->product)
                        ? DberpProductResource::getUrl('edit', ['record' => $record->product])
                        : null)
                    ->visible(fn (DberpPurchasePriceReferenceSnapshot $record): bool => $record->product !== null && DberpProductResource::canEdit($record->product)),
                Action::make('link_supplier')
                    ->label(__('dberp.resources.purchase_price_reference.link_supplier'))
                    ->url(fn (DberpPurchasePriceReferenceSnapshot $record): ?string => $record->supplier !== null && DberpSupplierResource::canEdit($record->supplier)
                        ? DberpSupplierResource::getUrl('edit', ['record' => $record->supplier])
                        : null)
                    ->visible(fn (DberpPurchasePriceReferenceSnapshot $record): bool => $record->supplier_id !== null
                        && $record->supplier !== null
                        && DberpSupplierResource::canEdit($record->supplier)),
            ])
            ->defaultSort('latest_transaction_date', 'desc');
    }

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

    public static function canView(Model $record): bool
    {
        return static::allowsPermission(DberpPermissionService::VIEW_PURCHASE_PRICE_REFERENCE);
    }

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

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

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