import { AppIdentity } from "@/shared/ui/AppIdentity.jsx";
import { EMPTY_RECHARGE_OVERVIEW, EMPTY_RECHARGE_SUMMARY, formatAmount, formatUsdMinor } from "../format.js";

const KPI_CARDS = [
    { filter: "", key: "total", label: "充值总和", tone: "total" },
    { filter: "google_play_recharge", key: "googlePlay", label: "谷歌充值", tone: "google" },
    { filter: "third_party", key: "thirdParty", label: "三方充值", tone: "thirdparty" },
    { filter: "coin_seller", key: "coinSeller", label: "币商充值", tone: "coinseller" },
];

const DAILY_FIELDS = {
    coinSeller: { coin: "coinSellerCoinAmount", usd: "coinSellerUsdMinor" },
    googlePlay: { coin: "googleCoinAmount", usd: "googleUsdMinor" },
    thirdParty: { coin: "thirdPartyCoinAmount", usd: "thirdPartyUsdMinor" },
};

export function FinanceOverview({
    currency,
    filters,
    loading,
    onFiltersChange,
    onGoUnsynced,
    onOpenApp,
    onOpenWithdrawals,
    overview,
    perAppSummaries,
    prevSummary,
    regions,
    summary,
}) {
    const data = summary || EMPTY_RECHARGE_SUMMARY;
    const trend = overview || EMPTY_RECHARGE_OVERVIEW;
    const showCoins = currency === "coin";
    const totalUsd = Number(data.total?.usdMinorAmount) || 0;
    const unsynced = trend.googlePaid.unsyncedCount;
    const selectedApp = filters.appCode;

    return (
        <div className="finance-overview">
            {unsynced > 0 ? (
                <div className="finance-alerts">
                    <span className="finance-alert finance-alert--warn">
                        ⚠ {formatAmount(unsynced)} 笔谷歌订单实付未同步，手续费口径尚不完整
                        <button type="button" onClick={onGoUnsynced}>
                            去同步
                        </button>
                    </span>
                </div>
            ) : null}

            <div className="finance-kpi-band">
                {KPI_CARDS.map(({ filter, key, label, tone }) => {
                    const bucket = data[key] || { billCount: 0, coinAmount: 0, usdMinorAmount: 0 };
                    const active = (filters.rechargeType || "") === filter;
                    return (
                        <button
                            className={["finance-kpi", `finance-kpi--${tone}`, active ? "finance-kpi--active" : ""]
                                .filter(Boolean)
                                .join(" ")}
                            key={key}
                            title={filter ? `点击只看${label}` : "查看全部来源"}
                            type="button"
                            onClick={() => onFiltersChange({ rechargeType: active && filter ? "" : filter })}
                        >
                            <span className="finance-kpi__label">{label}</span>
                            <strong className="finance-kpi__value">
                                {loading
                                    ? "…"
                                    : showCoins
                                      ? `${formatAmount(bucket.coinAmount)} 金币`
                                      : formatUsdMinor(bucket.usdMinorAmount, "USD")}
                            </strong>
                            <small className="finance-kpi__meta">
                                {loading ? "统计中" : kpiMeta(bucket, key, totalUsd, prevSummary)}
                            </small>
                            <Sparkline daily={trend.daily} field={key} showCoins={showCoins} tone={tone} />
                        </button>
                    );
                })}
                <WithdrawalKpi
                    loading={loading}
                    totalUsd={totalUsd}
                    withdrawal={trend.withdrawal}
                    onOpenWithdrawals={onOpenWithdrawals}
                />
            </div>

            <div className="finance-overview__split">
                <section className="finance-card">
                    <div className="finance-card__head">
                        <span className="finance-card__title">
                            充值趋势<small>按渠道堆叠 · 日 · {showCoins ? "金币" : "USD"}</small>
                        </span>
                        <div className="finance-card__tools finance-chartlegend">
                            <span>
                                <i style={{ background: "var(--fin-google)" }} />
                                谷歌
                            </span>
                            <span>
                                <i style={{ background: "var(--fin-third)" }} />
                                三方
                            </span>
                            <span>
                                <i style={{ background: "var(--fin-seller)" }} />
                                币商
                            </span>
                        </div>
                    </div>
                    <div className="finance-card__body">
                        <TrendChart daily={trend.daily} showCoins={showCoins} />
                    </div>
                </section>

                <section className="finance-card">
                    <div className="finance-card__head">
                        <span className="finance-card__title">
                            净入账拆解<small>谷歌已同步口径</small>
                        </span>
                    </div>
                    <div className="finance-card__body">
                        <DeductionBreakdown paid={trend.googlePaid} />
                        <div className="finance-card__divider" />
                        <div className="finance-card__title" style={{ marginBottom: 8 }}>
                            {selectedApp ? "区域分布 Top 5" : "区域分布"}
                        </div>
                        {selectedApp ? (
                            <RegionRanks regions={regions} />
                        ) : (
                            <p className="finance-hint">选择单个 App 后查看区域分布</p>
                        )}
                    </div>
                </section>
            </div>

            <section className="finance-card">
                <div className="finance-card__head">
                    <span className="finance-card__title">
                        App 对比<small>点击行进入该 App 流水</small>
                    </span>
                </div>
                <div className="finance-tablewrap">
                    <table className="finance-flat-table">
                        <thead>
                            <tr>
                                <th>App</th>
                                <th className="r">充值流水</th>
                                <th className="r">笔数</th>
                                <th className="r">谷歌</th>
                                <th className="r">三方</th>
                                <th className="r">币商</th>
                                <th style={{ width: 180 }}>占比</th>
                            </tr>
                        </thead>
                        <tbody>
                            {(perAppSummaries || []).map((app) => {
                                const appTotal = Number(app.summary?.total?.usdMinorAmount) || 0;
                                const maxTotal = Math.max(
                                    1,
                                    ...(perAppSummaries || []).map(
                                        (item) => Number(item.summary?.total?.usdMinorAmount) || 0,
                                    ),
                                );
                                return (
                                    <tr
                                        className="finance-flat-table__row"
                                        key={app.appCode}
                                        onClick={() => onOpenApp(app.appCode)}
                                    >
                                        <td>
                                            <AppIdentity app={app} size="small" />
                                        </td>
                                        <td className="r num">{formatUsdMinor(appTotal, "USD")}</td>
                                        <td className="r num">{formatAmount(app.summary?.total?.billCount || 0)}</td>
                                        <td className="r num">
                                            {formatUsdMinor(app.summary?.googlePlay?.usdMinorAmount || 0, "USD")}
                                        </td>
                                        <td className="r num">
                                            {formatUsdMinor(app.summary?.thirdParty?.usdMinorAmount || 0, "USD")}
                                        </td>
                                        <td className="r num">
                                            {formatUsdMinor(app.summary?.coinSeller?.usdMinorAmount || 0, "USD")}
                                        </td>
                                        <td>
                                            <span className="finance-rankbar">
                                                <i style={{ width: `${(appTotal / maxTotal) * 100}%` }} />
                                            </span>
                                        </td>
                                    </tr>
                                );
                            })}
                            {!perAppSummaries?.length ? (
                                <tr>
                                    <td colSpan={7} style={{ textAlign: "center" }}>
                                        暂无数据
                                    </td>
                                </tr>
                            ) : null}
                        </tbody>
                    </table>
                </div>
            </section>
        </div>
    );
}

// WithdrawalKpi 是两张独立口径的资金流出卡：
// 「用户提现」只统计提现申请审核通过的 USDT（点击进入提现审核页）；
// 「工资兑换」只统计用户工资转币商的 USDT（likei 平台为银行卡余额兑换金币）。
// 两者都不是充值渠道，不参与来源筛选联动，占比按“金额 / 充值总和”表达资金回流强度。
function WithdrawalKpi({ loading, onOpenWithdrawals, totalUsd, withdrawal }) {
    const data = withdrawal || {
        approvedCount: 0,
        approvedUsdMinor: 0,
        totalUsdMinor: 0,
        transferCount: 0,
        transferUsdMinor: 0,
    };
    return (
        <>
            <button
                className="finance-kpi finance-kpi--withdrawal"
                title="点击进入用户提现申请"
                type="button"
                onClick={onOpenWithdrawals}
            >
                <span className="finance-kpi__label">用户提现</span>
                <strong className="finance-kpi__value">{loading ? "…" : usdtText(data.approvedUsdMinor)}</strong>
                <small className="finance-kpi__meta">
                    {loading ? "统计中" : outflowMeta(data.approvedUsdMinor, data.approvedCount, totalUsd)}
                </small>
                <small className="finance-kpi__meta">提现申请审核通过</small>
            </button>
            <div className="finance-kpi finance-kpi--salary">
                <span className="finance-kpi__label">工资兑换</span>
                <strong className="finance-kpi__value">{loading ? "…" : usdtText(data.transferUsdMinor)}</strong>
                <small className="finance-kpi__meta">
                    {loading ? "统计中" : outflowMeta(data.transferUsdMinor, data.transferCount, totalUsd)}
                </small>
                <small className="finance-kpi__meta">用户工资转币商</small>
            </div>
        </>
    );
}

function usdtText(usdMinor) {
    return `USDT ${(usdMinor / 100).toLocaleString("zh-CN", { maximumFractionDigits: 2, minimumFractionDigits: 2 })}`;
}

function outflowMeta(usdMinor, count, totalUsd) {
    const parts = [];
    if (totalUsd > 0) {
        const share = (usdMinor / totalUsd) * 100;
        parts.push(`占充值 ${share.toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%`);
    }
    parts.push(`${formatAmount(count)} 笔`);
    return parts.join(" · ");
}

function kpiMeta(bucket, key, totalUsd, prevSummary) {
    const parts = [`${formatAmount(bucket.billCount)} 笔`];
    if (key !== "total" && totalUsd > 0) {
        const share = ((Number(bucket.usdMinorAmount) || 0) / totalUsd) * 100;
        parts.push(`占比 ${share.toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%`);
    }
    const prev = prevSummary?.[key];
    if (prev && Number(prev.usdMinorAmount) > 0) {
        const delta =
            ((Number(bucket.usdMinorAmount) - Number(prev.usdMinorAmount)) / Number(prev.usdMinorAmount)) * 100;
        const arrow = delta >= 0 ? "▲" : "▼";
        parts.push(`${arrow} ${Math.abs(delta).toLocaleString("zh-CN", { maximumFractionDigits: 1 })}% vs 上期`);
    }
    return parts.join(" · ");
}

function Sparkline({ daily, field, showCoins, tone }) {
    const values = (daily || []).map((bucket) => {
        if (field === "total") {
            return showCoins
                ? bucket.googleCoinAmount + bucket.thirdPartyCoinAmount + bucket.coinSellerCoinAmount
                : bucket.googleUsdMinor + bucket.thirdPartyUsdMinor + bucket.coinSellerUsdMinor;
        }
        const fields = DAILY_FIELDS[field];
        return fields ? bucket[showCoins ? fields.coin : fields.usd] : 0;
    });
    if (values.length < 2) {
        return <span className="finance-sparkline" />;
    }
    const width = 100;
    const height = 28;
    const max = Math.max(...values);
    const min = Math.min(...values);
    const points = values.map((value, index) => {
        const x = (index * width) / (values.length - 1);
        const y = height - 3 - ((value - min) / (max - min || 1)) * (height - 8);
        return `${x.toFixed(1)},${y.toFixed(1)}`;
    });
    const colors = {
        coinseller: "#B45309",
        google: "#1B873F",
        thirdparty: "#0E7490",
        total: "#2557D6",
    };
    const color = colors[tone] || colors.total;
    return (
        <svg className="finance-sparkline" preserveAspectRatio="none" viewBox={`0 0 ${width} ${height}`}>
            <polyline fill={`${color}22`} points={`${points.join(" ")} ${width},${height} 0,${height}`} stroke="none" />
            <polyline
                fill="none"
                points={points.join(" ")}
                stroke={color}
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth="1.8"
            />
        </svg>
    );
}

function TrendChart({ daily, showCoins }) {
    const buckets = daily || [];
    if (!buckets.length) {
        return <p className="finance-hint">当前时间范围内没有充值数据</p>;
    }
    const totals = buckets.map((bucket) =>
        showCoins
            ? bucket.googleCoinAmount + bucket.thirdPartyCoinAmount + bucket.coinSellerCoinAmount
            : bucket.googleUsdMinor + bucket.thirdPartyUsdMinor + bucket.coinSellerUsdMinor,
    );
    const max = Math.max(1, ...totals);
    const value = (bucket, channel) => {
        const fields = DAILY_FIELDS[channel];
        return bucket[showCoins ? fields.coin : fields.usd];
    };
    return (
        <div>
            <div className="finance-trend" role="img" aria-label="按渠道堆叠的每日充值趋势">
                {buckets.map((bucket) => (
                    <div
                        className="finance-trend__col"
                        key={bucket.date}
                        title={`${bucket.date} · 谷歌 ${trendTip(bucket, "googlePlay", showCoins)} · 三方 ${trendTip(bucket, "thirdParty", showCoins)} · 币商 ${trendTip(bucket, "coinSeller", showCoins)}`}
                    >
                        {["googlePlay", "thirdParty", "coinSeller"].map((channel) => {
                            const amount = value(bucket, channel);
                            if (amount <= 0) {
                                return null;
                            }
                            return (
                                <span
                                    className={`finance-trend__seg finance-trend__seg--${channel}`}
                                    key={channel}
                                    style={{ height: `${(amount / max) * 100}%` }}
                                />
                            );
                        })}
                    </div>
                ))}
            </div>
            <div className="finance-trend__axis">
                <span>{buckets[0].date.slice(5)}</span>
                {buckets.length > 2 ? <span>{buckets[Math.floor(buckets.length / 2)].date.slice(5)}</span> : null}
                <span>{buckets[buckets.length - 1].date.slice(5)}</span>
            </div>
        </div>
    );
}

function trendTip(bucket, channel, showCoins) {
    const fields = DAILY_FIELDS[channel];
    const amount = bucket[showCoins ? fields.coin : fields.usd];
    return showCoins ? formatAmount(amount) : formatUsdMinor(amount, "USD");
}

function DeductionBreakdown({ paid }) {
    const covered = paid.coveredUsdMinor;
    if (covered <= 0) {
        return (
            <p className="finance-hint">
                暂无已同步的谷歌实付明细；点「查询谷歌实付」同步后这里会展示手续费与税费拆解。
            </p>
        );
    }
    const rows = [
        { amount: paid.estNetUsdMinor, color: "var(--fin-pos)", label: "净入账（估）" },
        { amount: paid.estFeeUsdMinor, color: "#E19B3C", label: "谷歌服务费（估）" },
        { amount: paid.estTaxUsdMinor, color: "#C86A6A", label: "代缴税费（估）" },
    ];
    return (
        <div>
            <div className="finance-mixbar">
                {rows.map((row) => (
                    <span key={row.label} style={{ background: row.color, flex: Math.max(row.amount, 1) }} />
                ))}
            </div>
            {rows.map((row) => (
                <div className="finance-mixrow" key={row.label}>
                    <i style={{ background: row.color }} />
                    <span className="finance-mixrow__name">{row.label}</span>
                    <span className="finance-mixrow__amt num">{formatUsdMinor(row.amount, "USD")}</span>
                    <span className="finance-mixrow__pct num">
                        {((row.amount / covered) * 100).toLocaleString("zh-CN", { maximumFractionDigits: 1 })}%
                    </span>
                </div>
            ))}
            <p className="finance-hint" style={{ marginTop: 8 }}>
                口径：已同步 {formatAmount(paid.syncedCount)} / {formatAmount(paid.googleBillCount)}{" "}
                笔谷歌订单，覆盖流水 {formatUsdMinor(covered, "USD")}；按各订单实付占比折算成 USD
            </p>
        </div>
    );
}

function RegionRanks({ regions }) {
    const top = (regions || []).slice(0, 5);
    if (!top.length) {
        return <p className="finance-hint">当前筛选下暂无区域数据</p>;
    }
    const max = Math.max(1, ...top.map((region) => region.usdMinorAmount));
    return (
        <div>
            {top.map((region, index) => (
                <div className="finance-rankrow" key={region.regionId || region.name || index}>
                    <span className="finance-rankrow__idx num">{index + 1}</span>
                    <span className="finance-rankrow__name">{region.name || `区域 ${region.regionId}`}</span>
                    <span className="finance-rankbar">
                        <i style={{ width: `${(region.usdMinorAmount / max) * 100}%` }} />
                    </span>
                    <span className="finance-rankrow__amt num">{formatUsdMinor(region.usdMinorAmount, "USD")}</span>
                </div>
            ))}
        </div>
    );
}
