<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Business\Workbench;

use App\Filament\Widgets\InventoryGovernanceWorkbenchLinksWidget;
use App\Filament\Widgets\PurchaseCollaborationWorkbenchLinksWidget;
use App\Filament\Widgets\SalesControlWorkbenchLinksWidget;
use App\Filament\Widgets\SettlementWorkbenchLinksWidget;

/**
 * 聚合四域工作台待办；URL 与权限沿用各域 WorkbenchLinksWidget，避免重复维护下钻逻辑。
 */
final class UnifiedWorkbenchReminderService
{
    /**
     * @var list<array{0: class-string, 1: string}>
     */
    private const DOMAIN_SOURCES = [
        'inventory' => [InventoryGovernanceWorkbenchLinksWidget::class, 'dberp.widgets.inventory_workbench.module_title'],
        'purchase' => [PurchaseCollaborationWorkbenchLinksWidget::class, 'dberp.widgets.purchase_workbench.module_title'],
        'settlement' => [SettlementWorkbenchLinksWidget::class, 'dberp.widgets.settlement_workbench.module_title'],
        'sales' => [SalesControlWorkbenchLinksWidget::class, 'dberp.widgets.sales_workbench.module_title'],
    ];

    /**
     * @return list<array{
     *     key: string,
     *     domain: string,
     *     domain_label: string,
     *     title: string,
     *     count: int,
     *     amount: string,
     *     url: string,
     *     severity: string,
     * }>
     */
    public function activeReminderItems(): array
    {
        $items = [];
        $priorityBase = 0;

        foreach (self::DOMAIN_SOURCES as $domain => [$widgetClass, $domainLabelKey]) {
            $domain = (string) $domain;
            /** @var InventoryGovernanceWorkbenchLinksWidget|PurchaseCollaborationWorkbenchLinksWidget|SettlementWorkbenchLinksWidget|SalesControlWorkbenchLinksWidget $widget */
            $widget = app($widgetClass);

            foreach ($widget->reminderItems() as $index => $item) {
                $count = (int) ($item['count'] ?? 0);

                if ($count <= 0) {
                    continue;
                }

                $key = (string) $item['key'];
                $priority = $priorityBase + (int) $index;

                $items[] = [
                    'key' => $key,
                    'domain' => $domain,
                    'domain_label' => (string) __($domainLabelKey),
                    'title' => (string) $item['title'],
                    'count' => $count,
                    'amount' => (string) ($item['amount'] ?? ''),
                    'url' => (string) $item['url'],
                    'severity' => $this->severityFor($domain, $key),
                    'priority' => $priority,
                ];
            }

            $priorityBase += 100;
        }

        usort($items, static fn (array $left, array $right): int => (int) $left['priority'] <=> (int) $right['priority']);

        return array_map(static function (array $item): array {
            unset($item['priority']);

            return $item;
        }, $items);
    }

    private function severityFor(string $domain, string $key): string
    {
        return match ($domain) {
            'inventory' => match ($key) {
                'expired_batch', 'serial_mismatch' => 'danger',
                'near_expiry_batch', 'pending_stocktake_difference', 'pending_replenishment', 'low_stock' => 'warning',
                default => 'info',
            },
            'purchase' => match ($key) {
                'urgent_purchase_request', 'overdue_arrival_order', 'pending_purchase_exception', 'pending_resupply_exception' => 'danger',
                'pending_arrival_order', 'partial_arrival_order', 'supplier_performance_attention', 'stale_purchase_price_reference' => 'warning',
                default => 'info',
            },
            'settlement' => match ($key) {
                'overdue_receivable', 'reversed_write_off' => 'danger',
                'due_today_receivable', 'due_soon_payable', 'large_unwritten', 'long_unwritten', 'recent_adjustment' => 'warning',
                default => 'info',
            },
            'sales' => match ($key) {
                'expired_quote', 'blocked_credit_customer', 'expired_price_rule' => 'danger',
                'expiring_quote', 'long_unconverted_quote', 'near_limit_customer', 'expiring_price_rule', 'released_override_order' => 'warning',
                default => 'info',
            },
            default => 'info',
        };
    }
}
