<?php

declare(strict_types=1);

namespace App\Filament\Widgets;

use App\Business\Settlement\SettlementReminderService;
use App\Filament\Pages\DberpSettlementAgingAnalysisPage;
use App\Filament\Resources\DberpCustomerReceivables\DberpCustomerReceivableResource;
use App\Filament\Resources\DberpPaymentOrders\DberpPaymentOrderResource;
use App\Filament\Resources\DberpReceiptOrders\DberpReceiptOrderResource;
use App\Filament\Resources\DberpSettlementAdjustments\DberpSettlementAdjustmentResource;
use App\Filament\Resources\DberpSettlementStatements\DberpSettlementStatementResource;
use App\Filament\Resources\DberpSettlementWriteOffs\DberpSettlementWriteOffResource;
use App\Filament\Resources\DberpSupplierPayables\DberpSupplierPayableResource;
use App\Filament\Support\DberpShortcutRegistry;
use App\Services\DberpPermissionService;
use Filament\Widgets\Widget;
use Illuminate\Support\Facades\Auth;

class SettlementWorkbenchLinksWidget extends Widget
{
    protected static bool $isLazy = true;

    protected string $view = 'filament.widgets.settlement-workbench-links-widget';

    protected int|string|array $columnSpan = 'full';

    public static function canView(): bool
    {
        return app(DberpPermissionService::class)->allows(Auth::user(), DberpPermissionService::VIEW_WORKBENCH_OVERVIEW);
    }

    /**
     * @return list<array<string, string|int>>
     */
    public function reminderItems(): array
    {
        $items = app(SettlementReminderService::class)->reminderItems();

        return array_values(array_filter(array_map(function (array $item): array {
            $item['url'] = $this->urlForReminderKey((string) $item['key']);

            return $item;
        }, $items), fn (array $item): bool => $this->canAccessSettlementReminderKey((string) $item['key'])));
    }

    /**
     * @return list<array<string, string>>
     */
    public function shortcutLinks(): array
    {
        $links = app(DberpShortcutRegistry::class)->shortcutViewRowsForWorkbenchKeys(
            ['erp.customer_settlement_query', 'erp.supplier_settlement_query'],
            Auth::user(),
        );

        if (DberpCustomerReceivableResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.shortcut_receivables'), 'url' => DberpCustomerReceivableResource::getUrl('index')];
        }
        if (DberpSupplierPayableResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.shortcut_payables'), 'url' => DberpSupplierPayableResource::getUrl('index')];
        }
        if (DberpSettlementWriteOffResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.shortcut_write_offs'), 'url' => DberpSettlementWriteOffResource::getUrl('index')];
        }
        if (DberpSettlementStatementResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.shortcut_statements'), 'url' => DberpSettlementStatementResource::getUrl('index')];
        }
        if (DberpSettlementAgingAnalysisPage::canAccess()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.shortcut_aging'), 'url' => DberpSettlementAgingAnalysisPage::getUrl()];
        }

        return $links;
    }

    /**
     * @return list<array<string, string>>
     */
    public function exceptionLinks(): array
    {
        $links = [];

        if (DberpCustomerReceivableResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.exception_overdue_customer'), 'url' => $this->resourceUrl(DberpCustomerReceivableResource::class, 'overdue')];
        }
        if (DberpSupplierPayableResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.exception_overdue_supplier'), 'url' => $this->resourceUrl(DberpSupplierPayableResource::class, 'overdue')];
        }
        if (DberpReceiptOrderResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.exception_long_unwritten_receipt'), 'url' => $this->resourceUrl(DberpReceiptOrderResource::class, 'long_unwritten')];
        }
        if (DberpPaymentOrderResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.exception_long_unwritten_payment'), 'url' => $this->resourceUrl(DberpPaymentOrderResource::class, 'long_unwritten')];
        }
        if (DberpSettlementAdjustmentResource::canViewAny()) {
            $links[] = ['title' => (string) __('dberp.widgets.settlement_workbench.exception_recent_adjustment'), 'url' => $this->resourceUrl(DberpSettlementAdjustmentResource::class, 'recent_follow_up')];
        }

        return $links;
    }

    /**
     * 与 urlForReminderKey 目标一致：无权限的提醒不展示，避免点击进入 403。
     */
    private function canAccessSettlementReminderKey(string $key): bool
    {
        return match ($key) {
            'due_today_receivable', 'overdue_receivable' => DberpCustomerReceivableResource::canViewAny(),
            'due_soon_payable' => DberpSupplierPayableResource::canViewAny(),
            'large_unwritten', 'long_unwritten' => DberpReceiptOrderResource::canViewAny(),
            'reversed_write_off' => DberpSettlementWriteOffResource::canViewAny(),
            'recent_adjustment' => DberpSettlementAdjustmentResource::canViewAny(),
            default => DberpSettlementStatementResource::canViewAny(),
        };
    }

    private function urlForReminderKey(string $key): string
    {
        return match ($key) {
            'due_today_receivable' => $this->resourceUrl(DberpCustomerReceivableResource::class, 'due_today'),
            'overdue_receivable' => $this->resourceUrl(DberpCustomerReceivableResource::class, 'overdue'),
            'due_soon_payable' => $this->resourceUrl(DberpSupplierPayableResource::class, 'due_soon'),
            'large_unwritten' => $this->resourceUrl(DberpReceiptOrderResource::class, 'large_unwritten'),
            'long_unwritten' => $this->resourceUrl(DberpReceiptOrderResource::class, 'long_unwritten'),
            'reversed_write_off' => $this->resourceUrl(DberpSettlementWriteOffResource::class, 'reversed_follow_up'),
            'recent_adjustment' => $this->resourceUrl(DberpSettlementAdjustmentResource::class, 'recent_follow_up'),
            default => DberpSettlementStatementResource::getUrl('index'),
        };
    }

    private function resourceUrl(string $resourceClass, string $attentionStatus): string
    {
        return $resourceClass::getUrl('index').'?'.http_build_query([
            'filters' => [
                'attention_status' => [
                    'value' => $attentionStatus,
                ],
            ],
        ]);
    }
}
