import { useEffect, useState } from 'react';
import { View, Text, Input } from '@tarojs/components';
import '../../styles/redeem.css';
import Taro, { useRouter } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import SubPageHeader from '../../components/SubPageHeader';
import { goLogin } from '../../lib/auth-nav';
import { isLoggedIn, request, toast } from '../../lib/api';
import { formatMoney } from '../../lib/money';
import BenefitFigure from '../../components/BenefitFigure';

type BenefitSummary = {
  totalBalance: number;
  maxRedeemAmount: number;
};

const MIN_REDEEM_AMOUNT = 0.01;

/**
 * 核销金额输入清洗：
 * - 只保留数字与一个小数点
 * - 小数最多 2 位（再输入会被截断）
 * - 去掉多余前导 0
 */
function sanitizeRedeemAmountInput(raw: string): string {
  let next = String(raw ?? '').replace(/[^\d.]/g, '');
  if (!next) return '';

  const firstDot = next.indexOf('.');
  if (firstDot >= 0) {
    const intRaw = next.slice(0, firstDot).replace(/\D/g, '');
    const decRaw = next
      .slice(firstDot + 1)
      .replace(/\D/g, '')
      .slice(0, 2);
    const intPart = intRaw.replace(/^0+(?=\d)/, '') || '0';
    if (next.endsWith('.') && decRaw.length === 0) {
      return `${intPart}.`;
    }
    if (decRaw.length > 0) {
      return `${intPart}.${decRaw}`;
    }
    return intPart;
  }

  return next.replace(/^0+(?=\d)/, '');
}

export default function RedeemPage() {
  const router = useRouter();
  const couponId = router.params.couponId;
  const initialAmount = router.params.amount ?? '';
  const [balance, setBalance] = useState(0);
  const [couponBalance, setCouponBalance] = useState<number | null>(null);
  const [amount, setAmount] = useState(() => sanitizeRedeemAmountInput(initialAmount));
  /** 原生 input 在截断小数后偶发不同步，强制 remount 对齐受控值 */
  const [inputKey, setInputKey] = useState(0);
  const [loading, setLoading] = useState(false);

  const redeemableMax = couponId ? (couponBalance ?? 0) : balance;

  useEffect(() => {
    if (!isLoggedIn()) {
      goLogin('/pages/redeem/index');
      return;
    }
    request<BenefitSummary>('/benefit/summary')
      .then((s) => setBalance(Number(s.maxRedeemAmount ?? s.totalBalance ?? 0)))
      .catch(() => {});
  }, []);

  useEffect(() => {
    if (!couponId) {
      setCouponBalance(null);
      return;
    }
    request<Array<{ id: string; balance: number }>>('/benefit/coupons')
      .then((list) => {
        const found = list.find((c) => String(c.id) === couponId);
        if (found) setCouponBalance(Number(found.balance));
      })
      .catch(() => {});
  }, [couponId]);

  function fillMaxAmount() {
    if (redeemableMax < MIN_REDEEM_AMOUNT) return;
    setAmount(sanitizeRedeemAmountInput(redeemableMax.toFixed(2)));
    setInputKey((k) => k + 1);
  }

  function onAmountChange(raw: string) {
    const next = sanitizeRedeemAmountInput(raw);
    setAmount(next);
    // 用户试图输入超过两位小数 / 非法字符时，强制刷新原生框显示
    if (next !== raw) {
      setInputKey((k) => k + 1);
    }
  }

  async function submit() {
    const value = Math.round(Number(amount) * 100) / 100;
    if (!Number.isFinite(value) || value < MIN_REDEEM_AMOUNT) {
      toast(`核销金额不能低于 ${MIN_REDEEM_AMOUNT.toFixed(2)} 元`);
      return;
    }
    if (value > redeemableMax) {
      toast(couponId ? '核销金额不能超过该权益可用余额' : '核销金额不能超过可用余额');
      return;
    }

    setLoading(true);
    try {
      const body: { amount: number; couponId?: string } = { amount: value };
      if (couponId) body.couponId = couponId;

      const data = await request<{ token: string; amount: number }>('/redeem/tokens', {
        method: 'POST',
        data: body,
      });
      Taro.navigateTo({
        url: `/pages/redeem-code/index?token=${encodeURIComponent(data.token)}&amount=${data.amount}`,
      });
    } catch (e) {
      toast(e instanceof Error ? e.message : '生成失败');
    } finally {
      setLoading(false);
    }
  }

  return (
    <PageShell variant="sub" className="redeem-page">
      <SubPageHeader title="权益核销" />
      <View className="sub-page-body">
        <View className="redeem-hero">
          <Text className="redeem-hero-label">
            {couponId ? '当前权益可用余额' : '可用余额'}
          </Text>
          <BenefitFigure
            value={redeemableMax > 0 ? formatMoney(redeemableMax) : '--'}
            size="xl"
            className="redeem-hero-amount"
          />
        </View>
        <View className="redeem-input-wrap">
          <Input
            key={inputKey}
            className="redeem-input"
            type="digit"
            placeholder="输入核销金额"
            placeholderClass="redeem-input-placeholder"
            value={amount}
            maxlength={12}
            onInput={(e) => onAmountChange(e.detail.value)}
            onBlur={(e) => onAmountChange(e.detail.value)}
            style={{ textAlign: 'center' }}
          />
        </View>
        <View className="redeem-amount-foot">
          <View className="redeem-amount-hint">
            <Text>最高可核销</Text>
            <BenefitFigure value={formatMoney(redeemableMax)} size="sm" />
          </View>
          <Text className="redeem-fill-max" onClick={fillMaxAmount}>
            全部核销
          </Text>
        </View>
        <View className="redeem-tips">
          <Text className="redeem-tips-text">
            核销金额最低 0.01 元，小数最多两位。不超过可用权益余额。核销码有效期 3 分钟，请到店出示给收银员扫码。
          </Text>
        </View>
        <View
          className={`redeem-submit${loading || redeemableMax < MIN_REDEEM_AMOUNT ? ' redeem-submit--disabled' : ''}`}
          onClick={loading || redeemableMax < MIN_REDEEM_AMOUNT ? undefined : submit}
        >
          <Text>{loading ? '生成中...' : '生成核销码'}</Text>
        </View>
      </View>
    </PageShell>
  );
}
