import { useMemo, useState } from "react";
import { formatCoin, formatMoney, formatMoneyFull, formatNumber, formatPercent } from "../utils/format.js";
import { Panel } from "./Panel.jsx";

const textCollator = new Intl.Collator("zh-Hans", { numeric: true, sensitivity: "base" });

const tabs = [
  { key: "country", label: "国家表现" },
  { key: "gift", label: "礼物排行" },
  { key: "game", label: "游戏排行" }
];

const defaultSortByTab = {
  country: { direction: "desc", key: "recharge_usd_minor", type: "number" },
  gift: { direction: "desc", key: "value", type: "number" },
  game: { direction: "desc", key: "turnover_coin", type: "number" }
};

const countryColumns = [
  { key: "country", label: "国家", type: "text", align: "left" },
  { key: "registrations", label: "注册" },
  { key: "active_users", label: "活跃用户" },
  { key: "paid_users", label: "付费用户" },
  { key: "recharge_users", label: "充值用户" },
  { key: "recharge_usd_minor", label: "总充值 (USD)" },
  { key: "new_user_recharge_usd_minor", label: "新用户充值 (USD)" },
  { key: "arpu_usd_minor", label: "ARPU (USD)" },
  { key: "arppu_usd_minor", label: "ARPPU (USD)" },
  { key: "payer_rate", label: "付费转化率" },
  { key: "recharge_conversion_rate", label: "充值转化率" },
  { key: "avg_recharge_usd_minor", label: "平均充值 (USD)" },
  { key: "trend_rate", label: "近 7 日" }
];

const countrySortAccessors = {
  active_users: (item) => item.active_users,
  arppu_usd_minor: (item) => item.arppu_usd_minor,
  arpu_usd_minor: (item) => item.arpu_usd_minor,
  avg_recharge_usd_minor: (item) => item.avg_recharge_usd_minor,
  country: (item) => item.country,
  new_user_recharge_usd_minor: (item) => item.new_user_recharge_usd_minor,
  paid_users: (item) => item.paid_users,
  payer_rate: (item) => item.payer_rate,
  recharge_conversion_rate: (item) => item.recharge_conversion_rate,
  recharge_users: (item) => item.recharge_users,
  recharge_usd_minor: (item) => item.recharge_usd_minor,
  registrations: (item) => item.registrations,
  trend_rate: (item) => item.trend_rate
};

const giftColumns = [
  { key: "name", label: "礼物", type: "text", align: "left" },
  { key: "value", label: "金币消费" },
  { key: "share", label: "占比" },
  { key: "trend_rate", label: "近 7 日" }
];

const gameColumns = [
  { key: "game_id", label: "游戏", type: "text", align: "left" },
  { key: "turnover_coin", label: "流水 (金币)" },
  { key: "profit_rate", label: "利润率" },
  { key: "share", label: "占比" }
];

export function CountryPerformanceTable({ gameRanking, giftRanking, items, loading = false }) {
  const [activeTab, setActiveTab] = useState("country");
  const [sortByTab, setSortByTab] = useState(defaultSortByTab);

  const handleSort = (tabKey, columnKey, type = "number") => {
    setSortByTab((previous) => {
      const current = previous[tabKey];
      const nextDirection = current?.key === columnKey && current.direction === "desc" ? "asc" : "desc";

      return {
        ...previous,
        [tabKey]: {
          direction: type === "text" && current?.key !== columnKey ? "asc" : nextDirection,
          key: columnKey,
          type
        }
      };
    });
  };

  return (
    <Panel className="panel--table" title={<TableTabs activeTab={activeTab} onChange={setActiveTab} />}>
      <div className="country-table-wrap">
        {activeTab === "country" ? (
          <CountryTable
            items={items}
            loading={loading}
            onSort={(columnKey, type) => handleSort("country", columnKey, type)}
            sortState={sortByTab.country}
          />
        ) : null}
        {activeTab === "gift" ? (
          <GiftTable
            items={giftRanking}
            loading={loading}
            onSort={(columnKey, type) => handleSort("gift", columnKey, type)}
            sortState={sortByTab.gift}
          />
        ) : null}
        {activeTab === "game" ? (
          <GameTable
            items={gameRanking}
            loading={loading}
            onSort={(columnKey, type) => handleSort("game", columnKey, type)}
            sortState={sortByTab.game}
          />
        ) : null}
      </div>
    </Panel>
  );
}

function TableTabs({ activeTab, onChange }) {
  return (
    <div className="table-tabs">
      {tabs.map((tab) => (
        <button className={activeTab === tab.key ? "is-active" : ""} key={tab.key} type="button" onClick={() => onChange(tab.key)}>
          {tab.label}
        </button>
      ))}
    </div>
  );
}

function CountryTable({ items, loading, onSort, sortState }) {
  const sortedItems = useMemo(() => sortItems(items, sortState, countrySortAccessors), [items, sortState]);

  return (
    <table className="country-table country-table--wide">
      <thead>
        <tr>
          <th>#</th>
          {countryColumns.map((column) => (
            <SortableHeader column={column} key={column.key} onSort={onSort} sortState={sortState} />
          ))}
        </tr>
      </thead>
      <tbody>
        {loading ? <SkeletonRows colSpan={14} rows={6} /> : null}
        {!loading && !items.length ? <EmptyRow colSpan={14} /> : null}
        {!loading && sortedItems.map((item, index) => (
          <tr key={item.country}>
            <td>{index + 1}</td>
            <td>{item.flag ? <i className="table-flag">{item.flag}</i> : null}{item.country}</td>
            <td>{formatNumber(item.registrations)}</td>
            <td>{formatNumber(item.active_users)}</td>
            <td>{formatNumber(item.paid_users)}</td>
            <td>{formatNumber(item.recharge_users)}</td>
            <td>{formatMoneyFull(item.recharge_usd_minor)}</td>
            <td>{formatMoneyFull(item.new_user_recharge_usd_minor)}</td>
            <td>{formatMoney(item.arpu_usd_minor)}</td>
            <td>{formatMoney(item.arppu_usd_minor)}</td>
            <td>{formatPercent(item.payer_rate)}</td>
            <td>{formatPercent(item.recharge_conversion_rate)}</td>
            <td>{formatMoney(item.avg_recharge_usd_minor)}</td>
            <td className="positive">+{formatPercent(item.trend_rate)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function GiftTable({ items, loading, onSort, sortState }) {
  const total = items.reduce((sum, item) => sum + item.value, 0) || 1;
  const giftSortAccessors = useMemo(() => ({
    name: (item) => item.name,
    share: (item) => item.value / total,
    trend_rate: (item) => item.trend_rate,
    value: (item) => item.value
  }), [total]);
  const sortedItems = useMemo(() => sortItems(items, sortState, giftSortAccessors), [giftSortAccessors, items, sortState]);

  return (
    <table className="country-table">
      <thead>
        <tr>
          <th>#</th>
          {giftColumns.map((column) => (
            <SortableHeader column={column} key={column.key} onSort={onSort} sortState={sortState} />
          ))}
        </tr>
      </thead>
      <tbody>
        {loading ? <SkeletonRows colSpan={5} rows={5} /> : null}
        {!loading && !items.length ? <EmptyRow colSpan={5} /> : null}
        {!loading && sortedItems.map((item, index) => (
          <tr key={item.name}>
            <td>{index + 1}</td>
            <td>{item.name}</td>
            <td>{formatCoin(item.value)}</td>
            <td>{formatPercent(item.value / total)}</td>
            <td className={item.trend_rate >= 0 ? "positive" : "negative"}>{formatSignedPercent(item.trend_rate)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function GameTable({ items, loading, onSort, sortState }) {
  const total = items.reduce((sum, item) => sum + item.turnover_coin, 0) || 1;
  const gameSortAccessors = useMemo(() => ({
    game_id: (item) => item.game_label || item.game_id,
    profit_rate: (item) => item.profit_rate,
    share: (item) => item.turnover_coin / total,
    turnover_coin: (item) => item.turnover_coin
  }), [total]);
  const sortedItems = useMemo(() => sortItems(items, sortState, gameSortAccessors), [gameSortAccessors, items, sortState]);

  return (
    <table className="country-table">
      <thead>
        <tr>
          <th>#</th>
          {gameColumns.map((column) => (
            <SortableHeader column={column} key={column.key} onSort={onSort} sortState={sortState} />
          ))}
        </tr>
      </thead>
      <tbody>
        {loading ? <SkeletonRows colSpan={5} rows={5} /> : null}
        {!loading && !items.length ? <EmptyRow colSpan={5} /> : null}
        {!loading && sortedItems.map((item, index) => (
          <tr key={`${item.platform_code || "game"}-${item.game_id}`}>
            <td>{index + 1}</td>
            <td>{item.game_label || item.game_id}</td>
            <td>{formatCoin(item.turnover_coin)}</td>
            <td className="positive">{formatPercent(item.profit_rate)}</td>
            <td>{formatPercent(item.turnover_coin / total)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function SortableHeader({ column, onSort, sortState }) {
  const isActive = sortState?.key === column.key;
  const direction = isActive ? sortState.direction : "none";
  const ariaSort = isActive ? (sortState.direction === "asc" ? "ascending" : "descending") : "none";

  return (
    <th aria-sort={ariaSort} className="is-sortable" scope="col">
      <button
        className={`sort-header-button ${column.align === "left" ? "sort-header-button--left" : ""} ${isActive ? "is-active" : ""}`}
        type="button"
        onClick={() => onSort(column.key, column.type || "number")}
      >
        <span>{column.label}</span>
        <span aria-hidden="true" className="sort-indicator">{direction === "asc" ? "↑" : direction === "desc" ? "↓" : "↕"}</span>
      </button>
    </th>
  );
}

function SkeletonRows({ colSpan, rows }) {
  return Array.from({ length: rows }).map((_, index) => (
    <tr className="table-skeleton-row" key={index}>
      <td colSpan={colSpan}><span className="skeleton-block skeleton-table-line" /></td>
    </tr>
  ));
}

function EmptyRow({ colSpan }) {
  return (
    <tr className="table-empty-row">
      <td colSpan={colSpan}>暂无数据</td>
    </tr>
  );
}

function formatSignedPercent(value) {
  if (value === undefined || value === null || Number.isNaN(Number(value))) {
    return "";
  }
  return `${Number(value) >= 0 ? "+" : ""}${formatPercent(value)}`;
}

function sortItems(items, sortState, accessors) {
  if (!sortState?.key || !accessors[sortState.key]) {
    return items;
  }

  const directionMultiplier = sortState.direction === "asc" ? 1 : -1;

  return items
    .map((item, index) => ({ index, item }))
    .sort((left, right) => {
      const leftValue = accessors[sortState.key](left.item);
      const rightValue = accessors[sortState.key](right.item);
      const result = compareValues(leftValue, rightValue, sortState.type);

      return result === 0 ? left.index - right.index : result * directionMultiplier;
    })
    .map(({ item }) => item);
}

function compareValues(leftValue, rightValue, type) {
  if (type === "text") {
    return textCollator.compare(String(leftValue || ""), String(rightValue || ""));
  }

  const leftNumber = Number(leftValue);
  const rightNumber = Number(rightValue);

  if (!Number.isFinite(leftNumber) && !Number.isFinite(rightNumber)) {
    return 0;
  }
  if (!Number.isFinite(leftNumber)) {
    return -1;
  }
  if (!Number.isFinite(rightNumber)) {
    return 1;
  }

  return leftNumber - rightNumber;
}
