<?php

declare(strict_types=1);

namespace App\Filament\Pages\Concerns;

use App\Filament\Support\DberpExportCsvFilamentAction;
use App\Services\DberpAuditService;
use App\Services\DberpPermissionService;
use App\Support\DberpFilamentListPageUrl;
use App\Support\DberpNumberFormatter;
use Filament\Actions\Action;
use Illuminate\Support\Facades\Auth;

trait InteractsWithDberpReportPage
{
    use InteractsWithDberpNavigationGroupBreadcrumbs;

    protected function makeReportPageExportCsvAction(string $reportKey): Action
    {
        return DberpExportCsvFilamentAction::forReportPage(
            $reportKey,
            fn (): string => $this->buildReportExportUrl($reportKey, $this->form->getState()),
            fn (): bool => app(DberpPermissionService::class)->allowsReportExport(Auth::user(), $reportKey),
        );
    }

    /**
     * 报表页 Blade 展示用：按字段语义格式化为金额 / 数量 / 单价等（不改聚合计算结果）。
     */
    public function dberpFormatReportScalar(string $fieldKey, mixed $value): string
    {
        if ($value === null || $value === '') {
            return '—';
        }

        if (is_string($value)) {
            $trimmed = trim($value);

            if ($trimmed === '') {
                return '—';
            }

            // 分析服务已返回带货币符号等展示串时，避免二次 money() 解析失败显示为「-」。
            if (! is_numeric($trimmed)) {
                return $trimmed;
            }
        }

        $k = strtolower($fieldKey);

        if (preg_match('/_count$|_count_|(^|_)count($|_)/', $k) && ! str_contains($k, 'amount')) {
            return (string) $value;
        }

        if (str_contains($k, 'weight') && ! str_contains($k, 'font')) {
            return DberpNumberFormatter::weight($value);
        }

        if ((str_contains($k, 'quantity') || str_contains($k, '_qty') || preg_match('/(^|_)(inbound|outbound|realtime|available|arrived|remaining)(_|$)/', $k))
            && ! str_contains($k, 'amount')) {
            return DberpNumberFormatter::quantity($value);
        }

        if (str_contains($k, 'cost_price') || str_contains($k, 'average_cost') || str_contains($k, 'conversion_price')) {
            return DberpNumberFormatter::costPrice($value);
        }

        if (str_contains($k, 'unit_price') || (str_contains($k, 'price') && ! str_contains($k, 'cost'))) {
            return DberpNumberFormatter::price($value);
        }

        if (str_contains($k, 'amount') || str_contains($k, 'balance') || str_contains($k, 'receivable')
            || str_contains($k, 'payable') || str_contains($k, 'paid') || str_contains($k, 'unpaid')
            || str_contains($k, 'receipt') || str_contains($k, 'payment') || str_contains($k, 'written')
            || str_contains($k, 'settled') || str_contains($k, 'subtotal') || str_contains($k, 'final')
            || str_contains($k, 'current_amount') || str_contains($k, 'bucket_') || str_contains($k, 'total_amount')) {
            return DberpNumberFormatter::money($value);
        }

        return (string) $value;
    }

    protected function buildReportExportUrl(string $reportKey, array $filters): string
    {
        return route('dberp.reports.export', ['report' => $reportKey]).DberpFilamentListPageUrl::queryString(
            $this->compactReportFilters($filters),
        );
    }

    /**
     * @param  array<string, mixed>  $filters
     * @param  array<string, mixed>  $extra
     */
    protected function logReportAudit(string $action, string $reportKey, string $reportName, array $filters = [], array $extra = []): void
    {
        $snapshot = $this->compactReportFilters($filters);

        app(DberpAuditService::class)->log($action, null, null, array_merge([
            'report_name' => $reportName,
            'report_key' => $reportKey,
            'filter_summary' => $this->formatReportFilters($snapshot),
        ], $extra));
    }

    /**
     * @param  array<string, mixed>  $filters
     * @return array<string, mixed>
     */
    protected function compactReportFilters(array $filters): array
    {
        $compacted = [];

        foreach ($filters as $key => $value) {
            if (is_array($value)) {
                $nested = $this->compactReportFilters($value);

                if ($nested !== []) {
                    $compacted[$key] = $nested;
                }

                continue;
            }

            if ($value === null || $value === '') {
                continue;
            }

            $compacted[$key] = $value;
        }

        return $compacted;
    }

    /**
     * @param  array<string, mixed>  $filters
     */
    private function formatReportFilters(array $filters): string
    {
        if ($filters === []) {
            return '当前为默认筛选';
        }

        $pairs = [];

        foreach ($this->flattenReportFilters($filters) as $key => $value) {
            $pairs[] = $key.'='.$value;
        }

        return implode('；', $pairs);
    }

    /**
     * @param  array<string, mixed>  $filters
     * @return array<string, string>
     */
    private function flattenReportFilters(array $filters, string $prefix = ''): array
    {
        $flattened = [];

        foreach ($filters as $key => $value) {
            $fullKey = $prefix === '' ? (string) $key : $prefix.'.'.$key;

            if (is_array($value)) {
                $flattened = array_merge($flattened, $this->flattenReportFilters($value, $fullKey));

                continue;
            }

            if (is_bool($value)) {
                $flattened[$fullKey] = $value ? '是' : '否';

                continue;
            }

            $flattened[$fullKey] = (string) $value;
        }

        return $flattened;
    }
}
