import { MetricCard } from "./MetricCard.jsx";
import { Panel } from "./Panel.jsx";
import { formatCoin, formatNumber, formatPercent } from "../utils/format.js";
import { numberValue } from "../utils/number.js";

const gameOptions = [
  { label: "全部", value: "all" },
  { label: "Dice", value: "dice" },
  { label: "Rock", value: "rock" }
];

const eventLabels = {
  page_open: "页面打开",
  config_load_success: "配置成功",
  config_load_failed: "配置失败",
  gesture_select: "选择手势",
  match_api: "匹配接口",
  match_cancel: "取消匹配",
  stake_selected: "选择档位",
  stake_select: "选择档位",
  match_click: "点击匹配",
  match_success: "匹配成功",
  animation_start: "进入开奖",
  preload_complete: "预加载完成",
  reveal_enter: "进入开奖",
  roll_api: "开奖接口",
  settlement_show: "结算展示",
  play_again: "再来一局",
  play_again_click: "再来一局",
  exit_click: "退出"
};

export function SelfGameScreen({ gameId = "all", loading = false, onGameChange, overview }) {
  const model = buildSelfGameModel(overview);
  const showSkeleton = loading && !overview;

  return (
    <section className="self-game-screen" aria-label="自研游戏统计">
      <div className="self-game-toolbar">
        <div className="self-game-title">
          <strong>自研游戏</strong>
          <span>Dice / Rock H5 聚合统计</span>
        </div>
        <div className="game-switch" role="tablist" aria-label="游戏筛选">
          {gameOptions.map((item) => (
            <button className={gameId === item.value ? "is-active" : ""} key={item.value} onClick={() => onGameChange?.(item.value)} type="button">
              {item.label}
            </button>
          ))}
        </div>
      </div>

      <section className="self-game-kpi-grid" aria-label="自研游戏核心指标">
        {model.kpis.map((item) => (
          <MetricCard key={item.label} item={item} loading={showSkeleton} />
        ))}
      </section>

      <section className="self-game-panel-grid self-game-panel-grid--top">
        <FunnelTable funnel={model.funnel} loading={showSkeleton} />
        <StakeTable items={model.stakes} loading={showSkeleton} />
        <PoolTable items={model.pools} loading={showSkeleton} />
      </section>

      <section className="self-game-panel-grid">
        <ParticipantTable items={model.participants} loading={showSkeleton} />
        <WinLossTable summary={model.winLoss} loading={showSkeleton} />
        <RiskTable items={model.risks} loading={showSkeleton} />
      </section>

      <section className="self-game-panel-grid self-game-panel-grid--single">
        <MetricDefinitionList items={model.definitions} loading={showSkeleton} />
      </section>
    </section>
  );
}

function buildSelfGameModel(overview) {
  const events = eventIndex(overview?.events);
  const totals = overview?.match_totals || {};
  const retention = overview?.retention || {};
  const totalStake = numberValue(totals.user_stake_coin) + numberValue(totals.robot_stake_coin);
  const participants = Array.isArray(overview?.participant_distribution) ? overview.participant_distribution : [];
  const pools = Array.isArray(overview?.pool_stats) ? overview.pool_stats : [];
  const userResult = realUserResultCounts(participants, totals);
  const userNetWin = numberValue(totals.payout_coin) + numberValue(totals.refund_coin) - numberValue(totals.user_stake_coin);
  const poolBalance = latestPoolBalance(pools);
  const settlementEvent = events.get("settlement_show");
  const matchClickEvent = events.get("match_click");
  const matchSuccessEvent = events.get("match_success");
  const pageOpenEvent = events.get("page_open");
  const winLoss = {
    countNote: userResult.countNote,
    drawCount: userResult.draw,
    loserCount: userResult.lose,
    payoutCoin: numberValue(totals.payout_coin),
    refundCoin: numberValue(totals.refund_coin),
    userNetWin,
    userStakeCoin: numberValue(totals.user_stake_coin),
    winnerCount: userResult.win
  };

  return {
    kpis: [
      metric("游戏 PV / UV", `${formatNumber(pageOpenEvent.event_count)} / ${formatNumber(pageOpenEvent.user_count)}`, "进入 dice、rock H5 的次数和人数"),
      metric("开局人数", `点击 ${formatNumber(matchClickEvent.user_count)} / 成功 ${formatNumber(matchSuccessEvent.user_count)}`, `${formatNumber(matchClickEvent.event_count)} 次点击`),
      metric("创建局", formatNumber(totals.created_matches), "服务端创建的对局数"),
      metric("匹配成功局", formatNumber(totals.matched_matches), `${formatPercent(overview?.conversion?.match_click_to_success_rate)} 点击后成功`),
      metric("结算完成 UV", formatNumber(settlementEvent.user_count), `${formatPercent(overview?.conversion?.page_to_settlement_rate)} 页面到结算`),
      metric("已结算局", formatNumber(totals.settled_matches), "已经完成派奖或退款的局"),
      metric("取消 / 失败局", `${formatNumber(totals.canceled_matches)} / ${formatNumber(totals.failed_matches)}`, `${formatPercent(totals.cancel_rate)} / ${formatPercent(totals.fail_rate)}`),
      metric("参与人次", formatNumber(numberValue(totals.human_participants) + numberValue(totals.robot_participants)), `真人 ${formatNumber(totals.human_participants)} / 机器人 ${formatNumber(totals.robot_participants)}`),
      metric("总下注金币", formatCoin(totalStake), `真人 ${formatCoin(totals.user_stake_coin)} / 机器人 ${formatCoin(totals.robot_stake_coin)}`),
      metric("派奖金额", formatCoin(totals.payout_coin), `退款 ${formatCoin(totals.refund_coin)}`),
      metric("平台抽水", formatCoin(totals.platform_profit_coin), formatPercent(totals.platform_profit_rate)),
      metric("奖池变化", formatCoin(totals.pool_delta_coin), `余额 ${formatCoin(poolBalance)} / 强制 ${formatNumber(totals.forced_player_lose_matches)} 次`),
      metric("用户输赢", `${formatNumber(winLoss.winnerCount)} / ${formatNumber(winLoss.loserCount)} / ${formatNumber(winLoss.drawCount)}`, `真实用户净输赢 ${formatCoin(winLoss.userNetWin)}`),
      metric("次日 / 7日留存", `${formatPercent(retention.day1_rate)} / ${formatPercent(retention.day7_rate)}`, `样本 ${formatNumber(retention.cohort_users)} 人`)
    ],
    definitions: overview?.metric_definitions || [],
    funnel: overview?.funnel || [],
    participants,
    pools,
    risks: overview?.user_risk || [],
    stakes: overview?.stake_breakdown || [],
    winLoss
  };
}

function eventIndex(items) {
  const index = new Map();
  (Array.isArray(items) ? items : []).forEach((item) => {
    const name = item.event_name || "";
    const current = index.get(name) || emptyEvent();
    index.set(name, {
      event_count: numberValue(current.event_count) + numberValue(item.event_count),
      user_count: numberValue(current.user_count) + numberValue(item.user_count)
    });
  });
  return {
    get(name) {
      return index.get(name) || emptyEvent();
    }
  };
}

function emptyEvent() {
  return { event_count: 0, user_count: 0 };
}

function metric(label, value, caption) {
  return { caption, label, value };
}

function FunnelTable({ funnel, loading }) {
  return (
    <Panel className="panel--self-game" title="转化漏斗">
      <DataTable
        emptyText="暂无漏斗数据"
        loading={loading}
        rows={funnel}
        columns={[
          { key: "event_name", label: "节点", render: (row) => eventLabels[row.event_name] || row.event_name || "--" },
          { key: "user_count", label: "UV", render: (row) => formatNumber(row.user_count) },
          { key: "event_count", label: "次数", render: (row) => formatNumber(row.event_count) }
        ]}
      />
    </Panel>
  );
}

function StakeTable({ items, loading }) {
  return (
    <Panel className="panel--self-game" title="下注档位">
      <DataTable
        emptyText="暂无档位数据"
        loading={loading}
        rows={items}
        wide
        columns={[
          { key: "stake_coin", label: "档位", render: (row) => formatCoin(row.stake_coin) },
          { key: "created_matches", label: "创建局", render: (row) => formatNumber(row.created_matches) },
          { key: "matched_matches", label: "匹配局", render: (row) => formatNumber(row.matched_matches) },
          { key: "settled_matches", label: "结算局", render: (row) => formatNumber(row.settled_matches) },
          { key: "user_stake_coin", label: "真人下注", render: (row) => formatCoin(row.user_stake_coin) },
          { key: "robot_stake_coin", label: "机器人下注", render: (row) => formatCoin(row.robot_stake_coin) },
          { key: "stake", label: "总下注", render: (row) => formatCoin(numberValue(row.user_stake_coin) + numberValue(row.robot_stake_coin)) },
          { key: "payout_coin", label: "派奖", render: (row) => formatCoin(row.payout_coin) },
          { key: "profit", label: "盈利", render: (row) => formatCoin(row.platform_profit_coin) }
        ]}
      />
    </Panel>
  );
}

function PoolTable({ items, loading }) {
  return (
    <Panel className="panel--self-game" title="奖池流水">
      <DataTable
        emptyText="暂无奖池流水"
        loading={loading}
        rows={items}
        columns={[
          { key: "direction", label: "方向", render: (row) => directionLabel(row.direction) },
          { key: "reason", label: "原因", render: (row) => row.reason || "--" },
          { key: "flow", label: "入 / 出", render: (row) => `${formatCoin(row.in_coin)} / ${formatCoin(row.out_coin)}` },
          { key: "balance_after_coin", label: "余额", render: (row) => formatCoin(row.balance_after_coin) }
        ]}
      />
    </Panel>
  );
}

function ParticipantTable({ items, loading }) {
  return (
    <Panel className="panel--self-game" title="玩法分布">
      <DataTable
        emptyText="暂无玩法数据"
        loading={loading}
        rows={items}
        wide
        columns={[
          { key: "stake_coin", label: "档位", render: (row) => formatCoin(row.stake_coin) },
          { key: "type", label: "对象", render: (row) => participantLabel(row.participant_type) },
          { key: "play", label: "手势 / 点数", render: (row) => playLabel(row) },
          { key: "result", label: "结果", render: (row) => resultLabel(row.result) },
          { key: "count", label: "人次", render: (row) => formatNumber(row.participant_count) },
          { key: "net_win_coin", label: "净输赢", render: (row) => formatCoin(row.net_win_coin) },
          { key: "win_rate", label: "胜率", render: (row) => formatPercent(row.win_rate) }
        ]}
      />
    </Panel>
  );
}

function WinLossTable({ loading, summary }) {
  const rows = [
    { metric: "真实用户赢家数", value: summary.winnerCount, note: summary.countNote },
    { metric: "真实用户输家数", value: summary.loserCount, note: summary.countNote },
    { metric: "真实用户平局数", value: summary.drawCount, note: summary.countNote },
    { metric: "真实用户下注", value: summary.userStakeCoin, note: "match_totals.user_stake_coin", type: "coin" },
    { metric: "真实用户派奖", value: summary.payoutCoin, note: "match_totals.payout_coin", type: "coin" },
    { metric: "真实用户退款", value: summary.refundCoin, note: "match_totals.refund_coin", type: "coin" },
    { metric: "真实用户净输赢", value: summary.userNetWin, note: "派奖 + 退款 - 真实用户下注", type: "coin" }
  ];
  return (
    <Panel className="panel--self-game" title="用户输赢">
      <DataTable
        emptyText="暂无输赢数据"
        loading={loading}
        rows={rows}
        columns={[
          { key: "metric", label: "指标", render: (row) => row.metric },
          { key: "value", label: "数值", render: (row) => (row.type === "coin" ? formatCoin(row.value) : formatNumber(row.value)) },
          { key: "note", label: "口径", render: (row) => row.note }
        ]}
      />
    </Panel>
  );
}

function RiskTable({ items, loading }) {
  return (
    <Panel className="panel--self-game" title="高风险用户">
      <DataTable
        emptyText="暂无风险用户"
        loading={loading}
        rows={items}
        columns={[
          { key: "user_id", label: "用户", render: (row) => <RiskUserCell row={row} /> },
          { key: "match_count", label: "局数", render: (row) => formatNumber(row.match_count) },
          { key: "win_rate", label: "胜率", render: (row) => formatPercent(row.win_rate) },
          { key: "net_win_coin", label: "净赢", render: (row) => formatCoin(row.net_win_coin) },
          { key: "cancel_rate", label: "取消率", render: (row) => formatPercent(row.cancel_rate) }
        ]}
      />
    </Panel>
  );
}

function RiskUserCell({ row }) {
  const nickname = row.nickname || row.username || "";
  const shortID = row.short_id || row.display_user_id || "";
  const userID = row.user_id ? String(row.user_id) : "";
  const avatar = row.avatar || "";
  const primary = nickname || shortID || userID || "--";
  const secondary = shortID ? `ID ${shortID}` : userID ? `UID ${userID}` : "";
  return (
    <div className="risk-user-cell">
      {avatar ? <img alt="" className="risk-user-avatar" src={avatar} /> : <span className="risk-user-avatar risk-user-avatar--empty">{primary.slice(0, 1).toUpperCase()}</span>}
      <span className="risk-user-copy">
        <strong>{primary}</strong>
        {secondary ? <small>{secondary}</small> : null}
      </span>
    </div>
  );
}

function MetricDefinitionList({ items, loading }) {
  return (
    <Panel className="panel--self-game" title="口径">
      {loading ? <div className="panel-empty">加载中...</div> : null}
      {!loading && !items.length ? <div className="panel-empty">暂无口径说明</div> : null}
      {!loading && items.length ? (
        <div className="definition-list">
          {items.map((item) => (
            <div className="definition-row" key={item.metric}>
              <strong>{item.metric}</strong>
              <span>{item.definition}</span>
            </div>
          ))}
        </div>
      ) : null}
    </Panel>
  );
}

function DataTable({ columns, emptyText, loading, rows, wide = false }) {
  if (loading) {
    return <div className="panel-empty">加载中...</div>;
  }
  if (!rows.length) {
    return <div className="panel-empty">{emptyText}</div>;
  }
  return (
    <div className="self-game-table-wrap">
      <table className={["self-game-table", wide ? "self-game-table--wide" : ""].filter(Boolean).join(" ")}>
        <thead>
          <tr>
            {columns.map((column) => (
              <th key={column.key}>{column.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, rowIndex) => (
            <tr key={rowKey(row, rowIndex)}>
              {columns.map((column) => (
                <td key={column.key}>{column.render(row)}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function rowKey(row, rowIndex) {
  return [row.game_id, row.user_id, row.metric, row.stake_coin, row.event_name, row.reason, row.participant_type, row.result, row.rps_gesture, row.dice_point, rowIndex]
    .filter((item) => item !== undefined && item !== null && item !== "")
    .join(":");
}

function realUserResultCounts(items, totals) {
  const result = { countNote: "按 participant_distribution 中真实用户结果统计", draw: 0, lose: 0, win: 0 };
  let userRows = 0;
  items.forEach((item) => {
    if (!isRealUserParticipant(item.participant_type)) {
      return;
    }
    userRows += 1;
    const count = numberValue(item.participant_count);
    if (item.result === "win") {
      result.win += count;
    } else if (item.result === "lose") {
      result.lose += count;
    } else if (item.result === "draw") {
      result.draw += count;
    }
  });
  if (userRows > 0) {
    return result;
  }
  return {
    countNote: "缺少真实用户分布时回退 match_totals 参与人结果",
    draw: numberValue(totals.draw_count),
    lose: numberValue(totals.loser_count),
    win: numberValue(totals.winner_count)
  };
}

function isRealUserParticipant(value) {
  return value === "user" || value === "human";
}

function latestPoolBalance(items) {
  if (!items.length) {
    return 0;
  }
  return items.reduce((balance, item) => {
    const next = numberValue(item.balance_after_coin);
    return next !== 0 ? next : balance;
  }, 0);
}

function directionLabel(value) {
  if (value === "in") {
    return "入池";
  }
  if (value === "out") {
    return "出池";
  }
  return value || "--";
}

function participantLabel(value) {
  if (value === "robot") {
    return "机器人";
  }
  if (isRealUserParticipant(value)) {
    return "真人";
  }
  return value || "--";
}

function resultLabel(value) {
  if (value === "win") {
    return "胜";
  }
  if (value === "lose") {
    return "负";
  }
  if (value === "draw") {
    return "平";
  }
  return value || "--";
}

function playLabel(row) {
  if (row.rps_gesture) {
    return row.rps_gesture;
  }
  if (numberValue(row.dice_point) > 0) {
    return `${row.dice_point} 点`;
  }
  return "--";
}
