import { useEffect, useRef, useState, type CSSProperties } from 'react';

const RING_R = 16;
const CIRC = 2 * Math.PI * RING_R;
const POPOVER_WIDTH = 260;
const HEADER_POPOVER_OPEN_EVENT = 'tkmind:header-popover-open';
const HEADER_POPOVER_ID = 'balance-ring';

function formatYuan(cents: number) {
  return `¥${(cents / 100).toFixed(2)}`;
}

function formatTokenCount(tokens: number) {
  if (tokens >= 100_000) {
    return `${(tokens / 10_000).toFixed(1).replace(/\.0$/, '')} 万`;
  }
  if (tokens >= 10_000) {
    return `${(tokens / 10_000).toFixed(2).replace(/\.?0+$/, '')} 万`;
  }
  if (tokens >= 1_000) {
    return `${(tokens / 1_000).toFixed(1).replace(/\.0$/, '')}k`;
  }
  return tokens.toLocaleString('zh-CN');
}

function formatCallsApprox(tokens: number) {
  const calls = Math.floor(tokens / 3000);
  return `约 ${calls} 次`;
}

type ActiveSubscription = {
  planType: string;
  periodTokensLimit: number;
  periodTokensUsed: number;
  periodEnd: number;
  overageRate: number;
};

type BalanceRingProps = {
  balanceCents: number;
  totalCreditCents?: number;
  tokensUsed?: number;
  subscription?: ActiveSubscription | null;
  onRecharge: (force?: boolean) => void;
  onSubscribe?: () => void;
};

const PLAN_LABELS: Record<string, string> = {
  free: '免费版',
  lite: '轻量版',
  standard: '标准版',
  pro: '专业版',
};

export function BalanceRing({
  balanceCents,
  totalCreditCents,
  tokensUsed = 0,
  subscription,
  onRecharge,
  onSubscribe,
}: BalanceRingProps) {
  const [open, setOpen] = useState(false);
  const [popoverStyle, setPopoverStyle] = useState<CSSProperties>({});
  const wrapRef = useRef<HTMLDivElement>(null);

  // Subscription quota mode: only paid plans change the ring display.
  // Free plan runs silently in the background — balance ring stays primary.
  const isPaidPlan = Boolean(subscription) && subscription!.planType !== 'free';
  const hasSub = isPaidPlan;
  const subUnlimited = hasSub && subscription!.periodTokensLimit === 0;
  const subLimit = subscription?.periodTokensLimit ?? 0;
  const subUsed = subscription?.periodTokensUsed ?? 0;
  const subRemaining = Math.max(0, subLimit - subUsed);
  const subPct = subLimit > 0 ? Math.round((subRemaining / subLimit) * 100) : 100;
  const subLow = hasSub && !subUnlimited && subPct <= 15;
  const subEmpty = hasSub && !subUnlimited && subRemaining <= 0;

  // Balance mode (used when no active subscription or overage).
  const total = Math.max(totalCreditCents ?? balanceCents, balanceCents, 0);
  const spent = Math.max(0, total - balanceCents);
  const balancePct = total > 0 ? Math.round((balanceCents / total) * 100) : 0;
  const spentLen = total > 0 ? (spent / total) * CIRC : 0;
  const remainLen = total > 0 ? (balanceCents / total) * CIRC : 0;
  const spentPct = total > 0 ? (spent / total) * 100 : 0;
  const remainPct = total > 0 ? (balanceCents / total) * 100 : 0;
  const balanceLow = balanceCents > 0 && balanceCents <= 100;
  const balanceEmpty = balanceCents <= 0;

  // Ring display: subscription quota takes priority over balance.
  let ringRemainLen: number;
  let ringSpentLen: number;
  let centerLabel: string;
  let ariaLabel: string;
  let low: boolean;
  let empty: boolean;

  if (hasSub && !subUnlimited) {
    const usedLen = subLimit > 0 ? (subUsed / subLimit) * CIRC : 0;
    ringRemainLen = subLimit > 0 ? (subRemaining / subLimit) * CIRC : CIRC;
    ringSpentLen = usedLen;
    centerLabel = subEmpty ? '0%' : `${subPct}%`;
    ariaLabel = `本月额度，剩余 ${subPct}%`;
    low = subLow;
    empty = subEmpty;
  } else if (hasSub && subUnlimited) {
    ringRemainLen = CIRC;
    ringSpentLen = 0;
    centerLabel = '∞';
    ariaLabel = '专业版，不限额度';
    low = false;
    empty = false;
  } else {
    ringRemainLen = remainLen;
    ringSpentLen = spentLen;
    centerLabel = total <= 0 ? '—' : balanceEmpty ? '0%' : `${balancePct}%`;
    ariaLabel = total > 0 ? `账户余额，剩余 ${balancePct}%` : '账户余额';
    low = balanceLow;
    empty = balanceEmpty;
  }

  useEffect(() => {
    if (!open) return;
    const handleClick = (event: MouseEvent) => {
      if (wrapRef.current && !wrapRef.current.contains(event.target as Node)) {
        setOpen(false);
      }
    };
    document.addEventListener('click', handleClick);
    return () => document.removeEventListener('click', handleClick);
  }, [open]);

  useEffect(() => {
    const handleOtherPopoverOpen = (event: Event) => {
      const detail = (event as CustomEvent<{ id?: string }>).detail;
      if (detail?.id && detail.id !== HEADER_POPOVER_ID) {
        setOpen(false);
      }
    };
    window.addEventListener(HEADER_POPOVER_OPEN_EVENT, handleOtherPopoverOpen);
    return () => window.removeEventListener(HEADER_POPOVER_OPEN_EVENT, handleOtherPopoverOpen);
  }, []);

  useEffect(() => {
    if (!open) return;

    const updatePosition = () => {
      const anchor = wrapRef.current;
      if (!anchor) return;
      const rect = anchor.getBoundingClientRect();
      const width = Math.min(POPOVER_WIDTH, window.innerWidth - 24);
      let left = rect.left + rect.width / 2 - width / 2;
      left = Math.max(12, Math.min(left, window.innerWidth - width - 12));
      setPopoverStyle({
        position: 'fixed',
        top: rect.bottom + 10,
        left,
        width,
      });
    };

    updatePosition();
    window.addEventListener('resize', updatePosition);
    window.addEventListener('scroll', updatePosition, true);
    return () => {
      window.removeEventListener('resize', updatePosition);
      window.removeEventListener('scroll', updatePosition, true);
    };
  }, [open]);

  const periodEndDate = subscription
    ? new Date(subscription.periodEnd).toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' })
    : null;

  return (
    <div className={`balance-popover-wrap${open ? ' open' : ''}`} ref={wrapRef}>
      <button
        type="button"
        className={`balance-ring-btn${low ? ' low' : ''}${empty ? ' empty' : ''}`}
        aria-label={ariaLabel}
        aria-expanded={open}
        onClick={(event) => {
          event.stopPropagation();
          setOpen((value) => {
            const next = !value;
            if (next) {
              window.dispatchEvent(
                new CustomEvent(HEADER_POPOVER_OPEN_EVENT, {
                  detail: { id: HEADER_POPOVER_ID },
                }),
              );
            }
            return next;
          });
        }}
      >
        <svg className="balance-ring-svg" viewBox="0 0 40 40" aria-hidden="true">
          <circle className="balance-ring-track" cx="20" cy="20" r={RING_R} />
          <circle
            className="balance-ring-spent"
            cx="20"
            cy="20"
            r={RING_R}
            strokeDasharray={`${ringSpentLen} ${CIRC}`}
            strokeDashoffset={0}
          />
          <circle
            className="balance-ring-remain"
            cx="20"
            cy="20"
            r={RING_R}
            strokeDasharray={`${ringRemainLen} ${CIRC}`}
            strokeDashoffset={-ringSpentLen}
          />
        </svg>
        <span className="balance-ring-center">{centerLabel}</span>
      </button>

      <div className="balance-popover" role="dialog" aria-label="账户额度" style={popoverStyle}>
        {hasSub ? (
          <>
            <h4>
              {PLAN_LABELS[subscription!.planType] ?? subscription!.planType}
              {subscription!.planType !== 'free' && (
                <span className="balance-plan-badge">订阅中</span>
              )}
            </h4>

            {subUnlimited ? (
              <div className="balance-popover-row">
                <span className="balance-popover-label balance-popover-label-muted">本月额度</span>
                <span>不限量</span>
              </div>
            ) : (
              <>
                <div className="balance-popover-row">
                  <span className="balance-popover-label">
                    <span className="balance-dot balance-dot-remain" aria-hidden="true" />
                    剩余额度
                  </span>
                  <strong>{formatCallsApprox(subRemaining)}</strong>
                </div>
                <div className="balance-popover-row">
                  <span className="balance-popover-label">
                    <span className="balance-dot balance-dot-spent" aria-hidden="true" />
                    已使用
                  </span>
                  <strong>{formatCallsApprox(subUsed)}</strong>
                </div>
                <div className="balance-popover-bar" aria-hidden="true">
                  <div
                    className="balance-popover-bar-spent"
                    style={{ width: `${subLimit > 0 ? (subUsed / subLimit) * 100 : 0}%` }}
                  />
                  <div
                    className="balance-popover-bar-remain"
                    style={{ width: `${subLimit > 0 ? (subRemaining / subLimit) * 100 : 0}%` }}
                  />
                </div>
              </>
            )}

            {periodEndDate && (
              <p className="balance-popover-hint">周期截止 {periodEndDate}</p>
            )}

            <div className="balance-popover-section">
              <h5>余额账户</h5>
              <div className="balance-popover-row">
                <span className="balance-popover-label balance-popover-label-muted">可用余额</span>
                <span>{formatYuan(balanceCents)}</span>
              </div>
              {subscription!.overageRate < 1 && (
                <p className="balance-popover-hint">
                  超出套餐后按 {Math.round(subscription!.overageRate * 10)} 折从余额扣费
                </p>
              )}
            </div>

            {(subEmpty || subLow) && (
              <p className="balance-popover-warning">
                {subEmpty ? '本月额度已用完' : '额度即将耗尽'}
                {balanceCents > 0 ? '，将从余额扣费' : '，请充值继续使用'}
              </p>
            )}
          </>
        ) : (
          <>
            <h4>账户额度</h4>
            <div className="balance-popover-row">
              <span className="balance-popover-label">
                <span className="balance-dot balance-dot-remain" aria-hidden="true" />
                剩余
              </span>
              <strong>{formatYuan(balanceCents)}</strong>
            </div>
            <div className="balance-popover-row">
              <span className="balance-popover-label">
                <span className="balance-dot balance-dot-spent" aria-hidden="true" />
                已消耗
              </span>
              <strong>{formatYuan(spent)}</strong>
            </div>
            <div className="balance-popover-row">
              <span className="balance-popover-label balance-popover-label-muted">累计充值</span>
              <span>{formatYuan(total)}</span>
            </div>
            <div className="balance-popover-bar" aria-hidden="true">
              <div className="balance-popover-bar-spent" style={{ width: `${spentPct}%` }} />
              <div className="balance-popover-bar-remain" style={{ width: `${remainPct}%` }} />
            </div>
            {(balanceLow || balanceEmpty) && (
              <p className="balance-popover-warning">余额不足，请充值后继续</p>
            )}
            {subscription?.planType === 'free' && subscription.periodTokensLimit > 0 && (
              <p className="balance-popover-hint">
                每月赠送 {formatCallsApprox(Math.max(0, subscription.periodTokensLimit - subscription.periodTokensUsed))} 免费额度，余额用于超出部分
              </p>
            )}
          </>
        )}

        <div className="balance-popover-section">
          <h5>AI 消耗</h5>
          <div className="balance-popover-row">
            <span className="balance-popover-label balance-popover-label-muted">累计 Token</span>
            <span>{formatTokenCount(tokensUsed)}</span>
          </div>
          <p className="balance-popover-hint">按人民币结算，每次对话按实际用量扣费</p>
        </div>

        <div style={{ display: 'flex', gap: 8 }}>
          {onSubscribe && (
            <button
              type="button"
              className="balance-popover-cta"
              onClick={() => {
                setOpen(false);
                onSubscribe();
              }}
              style={{ flex: 1 }}
            >
              {hasSub && subscription!.planType !== 'free' ? '管理套餐' : '升级套餐'}
            </button>
          )}
          <button
            type="button"
            className="balance-popover-cta"
            onClick={() => {
              setOpen(false);
              onRecharge(empty);
            }}
            style={onSubscribe ? { flex: 1 } : {}}
          >
            去充值
          </button>
        </div>
      </div>
    </div>
  );
}
