// TeamKpiView：运营中心视图。后端已按当前登录用户的数据范围裁剪，页面只展示可见运营负责范围内的充值数据。
// 金额字段为 USD 分，缺失值显示 "--"，不在前端把缺失口径当作 0。

import { useMemo, useState } from "react";
import { SocialAppIdentity, useSocialBi } from "../SocialBiApp.jsx";
import { formatCount, formatMoneyMinor, isBlank } from "../format.js";
import { ALL } from "../state.js";
import "./team-kpi-view.css";

const DIMENSIONS = [
  { key: "person", label: "按人员×区域" },
  { key: "operatorApp", label: "按人员×App" },
  { key: "team", label: "按部门" }
];

function addNullable(sum, value) {
  if (isBlank(value)) {
    return sum;
  }
  return (sum ?? 0) + Number(value);
}

function numberOr(value, fallback) {
  return isBlank(value) ? fallback : Number(value);
}

function compareByMonthRecharge(left, right) {
  return numberOr(right.monthMinor, -1) - numberOr(left.monthMinor, -1);
}

function operatorLabelOf(item) {
  return item.operator_name || item.operator_account || `#${item.operator_user_id}`;
}

function regionLabelOf(item) {
  return item.region_name || item.region_code || "全部区域";
}

function operatorCountOf(items) {
  return new Set(items.map((item) => item.operator_user_id).filter((id) => !isBlank(id))).size;
}

export function TeamKpiView() {
  const { filters, isLoading, kpi, master } = useSocialBi();
  const [dimension, setDimension] = useState("person");

  const items = useMemo(() => kpi?.items || [], [kpi]);

  const personRows = useMemo(() => {
    const rows = items.map((item, index) => ({
      item,
      key: `${item.operator_user_id}-${item.app_code}-${item.region_id}-${index}`,
      monthMinor: item.month_recharge_usd_minor
    }));
    rows.sort(compareByMonthRecharge);
    return rows;
  }, [items]);

  const operatorAppRows = useMemo(() => {
    const rows = (kpi?.operator_app_rows || []).map((item, index) => ({
      item,
      key: `${item.operator_user_id}-${item.app_code}-${index}`,
      monthMinor: item.month_recharge_usd_minor
    }));
    rows.sort(compareByMonthRecharge);
    return rows;
  }, [kpi]);

  const teamRows = useMemo(() => {
    const groups = new Map();
    items.forEach((item) => {
      const teamName = item.team || "未分组";
      let group = groups.get(teamName);
      if (!group) {
        group = { members: new Set(), monthMinor: null, rangeMinor: null, team: teamName };
        groups.set(teamName, group);
      }
      group.members.add(item.operator_user_id);
      group.rangeMinor = addNullable(group.rangeMinor, item.range_recharge_usd_minor);
      group.monthMinor = addNullable(group.monthMinor, item.month_recharge_usd_minor);
    });
    const rows = [...groups.values()].map((group) => ({
      memberCount: group.members.size,
      monthMinor: group.monthMinor,
      rangeMinor: group.rangeMinor,
      team: group.team
    }));
    rows.sort(compareByMonthRecharge);
    return rows;
  }, [items]);

  if (isLoading && !kpi) {
    return <KpiSkeleton />;
  }

  const summary = kpi?.summary || {};
  const operatorCount = isBlank(summary.operator_count) ? operatorCountOf(items) : summary.operator_count;
  const selectedOperator = filters.operator === ALL
    ? null
    : (master?.operators || []).find((operator) => String(operator.user_id) === String(filters.operator));

  return (
    <div className="sbi-kpi-view">
      <section className="sbi-card sbi-kpi-board">
        <div className="sbi-card-header">
          <strong>充值排行</strong>
          <small>
            {kpi?.period_month || "--"} · {formatCount(operatorCount)} 名运营
          </small>
          <div className="sbi-card-toolbar">
            <div aria-label="排行维度" className="sbi-seg" role="radiogroup">
              {DIMENSIONS.map((option) => (
                <button
                  aria-checked={dimension === option.key}
                  className={dimension === option.key ? "is-active" : ""}
                  key={option.key}
                  onClick={() => setDimension(option.key)}
                  role="radio"
                  type="button"
                >
                  {option.label}
                </button>
              ))}
            </div>
          </div>
        </div>
        <KpiSummary operator={selectedOperator} operatorCount={operatorCount} summary={summary} />
        <div className="sbi-table-scroll sbi-kpi-board-scroll">
          {dimension === "person" ? (
            <PersonTable rows={personRows} />
          ) : dimension === "operatorApp" ? (
            <OperatorAppTable rows={operatorAppRows} />
          ) : (
            <TeamTable rows={teamRows} />
          )}
        </div>
      </section>
    </div>
  );
}

function KpiSummary({ operator, operatorCount, summary }) {
  const details = operator
    ? [operator.account, operator.team].filter(Boolean).join(" · ")
    : `${formatCount(operatorCount)} 名运营`;
  return (
    <div aria-label="充值金额汇总" className="sbi-kpi-summary">
      <div className="sbi-kpi-summary-person">
        <span>{operator ? "当前人员" : "当前范围"}</span>
        <strong>{operator ? operatorIdentity(operator) : "全部运营人员"}</strong>
        <small>{details}</small>
      </div>
      <SummaryAmount label="区间总金额" value={summary.range_recharge_usd_minor} />
      <SummaryAmount label="当月总金额" value={summary.month_recharge_usd_minor} />
    </div>
  );
}

function operatorIdentity(operator) {
  return operator?.name || operator?.account || `#${operator?.user_id}`;
}

function SummaryAmount({ label, value }) {
  return (
    <div className="sbi-kpi-summary-amount">
      <span>{label}</span>
      <strong>{formatMoneyMinor(value)}</strong>
    </div>
  );
}

function KpiSkeleton() {
  return (
    <div aria-busy="true" className="sbi-kpi-view">
      <section className="sbi-card">
        <div className="sbi-kpi-table-skeleton">
          {[0, 1, 2, 3, 4, 5].map((index) => (
            <span className="sbi-skeleton" key={index} style={{ height: 18, width: "100%" }} />
          ))}
        </div>
      </section>
    </div>
  );
}

function RankBadge({ rank }) {
  const medal = rank === 1 ? " is-gold" : rank === 2 ? " is-silver" : rank === 3 ? " is-bronze" : "";
  return <span className={`sbi-kpi-rank${medal}`}>{rank}</span>;
}

function OperatorAppTable({ rows }) {
  return (
    <table className="sbi-table">
      <thead>
        <tr>
          <th className="is-left">名次</th>
          <th className="is-left">运营人员</th>
          <th className="is-left">App</th>
          <th className="is-left">负责区域</th>
          <th>
            <span className="sbi-metric-hint" title="所选区间内该运营在此 App 负责范围的充值合计（USD）">
              区间充值
            </span>
          </th>
          <th>
            <span className="sbi-metric-hint" title="本自然月至今该运营在此 App 负责范围的充值合计（USD）">
              当月充值
            </span>
          </th>
        </tr>
      </thead>
      <tbody>
        {!rows.length ? <EmptyTableRow colSpan={6} /> : null}
        {rows.map((row, index) => {
          const item = row.item;
          return (
            <tr key={row.key}>
              <td className="is-left">
                <RankBadge rank={index + 1} />
              </td>
              <td className="is-left">
                <OperatorCell item={item} />
              </td>
              <td className="is-left">
                <AppCell item={item} />
              </td>
              <td className="is-left">{item.whole_app_scope ? "全部区域" : item.region_names || `${formatCount(item.region_count)} 个区域`}</td>
              <td>{formatMoneyMinor(item.range_recharge_usd_minor)}</td>
              <td>{formatMoneyMinor(item.month_recharge_usd_minor)}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

function PersonTable({ rows }) {
  return (
    <table className="sbi-table">
      <thead>
        <tr>
          <th className="is-left">名次</th>
          <th className="is-left">运营人员</th>
          <th className="is-left">App</th>
          <th className="is-left">区域</th>
          <th>
            <span className="sbi-metric-hint" title="所选区间内负责范围的充值合计（USD）">
              区间充值
            </span>
          </th>
          <th>
            <span className="sbi-metric-hint" title="本自然月至今负责范围的充值合计（USD）">
              当月充值
            </span>
          </th>
        </tr>
      </thead>
      <tbody>
        {!rows.length ? <EmptyTableRow colSpan={6} /> : null}
        {rows.map((row, index) => {
          const item = row.item;
          return (
            <tr key={row.key}>
              <td className="is-left">
                <RankBadge rank={index + 1} />
              </td>
              <td className="is-left">
                <OperatorCell item={item} />
              </td>
              <td className="is-left">
                <AppCell item={item} />
              </td>
              <td className="is-left">{regionLabelOf(item)}</td>
              <td>{formatMoneyMinor(item.range_recharge_usd_minor)}</td>
              <td>{formatMoneyMinor(item.month_recharge_usd_minor)}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

function TeamTable({ rows }) {
  return (
    <table className="sbi-table">
      <thead>
        <tr>
          <th className="is-left">名次</th>
          <th className="is-left">部门</th>
          <th>
            <span className="sbi-metric-hint" title="部门内去重运营人数">
              人数
            </span>
          </th>
          <th>
            <span className="sbi-metric-hint" title="部门内区间充值合计（USD）">
              区间充值
            </span>
          </th>
          <th>
            <span className="sbi-metric-hint" title="部门内本月充值合计（USD）">
              当月充值
            </span>
          </th>
        </tr>
      </thead>
      <tbody>
        {!rows.length ? <EmptyTableRow colSpan={5} /> : null}
        {rows.map((row, index) => (
          <tr key={row.team}>
            <td className="is-left">
              <RankBadge rank={index + 1} />
            </td>
            <td className="is-left">{row.team}</td>
            <td>{formatCount(row.memberCount)}</td>
            <td>{formatMoneyMinor(row.rangeMinor)}</td>
            <td>{formatMoneyMinor(row.monthMinor)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function EmptyTableRow({ colSpan }) {
  return (
    <tr>
      <td className="sbi-kpi-empty-cell" colSpan={colSpan}>当前无数据</td>
    </tr>
  );
}

function OperatorCell({ item }) {
  return (
    <div className="sbi-kpi-person">
      <span className="sbi-kpi-person-top">
        <strong>{operatorLabelOf(item)}</strong>
        {item.data_error ? (
          <span className="sbi-badge is-warn" title={item.data_error}>
            数据异常
          </span>
        ) : null}
      </span>
      <small>{[item.operator_account, item.team || "未分组"].filter(Boolean).join(" · ")}</small>
    </div>
  );
}

function AppCell({ item }) {
  return (
    <span className="sbi-kpi-app">
      <SocialAppIdentity appCode={item.app_code} appName={item.app_name} />
    </span>
  );
}
