<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Concerns\ResolvesPlatformAdminContext;
use App\Http\Controllers\Controller;
use App\Models\Plan;
use App\Models\PlatformOrder;
use App\Models\SiteSubscription;
use App\Support\BackUrl;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\StreamedResponse;

class PlanController extends Controller
{
    use ResolvesPlatformAdminContext;

    public function export(Request $request): StreamedResponse
    {
        $this->ensurePlatformAdmin($request);

        // 安全阀：必须显式声明 download=1，避免浏览器预取/误触发导致频繁导出
        if ((string) $request->query('download', '') !== '1') {
            abort(400, 'download=1 required');
        }

        $filters = [
            'status' => trim((string) $request->query('status', '')),
            'billing_cycle' => trim((string) $request->query('billing_cycle', '')),
            'keyword' => trim((string) $request->query('keyword', '')),
            'published' => trim((string) $request->query('published', '')),
        ];

        $query = $this->applyFilters(Plan::query(), $filters)
            ->orderBy('sort')
            ->orderByDesc('id');

        $filename = 'plans_' . now()->format('Ymd_His') . '.csv';

        return response()->streamDownload(function () use ($query) {
            $out = fopen('php://output', 'w');

            // UTF-8 BOM，避免 Excel 打开中文乱码
            fwrite($out, "\xEF\xBB\xBF");

            fputcsv($out, [
                'ID',
                '套餐名称',
                '编码',
                '计费周期',
                '售价',
                '划线价',
                '状态',
                '排序',
                '发布时间',
                '描述',
            ]);

            $query->chunkById(500, function ($plans) use ($out) {
                foreach ($plans as $plan) {
                    fputcsv($out, [
                        $plan->id,
                        $plan->name,
                        $plan->code,
                        $plan->billing_cycle,
                        (float) $plan->price,
                        (float) $plan->list_price,
                        $plan->status,
                        (int) $plan->sort,
                        optional($plan->published_at)->format('Y-m-d H:i:s') ?: '',
                        $plan->description ?: '',
                    ]);
                }
            });

            fclose($out);
        }, $filename, [
            'Content-Type' => 'text/csv; charset=UTF-8',
        ]);
    }

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

        $filters = [
            'status' => trim((string) $request->query('status', '')),
            'billing_cycle' => trim((string) $request->query('billing_cycle', '')),
            'keyword' => trim((string) $request->query('keyword', '')),
            // 发布状态筛选（按 published_at 是否为空）
            // - published：已发布（published_at not null）
            // - unpublished：未发布（published_at is null）
            'published' => trim((string) $request->query('published', '')),
        ];

        $plansQuery = $this->applyFilters(Plan::query()->withCount(['subscriptions', 'platformOrders']), $filters);

        $plans = (clone $plansQuery)
            ->orderBy('sort')
            ->orderByDesc('id')
            ->paginate(10)
            ->withQueryString();

        return view('admin.plans.index', [
            'plans' => $plans,
            'filters' => $filters,
            'filterOptions' => [
                'statuses' => $this->statusLabels(),
                'billingCycles' => $this->billingCycleLabels(),
            ],
            'summaryStats' => [
                'total_plans' => (clone $plansQuery)->count(),
                'active_plans' => (clone $plansQuery)->where('status', 'active')->count(),
                'monthly_plans' => (clone $plansQuery)->where('billing_cycle', 'monthly')->count(),
                'yearly_plans' => (clone $plansQuery)->where('billing_cycle', 'yearly')->count(),
                'published_plans' => (clone $plansQuery)->whereNotNull('published_at')->count(),
                'unpublished_plans' => (clone $plansQuery)->whereNull('published_at')->count(),
                // 治理联动：当前筛选范围内关联订阅/订单总量
                // 注意：subscriptions_count/platform_orders_count 是 withCount() 的别名列，不能直接 sum('subscriptions_count')，
                // 否则 MySQL 会报 Unknown column。
                'subscriptions_count' => (function () use ($plansQuery) {
                    $planIds = (clone $plansQuery)->pluck('id')->all();
                    if (count($planIds) === 0) {
                        return 0;
                    }

                    return (int) SiteSubscription::query()->whereIn('plan_id', $planIds)->count();
                })(),
                'platform_orders_count' => (function () use ($plansQuery) {
                    $planIds = (clone $plansQuery)->pluck('id')->all();
                    if (count($planIds) === 0) {
                        return 0;
                    }

                    return (int) PlatformOrder::query()->whereIn('plan_id', $planIds)->count();
                })(),
            ],
            'statusLabels' => $this->statusLabels(),
            'billingCycleLabels' => $this->billingCycleLabels(),
        ]);
    }

    public function create(Request $request): View
    {
        $this->ensurePlatformAdmin($request);

        $back = (string) $request->query('back', '');
        // back 安全阀：统一收敛到 BackUrl::sanitizeForLinks（用于 Blade `{!! !!}` 原样输出场景）
        $safeBack = BackUrl::sanitizeForLinks($back);

        return view('admin.plans.form', [
            'plan' => new Plan(),
            'statusLabels' => $this->statusLabels(),
            'billingCycleLabels' => $this->billingCycleLabels(),
            'formAction' => '/admin/plans',
            'method' => 'post',
            'back' => $safeBack,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $data = $this->validatePlan($request);

        $back = (string) $request->input('back', '');
        // back 安全阀：统一收敛到 BackUrl::sanitizeForLinks（用于 Blade `{!! !!}` 原样输出场景）
        $safeBack = BackUrl::sanitizeForLinks($back);

        $plan = Plan::query()->create($data);

        if ($safeBack !== '') {
            return redirect($safeBack)->with('success', '套餐已创建：' . $plan->name);
        }

        return redirect('/admin/plans')->with('success', '套餐已创建：' . $plan->name);
    }

    public function edit(Request $request, Plan $plan): View
    {
        $this->ensurePlatformAdmin($request);

        $back = (string) $request->query('back', '');
        // back 安全阀：统一收敛到 BackUrl::sanitizeForLinks（用于 Blade `{!! !!}` 原样输出场景）
        $safeBack = BackUrl::sanitizeForLinks($back);

        return view('admin.plans.form', [
            'plan' => $plan,
            'statusLabels' => $this->statusLabels(),
            'billingCycleLabels' => $this->billingCycleLabels(),
            'formAction' => '/admin/plans/' . $plan->id,
            'method' => 'post',
            'back' => $safeBack,
        ]);
    }

    public function setStatus(Request $request, Plan $plan): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $data = $request->validate([
            'status' => ['required', Rule::in(array_keys($this->statusLabels()))],
        ]);

        $plan->status = (string) $data['status'];

        // 最小治理：当启用且未设置发布时间时，自动补一个发布时间（便于运营口径）
        if ($plan->status === 'active' && $plan->published_at === null) {
            $plan->published_at = now();
        }

        $plan->save();

        return redirect()->back()->with('success', '套餐状态已更新：' . ($this->statusLabels()[$plan->status] ?? $plan->status));
    }

    public function setPublished(Request $request, Plan $plan): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        $data = $request->validate([
            'published' => ['required', Rule::in(['0', '1'])],
        ]);

        $published = (string) $data['published'] === '1';

        if ($published) {
            // 最小治理：发布动作仅写 published_at，不改变 status（避免误把草稿/停用套餐误启用）。
            $plan->published_at = $plan->published_at ?? now();
        } else {
            $plan->published_at = null;
        }

        $plan->save();

        return redirect()->back()->with('success', $published ? '套餐已发布' : '套餐已取消发布');
    }

    public function update(Request $request, Plan $plan): RedirectResponse
    { 
        $this->ensurePlatformAdmin($request);

        $data = $this->validatePlan($request, $plan->id);

        $back = (string) $request->input('back', '');
        // back 安全阀：统一收敛到 BackUrl::sanitizeForLinks（用于 Blade `{!! !!}` 原样输出场景）
        $safeBack = BackUrl::sanitizeForLinks($back);

        $plan->update($data);

        if ($safeBack !== '') {
            return redirect($safeBack)->with('success', '套餐已更新：' . $plan->name);
        }

        return redirect('/admin/plans')->with('success', '套餐已更新：' . $plan->name);
    }

    protected function validatePlan(Request $request, ?int $planId = null): array
    {
        $data = $request->validate([
            'code' => ['required', 'string', 'max:50', 'regex:/^[A-Za-z0-9-_]+$/', Rule::unique('plans', 'code')->ignore($planId)],
            'name' => ['required', 'string', 'max:100'],
            'billing_cycle' => ['required', Rule::in(array_keys($this->billingCycleLabels()))],
            'price' => ['required', 'numeric', 'min:0'],
            'list_price' => ['nullable', 'numeric', 'min:0'],
            'status' => ['required', Rule::in(array_keys($this->statusLabels()))],
            'sort' => ['nullable', 'integer', 'min:0'],
            'description' => ['nullable', 'string'],
            'published_at' => ['nullable', 'date'],
        ], [
            'code.regex' => '套餐编码仅支持字母、数字、短横线与下划线。',
        ]);

        $data['sort'] = $data['sort'] ?? 0;

        return $data;
    }

    protected function applyFilters(Builder $query, array $filters): Builder
    {
        return $query
            ->when($filters['status'] !== '', fn (Builder $builder) => $builder->where('status', $filters['status']))
            ->when($filters['billing_cycle'] !== '', fn (Builder $builder) => $builder->where('billing_cycle', $filters['billing_cycle']))
            ->when(($filters['published'] ?? '') !== '', function (Builder $builder) use ($filters) {
                $published = (string) ($filters['published'] ?? '');
                if ($published === 'published') {
                    $builder->whereNotNull('published_at');
                } elseif ($published === 'unpublished') {
                    $builder->whereNull('published_at');
                }
            })
            ->when($filters['keyword'] !== '', function (Builder $builder) use ($filters) {
                $keyword = $filters['keyword'];

                $builder->where(function (Builder $subQuery) use ($keyword) {
                    $subQuery->where('name', 'like', '%' . $keyword . '%')
                        ->orWhere('code', 'like', '%' . $keyword . '%')
                        ->orWhere('description', 'like', '%' . $keyword . '%');
                });
            });
    }

    public function seedDefaults(Request $request): RedirectResponse
    {
        $this->ensurePlatformAdmin($request);

        // 安全护栏：仅当当前库没有任何套餐时才允许一键初始化
        $existingCount = Plan::query()->count();
        if ($existingCount > 0) {
            return redirect()->back()->with('error', '当前已有套餐（' . $existingCount . ' 条），为避免污染运营数据，已阻止一键初始化。');
        }

        $now = now();
        $defaults = [
            [
                'code' => 'starter_monthly',
                'name' => '基础版（月付）',
                'billing_cycle' => 'monthly',
                'price' => 99,
                'list_price' => 129,
                'status' => 'active',
                'sort' => 10,
                'description' => '适合刚开站的试运营阶段，可用于 Demo 场景。',
                'published_at' => $now,
            ],
            [
                'code' => 'pro_yearly',
                'name' => '专业版（年付）',
                'billing_cycle' => 'yearly',
                'price' => 1999,
                'list_price' => 2599,
                'status' => 'active',
                'sort' => 20,
                'description' => '面向成长型站点，后续搭配授权项配置。',
                'published_at' => $now,
            ],
        ];

        foreach ($defaults as $row) {
            Plan::query()->create($row);
        }

        return redirect('/admin/plans')->with('success', '已初始化默认套餐：' . count($defaults) . ' 条。');
    }

    protected function statusLabels(): array
    {
        return [
            'active' => '启用中',
            'draft' => '草稿中',
            'inactive' => '未启用',
        ];
    }

    protected function billingCycleLabels(): array
    {
        return [
            'monthly' => '月付',
            'quarterly' => '季付',
            'yearly' => '年付',
            'one_time' => '一次性',
        ];
    }
}
