import { useCallback, useEffect, useMemo, useState } from "react";
import { drawStatusOptions } from "@/features/lucky-gift/constants.js";
import { AdminFilterResetButton, AdminFilterSelect, AdminListToolbar, AdminSearchBox } from "@/shared/ui/AdminListLayout.jsx";
import { DataTable } from "@/shared/ui/DataTable.jsx";
import { TimeText } from "@/shared/ui/TimeText.jsx";
import { fetchLuckyGiftDraws } from "../api.js";
import { formatMultiplierFromPPM, formatNumber } from "../format.js";
import { OpsStatusBadge } from "./OpsStatusBadge.jsx";

const PAGE_SIZE = 20;

const initialFilters = { poolId: "", status: "", userId: "" };

export function DrawsView({ apps, defaultAppCode, poolIDsByApp }) {
  // 抽奖流水量大且服务端分页，必须选定应用后按需拉取，不能像配置那样一次拉全。
  const [appCode, setAppCode] = useState(defaultAppCode);
  const [filters, setFilters] = useState(initialFilters);
  const [page, setPage] = useState(1);
  const [state, setState] = useState({ error: "", items: [], loading: false, total: 0 });

  useEffect(() => {
    // 首屏 dashboard 加载完成前 defaultAppCode 为空，就绪后自动选中第一个应用。
    setAppCode((current) => current || defaultAppCode);
  }, [defaultAppCode]);

  useEffect(() => {
    if (!appCode) {
      return undefined;
    }
    let cancelled = false;
    setState((current) => ({ ...current, error: "", loading: true }));
    fetchLuckyGiftDraws({ appCode, page, pageSize: PAGE_SIZE, poolId: filters.poolId, status: filters.status, userId: filters.userId })
      .then((result) => {
        if (cancelled) {
          return;
        }
        setState((current) => ({
          error: "",
          // 滚动加载：翻页时向已加载列表追加；筛选变化会把 page 重置为 1，从头替换。
          items: page > 1 ? [...current.items, ...result.items] : result.items,
          loading: false,
          total: result.total
        }));
      })
      .catch((error) => {
        if (cancelled) {
          return;
        }
        setState((current) => ({ ...current, error: error.message || "获取抽奖记录失败", loading: false }));
      });
    return () => {
      cancelled = true;
    };
  }, [appCode, filters, page]);

  const changeAppCode = useCallback((nextAppCode) => {
    setAppCode(nextAppCode);
    // 奖池归属于应用，切换应用后旧奖池筛选一定失效，一并重置。
    setFilters(initialFilters);
    setPage(1);
  }, []);

  const changeFilter = useCallback((key, value) => {
    setFilters((current) => ({ ...current, [key]: value }));
    setPage(1);
  }, []);

  const resetFilters = useCallback(() => {
    setFilters(initialFilters);
    setPage(1);
  }, []);

  const appOptions = useMemo(() => apps.map((item) => [item.app_code ?? item.appCode, item.app_code ?? item.appCode]), [apps]);
  const poolOptions = useMemo(() => (poolIDsByApp.get(appCode) || []).map((poolID) => [poolID, poolID]), [appCode, poolIDsByApp]);
  const hasActiveFilters = Boolean(filters.poolId || filters.status || filters.userId);

  return (
    <div className="ops-view">
      <AdminListToolbar
        filters={
          <>
            <AdminFilterSelect label="应用" options={appOptions} value={appCode || ""} onChange={changeAppCode} />
            <AdminFilterSelect
              label="奖池"
              options={[["", "全部奖池"], ...poolOptions]}
              value={filters.poolId}
              onChange={(value) => changeFilter("poolId", value)}
            />
            <AdminFilterSelect
              label="发放状态"
              options={[["", "全部状态"], ...drawStatusOptions]}
              value={filters.status}
              onChange={(value) => changeFilter("status", value)}
            />
            <AdminSearchBox
              label="用户"
              placeholder="用户 ID / 外部用户 ID"
              value={filters.userId}
              onChange={(value) => changeFilter("userId", value)}
            />
            <AdminFilterResetButton disabled={!hasActiveFilters} onClick={resetFilters} />
          </>
        }
      />
      {state.error ? <div className="ops-alert" role="alert">{state.error}</div> : null}
      <DataTable
        columns={drawColumns}
        emptyLabel={state.loading ? "加载中..." : "暂无抽奖记录"}
        items={state.items}
        minWidth="1080px"
        pagination={{ onPageChange: setPage, page, total: state.total }}
        rowKey={(item) => item.draw_id ?? item.drawId}
        title="抽奖记录"
        total={state.total}
      />
    </div>
  );
}

const drawColumns = [
  {
    key: "created_at_ms",
    label: "抽奖时间",
    render: (item) => <TimeText value={item.created_at_ms ?? item.createdAtMs} />,
    width: "minmax(150px, 1fr)"
  },
  { key: "app_code", label: "应用", render: (item) => item.app_code ?? item.appCode, width: "minmax(80px, 0.6fr)" },
  {
    key: "user",
    label: "用户",
    // 外部接入应用只有 external_user_id，内部应用只有数字 user_id，两者互斥，取有值的一侧。
    render: (item) => item.external_user_id || item.externalUserId || item.user_id || item.userId || "-",
    width: "minmax(120px, 1fr)"
  },
  { key: "pool_id", label: "奖池", render: (item) => item.pool_id ?? item.poolId, width: "minmax(100px, 0.8fr)" },
  { key: "gift_id", label: "礼物", render: (item) => item.gift_id ?? item.giftId, width: "minmax(100px, 0.8fr)" },
  {
    key: "multiplier_ppm",
    label: "命中倍率",
    render: (item) => formatMultiplierFromPPM(item.multiplier_ppm ?? item.multiplierPpm),
    width: "minmax(88px, 0.6fr)"
  },
  { key: "effective_reward_coins", label: "中奖金币", render: (item) => formatNumber(item.effective_reward_coins ?? item.effectiveRewardCoins) },
  {
    key: "reward_status",
    label: "发放状态",
    render: (item) => renderRewardStatus(item.reward_status ?? item.rewardStatus),
    width: "minmax(124px, 0.8fr)"
  },
  {
    key: "rule_version",
    label: "规则版本",
    render: (item) => `v${item.rule_version ?? item.ruleVersion ?? "-"}`,
    width: "minmax(80px, 0.5fr)"
  }
];

function renderRewardStatus(status) {
  if (status === "granted") {
    return <OpsStatusBadge label="已发放" tone="succeeded" />;
  }
  if (status === "failed") {
    return <OpsStatusBadge label="发放失败" tone="danger" />;
  }
  if (status === "pending") {
    return <OpsStatusBadge label="发放中" tone="warning" />;
  }
  return <OpsStatusBadge label={status || "-"} />;
}
