<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Concerns\ResolvesPlatformAdminContext;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Models\Order;
use App\Models\Product;
use App\Models\Merchant;
use App\Models\Plan;
use App\Models\PlatformOrder;
use App\Models\SiteSubscription;
use App\Models\User;
use App\Support\CacheKeys;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\View\View;

class DashboardController extends Controller
{
    use ResolvesPlatformAdminContext;

    public function index(Request $request): View
    {
        $admin = $this->ensurePlatformAdmin($request);

        $stats = Cache::remember(
            CacheKeys::platformDashboardStats(),
            now()->addMinutes(10),
            fn () => [
                'merchants' => Merchant::count(),
                'admins' => Admin::count(),
                'users' => User::count(),
                'products' => Product::count(),
                'orders' => Order::count(),

                // 收费中心（平台侧）
                'plans' => Plan::count(),
                'site_subscriptions' => SiteSubscription::count(),
                'site_subscriptions_expired' => SiteSubscription::query()
                    ->whereNotNull('ends_at')
                    ->where('ends_at', '<', now())
                    ->count(),
                'site_subscriptions_expiring_7d' => SiteSubscription::query()
                    ->whereNotNull('ends_at')
                    ->where('ends_at', '>=', now())
                    ->where('ends_at', '<', now()->addDays(7))
                    ->count(),
                'platform_orders' => PlatformOrder::count(),
                // 可BMPA处理（尽量贴近后端治理安全阀）：
                // - pending + unpaid
                // - 排除：存在退款轨迹（refund_total > 0）
                // - 排除：续费缺订阅（order_type=renewal 且 site_subscription_id 为空）
                'platform_orders_unpaid_pending' => (function () {
                    $q = PlatformOrder::query()
                        ->where('payment_status', 'unpaid')
                        ->where('status', 'pending')
                        ->where(function ($b) {
                            $b->where('order_type', '!=', 'renewal')
                                ->orWhereNotNull('site_subscription_id');
                        });

                    $driver = $q->getQuery()->getConnection()->getDriverName();

                    if ($driver === 'sqlite') {
                        $refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_EXTRACT(meta, '$.refund_summary.total_amount') AS REAL) ELSE (SELECT IFNULL(SUM(CAST(JSON_EXTRACT(value, '$.amount') AS REAL)), 0) FROM json_each(COALESCE(JSON_EXTRACT(meta, '$.refund_receipts'), '[]'))) END)";
                        $q->whereRaw("ROUND(($refundTotalExpr) * 100) <= 0");
                    } else {
                        $refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_UNQUOTE(JSON_EXTRACT(meta, '$.refund_summary.total_amount')) AS DECIMAL(12,2)) ELSE (SELECT IFNULL(SUM(j.amount), 0) FROM JSON_TABLE(meta, '$.refund_receipts[*]' COLUMNS(amount DECIMAL(12,2) PATH '$.amount')) j) END)";
                        $q->whereRaw("ROUND(($refundTotalExpr) * 100) <= 0");
                    }

                    return $q->count();
                })(),
                'platform_orders_paid_pending' => PlatformOrder::query()
                    ->where('payment_status', 'paid')
                    ->where('status', 'pending')
                    // 口径对齐“待生效”语义（sync_status=unsynced）：未同步 + 非失败
                    ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation.subscription_id') IS NULL")
                    ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation_error.message') IS NULL")
                    ->count(),
                // 可同步：沿用平台订单列表口径（paid+activated+未同步+无失败），且排除续费缺订阅脏数据
                'platform_orders_syncable' => PlatformOrder::query()
                    ->where('payment_status', 'paid')
                    ->where('status', 'activated')
                    ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation.subscription_id') IS NULL")
                    ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation_error.message') IS NULL")
                    ->where(function ($q) {
                        $q->where('order_type', '!=', 'renewal')
                            ->orWhereNotNull('site_subscription_id');
                    })
                    ->count(),
                // 同步失败：沿用平台订单列表口径（meta.subscription_activation_error.message 存在即失败）
                'platform_orders_sync_failed' => PlatformOrder::query()
                    ->whereRaw("JSON_EXTRACT(meta, '$.subscription_activation_error.message') IS NOT NULL")
                    ->count(),
                'platform_orders_renewal_missing_subscription' => PlatformOrder::query()
                    ->where('order_type', 'renewal')
                    ->whereNull('site_subscription_id')
                    ->count(),
                // BMPA 失败：用于运营快速定位“批量标记支付并生效”失败的订单集合
                'platform_orders_bmpa_failed' => PlatformOrder::query()
                    ->whereRaw("JSON_EXTRACT(meta, '$.batch_mark_paid_and_activate_error.message') IS NOT NULL")
                    ->count(),
                // BMPA 成功：用于运营抽样复核（spot-check）批量标记支付并生效的成功集合
                // 口径与平台订单列表 bmpa_success_only=1 一致：run_id 存在且 error.message 为空
                'platform_orders_bmpa_success' => PlatformOrder::query()
                    ->whereRaw("JSON_EXTRACT(meta, '$.batch_mark_paid_and_activate.run_id') IS NOT NULL")
                    ->whereRaw("JSON_EXTRACT(meta, '$.batch_mark_paid_and_activate_error.message') IS NULL")
                    ->count(),
                // 无回执（已支付但缺少回执证据）：用于治理“已付但无回执”的风险订单
                'platform_orders_paid_no_receipt' => PlatformOrder::query()
                    ->where('payment_status', 'paid')
                    ->whereRaw("JSON_EXTRACT(meta, '$.payment_summary.total_amount') IS NULL")
                    ->whereRaw("JSON_EXTRACT(meta, '$.payment_receipts[0].amount') IS NULL")
                    ->count(),
                // 对账不一致（基于 paid_amount vs 回执总额，容差见 config('saasshop.amounts.tolerance')）
                'platform_orders_reconcile_mismatch' => (function () {
                    $tol = (float) config('saasshop.amounts.tolerance', 0.01);
                    $tolCents = (int) round($tol * 100);
                    $tolCents = max(1, $tolCents);

                    $q = PlatformOrder::query();
                    $driver = $q->getQuery()->getConnection()->getDriverName();

                    // 重要：与 PlatformOrder::isReconcileMismatch() 口径一致：若无回执证据，不判定 mismatch（而是走“无回执”治理集合）
                    $q->where(function ($b) {
                        $b->whereRaw("JSON_EXTRACT(meta, '$.payment_summary.total_amount') IS NOT NULL")
                          ->orWhereRaw("JSON_EXTRACT(meta, '$.payment_receipts[0].amount') IS NOT NULL");
                    });

                    if ($driver === 'sqlite') {
                        $q->whereRaw("ABS(ROUND((CASE WHEN JSON_EXTRACT(meta, '$.payment_summary.total_amount') IS NOT NULL THEN CAST(JSON_EXTRACT(meta, '$.payment_summary.total_amount') AS REAL) ELSE (SELECT IFNULL(SUM(CAST(JSON_EXTRACT(value, '$.amount') AS REAL)), 0) FROM json_each(COALESCE(JSON_EXTRACT(meta, '$.payment_receipts'), '[]'))) END) * 100) - ROUND(paid_amount * 100)) >= {$tolCents}");
                    } else {
                        $q->whereRaw("ABS(ROUND((CASE WHEN JSON_EXTRACT(meta, '$.payment_summary.total_amount') IS NOT NULL THEN CAST(JSON_UNQUOTE(JSON_EXTRACT(meta, '$.payment_summary.total_amount')) AS DECIMAL(12,2)) ELSE (SELECT IFNULL(SUM(j.amount), 0) FROM JSON_TABLE(meta, '$.payment_receipts[*]' COLUMNS(amount DECIMAL(12,2) PATH '$.amount')) j) END) * 100) - ROUND(paid_amount * 100)) >= {$tolCents}");
                    }

                    return $q->count();
                })(),
                // 退款数据不一致（口径与平台订单列表 refund_inconsistent=1 一致）
                // 注意：仅当退款总额 > 0 时才参与不一致判定（避免 refund_summary.total_amount=0 的“空字段”噪音被计入）。
                'platform_orders_refund_inconsistent' => (function () {
                    $tol = (float) config('saasshop.amounts.tolerance', 0.01);
                    $tolCents = (int) round($tol * 100);
                    $tolCents = max(1, $tolCents);

                    $q = PlatformOrder::query();
                    $driver = $q->getQuery()->getConnection()->getDriverName();

                    if ($driver === 'sqlite') {
                        $refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_EXTRACT(meta, '$.refund_summary.total_amount') AS REAL) ELSE (SELECT IFNULL(SUM(CAST(JSON_EXTRACT(value, '$.amount') AS REAL)), 0) FROM json_each(COALESCE(JSON_EXTRACT(meta, '$.refund_receipts'), '[]'))) END)";

                        // 只统计退款总额 > 0 的订单
                        $q->whereRaw("ROUND(($refundTotalExpr) * 100) > 0");

                        $q->where(function ($b) use ($refundTotalExpr, $tolCents) {
                            $b->where(function ($q2) use ($refundTotalExpr, $tolCents) {
                                $q2->where('payment_status', 'refunded')
                                    ->whereRaw('paid_amount > 0')
                                    ->whereRaw("(ROUND($refundTotalExpr * 100) + {$tolCents}) < ROUND(paid_amount * 100)");
                            })->orWhere(function ($q2) use ($refundTotalExpr, $tolCents) {
                                $q2->where('payment_status', '!=', 'refunded')
                                    ->whereRaw('paid_amount > 0')
                                    ->whereRaw("ROUND($refundTotalExpr * 100) >= (ROUND(paid_amount * 100) + {$tolCents})");
                            });
                        });
                    } else {
                        $refundTotalExpr = "(CASE WHEN JSON_EXTRACT(meta, '$.refund_summary.total_amount') IS NOT NULL THEN CAST(JSON_UNQUOTE(JSON_EXTRACT(meta, '$.refund_summary.total_amount')) AS DECIMAL(12,2)) ELSE (SELECT IFNULL(SUM(j.amount), 0) FROM JSON_TABLE(meta, '$.refund_receipts[*]' COLUMNS(amount DECIMAL(12,2) PATH '$.amount')) j) END)";

                        // 只统计退款总额 > 0 的订单
                        $q->whereRaw("ROUND(($refundTotalExpr) * 100) > 0");

                        $q->where(function ($b) use ($refundTotalExpr, $tolCents) {
                            $b->where(function ($q2) use ($refundTotalExpr, $tolCents) {
                                $q2->where('payment_status', 'refunded')
                                    ->whereRaw('paid_amount > 0')
                                    ->whereRaw("(ROUND($refundTotalExpr * 100) + {$tolCents}) < ROUND(paid_amount * 100)");
                            })->orWhere(function ($q2) use ($refundTotalExpr, $tolCents) {
                                $q2->where('payment_status', '!=', 'refunded')
                                    ->whereRaw('paid_amount > 0')
                                    ->whereRaw("ROUND($refundTotalExpr * 100) >= (ROUND(paid_amount * 100) + {$tolCents})");
                            });
                        });
                    }

                    return $q->count();
                })(),

                // 站点治理
                'active_merchants' => Merchant::query()->where('status', 'active')->count(),
                'pending_orders' => Order::query()->where('status', 'pending')->count(),
            ]
        );

        // 统一基准时间：避免本方法内多次 now() 调用在跨天瞬间造成口径漂移
        $baseNow = now();

        // 趋势卡（最小可用）：近 7 天平台订单按天统计（订单数 + 已付金额）
        $trendDays = 7;
        $trendStart = $baseNow->copy()->startOfDay()->subDays($trendDays - 1);
        $trendEnd = $baseNow->copy()->endOfDay();

        // 统一提供给视图做“趋势/排行/占比”跳转的日期范围口径，避免 Blade 内重复 now() 计算导致漂移。
        $dashboardRangeFrom7d = (string) $trendStart->format('Y-m-d');
        $dashboardRangeTo7d = (string) $trendEnd->format('Y-m-d');

        $trendRawRows = PlatformOrder::query()
            ->selectRaw("DATE(created_at) as d")
            ->selectRaw('COUNT(*) as cnt')
            ->selectRaw("SUM(CASE WHEN payment_status = 'paid' THEN paid_amount ELSE 0 END) as paid_sum")
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->groupBy('d')
            ->orderBy('d')
            ->get();

        $trendByDate = [];
        foreach ($trendRawRows as $r) {
            $trendByDate[(string) $r->d] = [
                'date' => (string) $r->d,
                'count' => (int) ($r->cnt ?? 0),
                'paid_sum' => (float) ($r->paid_sum ?? 0),
            ];
        }

        $platformOrderTrend7d = [];
        for ($i = 0; $i < $trendDays; $i++) {
            $day = $trendStart->copy()->addDays($i)->format('Y-m-d');
            $platformOrderTrend7d[] = $trendByDate[$day] ?? [
                'date' => $day,
                'count' => 0,
                'paid_sum' => 0.0,
            ];
        }

        $recentPlatformOrders = PlatformOrder::query()
            ->with(['merchant', 'plan'])
            ->orderByDesc('id')
            ->limit(2)
            ->get();

        // 占比卡（最小可用）：近 7 天按套餐统计平台订单数量 TopN
        // 说明：
        // - Top5 数据用于“对比/聚焦”（减少噪音）
        // - total 用于计算“占比/覆盖率”，避免将 Top5 误当全量
        $planOrderShareTotal = PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->whereNotNull('plan_id')
            ->count();

        $planOrderShare = PlatformOrder::query()
            ->selectRaw('plan_id, COUNT(*) as cnt')
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->whereNotNull('plan_id')
            ->groupBy('plan_id')
            ->orderByDesc('cnt')
            ->limit(5)
            ->get()
            ->map(function ($row) {
                return [
                    'plan_id' => (int) $row->plan_id,
                    'count' => (int) $row->cnt,
                ];
            })
            ->values()
            ->all();

        $planIdToName = Plan::query()->pluck('name', 'id')->all();

        // 排行卡（最小可用）：近 7 天站点收入排行 Top5（按已付金额）
        // 说明：只统计 payment_status=paid，避免“未支付订单=0金额”混入排行造成噪音。
        $merchantRevenueRank7d = PlatformOrder::query()
            ->selectRaw('merchant_id, COUNT(*) as cnt')
            ->selectRaw('SUM(paid_amount) as paid_sum')
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'paid')
            ->groupBy('merchant_id')
            ->orderByDesc('paid_sum')
            ->limit(5)
            ->get()
            ->map(function ($row) {
                return [
                    'merchant_id' => (int) ($row->merchant_id ?? 0),
                    'count' => (int) ($row->cnt ?? 0),
                    'paid_sum' => (float) ($row->paid_sum ?? 0),
                ];
            })
            ->values()
            ->all();

        // 用于计算“Top5覆盖率/其它”的全量分母（近 7 天全站点已付总额/总订单数）
        $merchantRevenueTotalPaid7d = (float) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'paid')
            ->sum('paid_amount');

        $merchantRevenueTotalOrders7d = (int) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'paid')
            ->count();

        $merchantIdToName = Merchant::query()->pluck('name', 'id')->all();

        // 平台定位（运营版）：北极星指标 + 明确治理入口（不暴露组合维度）
        $range30Start = $baseNow->copy()->subDays(29)->startOfDay();
        $range30End = $baseNow->copy()->endOfDay();
        $range30From = (string) $range30Start->format('Y-m-d');
        $range30To = (string) $range30End->format('Y-m-d');

        $paidRevenue30d = (float) PlatformOrder::query()
            ->where('payment_status', 'paid')
            ->whereBetween('created_at', [$range30Start, $range30End])
            ->sum('paid_amount');

        $activePaidMerchants = (int) SiteSubscription::query()
            ->whereNotNull('merchant_id')
            ->where('status', 'activated')
            ->whereNotNull('ends_at')
            ->where('ends_at', '>=', $baseNow)
            ->distinct()
            ->count('merchant_id');

        $renewalCreated30d = (int) PlatformOrder::query()
            ->where('order_type', 'renewal')
            ->whereBetween('created_at', [$range30Start, $range30End])
            ->count();
        $renewalSuccess30d = (int) PlatformOrder::query()
            ->where('order_type', 'renewal')
            ->where('payment_status', 'paid')
            ->where('status', 'activated')
            ->whereBetween('created_at', [$range30Start, $range30End])
            ->count();
        $renewalSuccessRate30d = $renewalCreated30d > 0
            ? min(100, max(0, round(($renewalSuccess30d / $renewalCreated30d) * 100, 1)))
            : 0;

        $ordersTotal7d = (int) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->count();

        $funnelUnpaidPending7d = (int) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'unpaid')
            ->where('status', 'pending')
            ->count();
        $funnelPaid7d = (int) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'paid')
            ->count();
        $funnelPaidActivated7d = (int) PlatformOrder::query()
            ->whereBetween('created_at', [$trendStart, $trendEnd])
            ->where('payment_status', 'paid')
            ->where('status', 'activated')
            ->count();

        // 将平台定位的关键指标与“可执行动作入口”绑定（回到仪表盘自身）
        $opsLinks = [
            'revenue_30d_paid_orders' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
                'payment_status' => 'paid',
                'created_from' => $range30From,
                'created_to' => $range30To,
            ]), \App\Support\BackUrl::selfWithoutBack()),
            'active_paid_merchants_subscriptions' => \App\Support\BackUrl::withBack('/admin/site-subscriptions?' . \Illuminate\Support\Arr::query([
                'status' => 'activated',
                // 口径对齐 active_paid_merchants：已生效且未到期（ends_at >= today）
                'ends_from' => (string) $baseNow->format('Y-m-d'),
                'page' => null,
            ]), \App\Support\BackUrl::selfWithoutBack()),
            'renewal_orders_30d' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
                'order_type' => 'renewal',
                'created_from' => $range30From,
                'created_to' => $range30To,
            ]), \App\Support\BackUrl::selfWithoutBack()),
            'funnel_unpaid_pending_7d' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
                'payment_status' => 'unpaid',
                'status' => 'pending',
                'created_from' => $dashboardRangeFrom7d,
                'created_to' => $dashboardRangeTo7d,
            ]), \App\Support\BackUrl::selfWithoutBack()),
            'funnel_paid_7d' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
                'payment_status' => 'paid',
                'created_from' => $dashboardRangeFrom7d,
                'created_to' => $dashboardRangeTo7d,
            ]), \App\Support\BackUrl::selfWithoutBack()),
            'funnel_paid_activated_7d' => \App\Support\BackUrl::withBack('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
                'payment_status' => 'paid',
                'status' => 'activated',
                'created_from' => $dashboardRangeFrom7d,
                'created_to' => $dashboardRangeTo7d,
            ]), \App\Support\BackUrl::selfWithoutBack()),
        ];

        return view('admin.dashboard', [
            'adminName' => $admin->name,
            'stats' => $stats,
            'platformOrderTrend7d' => $platformOrderTrend7d,
            'recentPlatformOrders' => $recentPlatformOrders,
            'dashboardRangeFrom7d' => $dashboardRangeFrom7d,
            'dashboardRangeTo7d' => $dashboardRangeTo7d,
            // 注意：旧版的 platformPositioning 已弃用；当前仪表盘使用 platformOpsOverview 作为“平台定位（运营版）”的数据源。
            // 这里先移除 platformPositioning，避免遗留变量命名不一致导致 /admin 500，破坏 Dashboard 回归基线。
            'planOrderShare' => $planOrderShare,
            'planOrderShareTotal' => (int) $planOrderShareTotal,
            'planIdToName' => $planIdToName,
            'merchantRevenueRank7d' => $merchantRevenueRank7d,
            'merchantRevenueTotalPaid7d' => (float) $merchantRevenueTotalPaid7d,
            'merchantRevenueTotalOrders7d' => (int) $merchantRevenueTotalOrders7d,
            'merchantIdToName' => $merchantIdToName,
            'platformAdmin' => $admin,
            'cacheMeta' => [
                'store' => config('cache.default'),
                'ttl' => '10m',
            ],
            'platformOpsOverview' => [
                // 北极星指标
                'paid_revenue_30d' => $paidRevenue30d,
                'active_paid_merchants' => $activePaidMerchants,
                'renewal_success_rate_30d' => $renewalSuccessRate30d,
                'renewal_success_30d' => $renewalSuccess30d,
                'renewal_created_30d' => $renewalCreated30d,

                // 漏斗（近7天）
                'orders_total_7d' => $ordersTotal7d,
                'funnel_unpaid_pending_7d' => $funnelUnpaidPending7d,
                'funnel_paid_7d' => $funnelPaid7d,
                'funnel_paid_activated_7d' => $funnelPaidActivated7d,

                // 待处理治理（积压口径，全量）
                'govern_bmpa_processable' => (int) ($stats['platform_orders_unpaid_pending'] ?? 0),
                'govern_syncable' => (int) ($stats['platform_orders_syncable'] ?? 0),
                'govern_sync_failed' => (int) ($stats['platform_orders_sync_failed'] ?? 0),

                'links' => $opsLinks,
            ],

            'platformOverview' => [
                'system_role' => '总台管理',
                'current_scope' => '总台运营方视角',
                'merchant_mode' => '统一管理多个站点',
                'channel_count' => 5,
                'active_merchants' => $stats['active_merchants'],
                'pending_orders' => $stats['pending_orders'],
            ],
        ]);
    }
}
