"use client";

import { useCallback, useEffect, useMemo, useState } from "react";

import { getPlayEffective } from "@/api/play";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { getLotteryRequestLocale } from "@/lib/lottery-locale";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import type {
  PlayEffectivePayload,
  PlayEffectivePlayRow,
} from "@/types/api/play-effective";

const DEFAULT_POLL_MS = 120_000;

function pickDisplayName(row: PlayEffectivePlayRow): string {
  const loc = getLotteryRequestLocale();
  if (loc === "zh") {
    return row.display_name_zh ?? row.display_name_en ?? row.play_code;
  }
  if (loc === "ne") {
    return row.display_name_ne ?? row.display_name_en ?? row.play_code;
  }
  return row.display_name_en ?? row.display_name_zh ?? row.play_code;
}

function pickRuleText(row: PlayEffectivePlayRow): string | null {
  const c = row.config;
  if (!c) {
    return null;
  }
  const loc = getLotteryRequestLocale();
  if (loc === "zh") {
    return c.rule_text_zh ?? c.rule_text_en;
  }
  if (loc === "ne") {
    return c.rule_text_ne ?? c.rule_text_en;
  }
  return c.rule_text_en ?? c.rule_text_zh;
}

/** 主数据开关 + 配置版本内开关，同时有 config 行才算对客开放 */
function isPlayOpenForPlayer(row: PlayEffectivePlayRow): boolean {
  if (!row.master_enabled || row.config === null) {
    return false;
  }
  return row.config.is_enabled;
}

type LoadState =
  | { kind: "loading" }
  | { kind: "ok"; data: PlayEffectivePayload }
  | { kind: "error"; message: string; notReady?: boolean };

function formatMoneyAmount(n: number): string {
  return new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(
    n,
  );
}

export function HallPlayCatalogPanel() {
  const [state, setState] = useState<LoadState>({ kind: "loading" });
  const currencyParam = useMemo(() => {
    const fromEnv = process.env.NEXT_PUBLIC_LOTTERY_PLAY_CURRENCY?.trim();
    return fromEnv !== undefined && fromEnv !== "" ? fromEnv : undefined;
  }, []);

  const load = useCallback(async () => {
    setState((s) => (s.kind === "ok" ? s : { kind: "loading" }));
    try {
      const data = await getPlayEffective(
        currencyParam !== undefined ? { currency: currencyParam } : undefined,
      );
      setState({ kind: "ok", data });
    } catch (e) {
      if (e instanceof LotteryApiBizError && e.code === 9004) {
        setState({
          kind: "error",
          message:
            "玩法配置尚未初始化。请在 Laravel 执行含 OperationalConfigV1Seeder 的 seed。",
          notReady: true,
        });
        return;
      }
      const msg =
        e instanceof LotteryApiBizError
          ? e.message
          : "加载玩法配置失败，请稍后重试。";
      setState({ kind: "error", message: msg });
    }
  }, [currencyParam]);

  useEffect(() => {
    queueMicrotask(() => {
      void load();
    });
  }, [load]);

  useEffect(() => {
    const id = window.setInterval(() => {
      void load();
    }, DEFAULT_POLL_MS);
    return () => window.clearInterval(id);
  }, [load]);

  const body = (() => {
    if (state.kind === "loading") {
      return (
        <p className="text-sm text-muted-foreground">加载玩法与赔率…</p>
      );
    }
    if (state.kind === "error") {
      return (
        <div className="space-y-2">
          <p className="text-sm text-destructive">{state.message}</p>
          <Button type="button" size="sm" variant="secondary" onClick={() => void load()}>
            重试
          </Button>
        </div>
      );
    }

    const { data } = state;
    const ordered = [...data.plays].sort(
      (a, b) => a.sort_order - b.sort_order || a.play_code.localeCompare(b.play_code),
    );

    return (
      <div className="space-y-6">
        <p className="text-xs text-muted-foreground">
          币种 {data.currency_code} · 配置版本 play#{data.effective_versions.play_config.version_no}
          ／odds#{data.effective_versions.odds.version_no} · 限额单位为最小货币单位（与钱包一致）。
        </p>

        <div className="overflow-x-auto rounded-md border">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="min-w-[140px]">玩法</TableHead>
                <TableHead className="w-[88px] text-center">状态</TableHead>
                <TableHead className="min-w-[160px] whitespace-nowrap">下注限额</TableHead>
                <TableHead className="min-w-[100px]">赔率×</TableHead>
                <TableHead className="min-w-[200px]">说明</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {ordered.map((row) => {
                const open = isPlayOpenForPlayer(row);
                const rule = pickRuleText(row);
                const oddsMul =
                  row.odds === null
                    ? "—"
                    : typeof row.odds.odds_multiplier === "number"
                      ? row.odds.odds_multiplier.toFixed(4)
                      : (row.odds.odds_value / 10000).toFixed(4);

                return (
                  <TableRow
                    key={row.play_code}
                    className={cn(!open && "opacity-60")}
                  >
                    <TableCell>
                      <div className="flex flex-col gap-0.5">
                        <span className="font-medium">{pickDisplayName(row)}</span>
                        <span className="font-mono text-xs text-muted-foreground">
                          {row.play_code}
                          {row.dimension != null ? ` · ${row.dimension}D` : ""}
                        </span>
                      </div>
                    </TableCell>
                    <TableCell className="text-center">
                      {open ? (
                        <Badge variant="default" className="font-normal">
                          开放
                        </Badge>
                      ) : (
                        <Badge variant="secondary" className="font-normal">
                          关闭
                        </Badge>
                      )}
                    </TableCell>
                    <TableCell className="font-mono text-sm tabular-nums">
                      {row.config ? (
                        <>
                          {formatMoneyAmount(row.config.min_bet_amount)}
                          {" — "}
                          {formatMoneyAmount(row.config.max_bet_amount)}
                        </>
                      ) : (
                        "—"
                      )}
                    </TableCell>
                    <TableCell className="font-mono text-sm tabular-nums">
                      {row.odds ? oddsMul : "—"}
                    </TableCell>
                    <TableCell className="text-muted-foreground text-sm leading-snug">
                      {rule ?? "—"}
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </div>

        {data.risk_cap_items.length > 0 ? (
          <div className="space-y-2">
            <h3 className="text-sm font-medium text-foreground">风控封顶（示例号码）</h3>
            <div className="overflow-x-auto rounded-md border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>号码</TableHead>
                    <TableHead>封顶额</TableHead>
                    <TableHead>类型</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {data.risk_cap_items.map((r, i) => (
                    <TableRow key={`${r.normalized_number}-${i}`}>
                      <TableCell className="font-mono">{r.normalized_number}</TableCell>
                      <TableCell className="font-mono tabular-nums text-sm">
                        {formatMoneyAmount(r.cap_amount)}
                      </TableCell>
                      <TableCell className="text-sm text-muted-foreground">
                        {r.cap_type}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </div>
        ) : null}
      </div>
    );
  })();

  return (
    <Card>
      <CardHeader className="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
        <div className="space-y-1">
          <CardTitle className="text-base">玩法与赔率</CardTitle>
          <CardDescription>
            数据来自 <code className="text-xs">GET /api/v1/play/effective</code>
            ；后台修改并发布后，最长约 {DEFAULT_POLL_MS / 1000}s 内自动刷新（亦可手动刷新）。
          </CardDescription>
        </div>
        <Button
          type="button"
          variant="outline"
          size="sm"
          className="shrink-0"
          onClick={() => void load()}
        >
          刷新配置
        </Button>
      </CardHeader>
      <CardContent>{body}</CardContent>
    </Card>
  );
}
