import { useCallback, useEffect, useRef, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { REDEEM_TOKEN_TTL_SECONDS } from '@dukang/shared-types';
import { request } from '../lib/api';
import { usePageView } from '../lib/usePageView';

const POLL_INTERVAL_MS = 2500;

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

type RedeemTokenStatus =
  | { status: 'PENDING'; expireInSeconds: number; amount: number }
  | {
      status: 'CONSUMED';
      record: {
        id: string;
        redeemNo: string;
        amount: number;
        storeId: string;
        storeName: string;
        createdAt: string;
      };
    }
  | { status: 'EXPIRED' };

function formatMoney(amount: number) {
  return amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

function formatTimer(seconds: number) {
  const mins = Math.floor(seconds / 60);
  const secs = seconds % 60;
  return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
}

export default function RedeemPage() {
  usePageView('benefit_redeem_start');
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const couponId = searchParams.get('couponId') ?? undefined;
  const presetAmount = searchParams.get('amount');

  const [summary, setSummary] = useState<BenefitSummary | null>(null);
  const [couponBalance, setCouponBalance] = useState<number | null>(null);
  const [amountInput, setAmountInput] = useState('');
  const [msg, setMsg] = useState('');
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [token, setToken] = useState('');
  const [confirmAmount, setConfirmAmount] = useState(0);
  const [timerSec, setTimerSec] = useState(REDEEM_TOKEN_TTL_SECONDS);
  const timerRef = useRef<number | null>(null);
  const presetApplied = useRef(false);
  const successHandled = useRef(false);

  const redeemableMax = couponId ? (couponBalance ?? 0) : (summary?.totalBalance ?? 0);

  useEffect(() => {
    request<BenefitSummary>('USER_H5', '/benefit/summary').then(setSummary).catch(() => {});
    return () => stopTimer();
  }, []);

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

  useEffect(() => {
    if (presetApplied.current) return;
    if (presetAmount && Number(presetAmount) > 0) {
      setAmountInput(formatMoney(Number(presetAmount)));
      presetApplied.current = true;
    }
  }, [presetAmount]);

  function stopTimer() {
    if (timerRef.current != null) {
      window.clearInterval(timerRef.current);
      timerRef.current = null;
    }
  }

  const closeModal = useCallback(() => {
    stopTimer();
    setModalOpen(false);
    setToken('');
    setTimerSec(REDEEM_TOKEN_TTL_SECONDS);
    successHandled.current = false;
  }, []);

  const handleRedeemExpired = useCallback(() => {
    if (successHandled.current) return;
    successHandled.current = true;
    closeModal();
    sessionStorage.removeItem('redeemToken');
    sessionStorage.removeItem('redeemAmount');
    setMsg('核销码已失效，请重新生成');
  }, [closeModal]);

  const handleRedeemSuccess = useCallback(
    (record: NonNullable<Extract<RedeemTokenStatus, { status: 'CONSUMED' }>['record']>) => {
      if (successHandled.current) return;
      successHandled.current = true;
      stopTimer();
      setModalOpen(false);
      setToken('');
      sessionStorage.setItem('lastRedeemRecordId', record.id);
      sessionStorage.setItem('lastRedeemResult', JSON.stringify(record));
      sessionStorage.removeItem('redeemToken');
      sessionStorage.removeItem('redeemAmount');
      navigate('/redeem/success', {
        replace: true,
        state: { record },
      });
    },
    [navigate],
  );

  function startTimer() {
    stopTimer();
    setTimerSec(REDEEM_TOKEN_TTL_SECONDS);
    timerRef.current = window.setInterval(() => {
      setTimerSec((prev) => {
        if (prev <= 1) {
          stopTimer();
          window.setTimeout(() => handleRedeemExpired(), 0);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  }

  useEffect(() => {
    if (!modalOpen || !token) return undefined;

    let cancelled = false;

    async function pollStatus() {
      try {
        const status = await request<RedeemTokenStatus>('USER_H5', `/redeem/tokens/${token}/status`);
        if (cancelled || successHandled.current) return;
        if (status.status === 'CONSUMED' && status.record) {
          handleRedeemSuccess(status.record);
        } else if (status.status === 'EXPIRED') {
          handleRedeemExpired();
        } else if (status.status === 'PENDING' && status.expireInSeconds > 0) {
          setTimerSec((prev) => Math.min(prev, status.expireInSeconds));
        }
      } catch {
        /* 轮询失败忽略，下次重试 */
      }
    }

    void pollStatus();
    const pollId = window.setInterval(() => void pollStatus(), POLL_INTERVAL_MS);
    return () => {
      cancelled = true;
      window.clearInterval(pollId);
    };
  }, [modalOpen, token, handleRedeemSuccess, handleRedeemExpired]);

  function parseAmount() {
    const value = Number(amountInput);
    return Number.isFinite(value) ? Math.round(value * 100) / 100 : 0;
  }

  function fillMaxAmount() {
    if (redeemableMax <= 0) return;
    setAmountInput(formatMoney(redeemableMax));
    setMsg('');
  }

  async function submit() {
    const amount = parseAmount();
    if (!summary) return;
    const maxAllowed = couponId ? (couponBalance ?? 0) : summary.totalBalance;

    if (amount <= 0) {
      setMsg('请输入核销金额');
      return;
    }
    if (amount > maxAllowed) {
      setMsg(couponId ? '核销金额不能超过该权益可用余额' : '核销金额不能超过可用余额');
      return;
    }

    setLoading(true);
    setMsg('');
    successHandled.current = false;
    try {
      const body: { amount: number; couponId?: string } = { amount };
      if (couponId) body.couponId = couponId;

      const data = await request<{ token: string; amount: number }>('USER_H5', '/redeem/tokens', {
        method: 'POST',
        body: JSON.stringify(body),
      });
      setToken(data.token);
      setConfirmAmount(data.amount);
      setModalOpen(true);
      startTimer();
      sessionStorage.setItem('redeemToken', data.token);
      sessionStorage.setItem('redeemAmount', String(data.amount));
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '生成失败');
    } finally {
      setLoading(false);
    }
  }

  const qrUrl = token
    ? `https://api.qrserver.com/v1/create-qr-code/?size=192x192&data=${encodeURIComponent(token)}`
    : '';

  return (
    <div className="redeem-page">
      <header className="redeem-header">
        <button type="button" className="redeem-header-btn" aria-label="返回" onClick={() => navigate(-1)}>
          <span className="material-symbols-outlined">arrow_back</span>
        </button>
        <h1 className="app-page-title">好客权益核销</h1>
        <button
          type="button"
          className="redeem-header-btn"
          aria-label="帮助"
          onClick={() => window.alert('核销金额不超过可用余额，核销码 3 分钟内有效。')}
        >
          <span className="material-symbols-outlined">help_outline</span>
        </button>
      </header>

      <main className="redeem-main">
        <section className="redeem-balance-card">
          <div className="redeem-balance-pattern" aria-hidden />
          <div className="redeem-balance-inner">
            <span className="redeem-balance-label">
              {couponId ? '当前权益可用余额' : '当前好客权益可用余额'}
            </span>
            <div className="redeem-balance-amount">
              <span className="redeem-balance-symbol">¥</span>
              <span className="redeem-balance-value">
                {redeemableMax > 0 ? formatMoney(redeemableMax) : '--'}
              </span>
            </div>
          </div>
        </section>

        <section className="redeem-form-card">
          <label className="redeem-form-label" htmlFor="redeem-amount">
            核销金额 (¥)
          </label>
          <div className="redeem-amount-row">
            <span className="redeem-amount-symbol">¥</span>
            <input
              id="redeem-amount"
              className="redeem-amount-input"
              type="number"
              inputMode="decimal"
              step="0.01"
              min="0"
              placeholder="0.00"
              value={amountInput}
              onChange={(e) => {
                setAmountInput(e.target.value);
                setMsg('');
              }}
            />
          </div>
          <div className="redeem-amount-foot">
            <span>最高可核销 ¥{formatMoney(redeemableMax)}</span>
            <button type="button" className="redeem-fill-max" onClick={fillMaxAmount}>
              全部核销
            </button>
          </div>
        </section>

        {msg && <p className="redeem-msg">{msg}</p>}

        <button
          type="button"
          className="redeem-submit-btn"
          disabled={loading || redeemableMax <= 0}
          onClick={submit}
        >
          <span className="material-symbols-outlined">qr_code_2</span>
          {loading ? '生成中...' : '生成核销码'}
        </button>

        <div className="redeem-security">
          <span className="material-symbols-outlined">shield</span>
          <p>安全提示：请在核销前核实金额，核销码将在 3 分钟后自动失效。</p>
        </div>
      </main>

      <div className={`redeem-modal${modalOpen ? ' open' : ''}`} aria-hidden={!modalOpen}>
        <div className="redeem-modal-backdrop" onClick={closeModal} aria-hidden />
        <div className={`redeem-modal-panel${modalOpen ? ' open' : ''}`}>
          <div className="redeem-modal-head">
            <h3>正在核销</h3>
            <p>请向收银员出示此码</p>
          </div>
          <div className="redeem-modal-body">
            <div className="redeem-qr-wrap">
              <div className="redeem-qr-box">
                {qrUrl ? (
                  <img className="redeem-qr-img" src={qrUrl} alt="核销二维码" />
                ) : (
                  <div className="redeem-qr-placeholder" />
                )}
                <div className="redeem-qr-scanline" aria-hidden />
              </div>
            </div>
            <div className={`redeem-timer${timerSec > 0 && timerSec < REDEEM_TOKEN_TTL_SECONDS ? ' active' : ''}`}>
              <span className="redeem-timer-value">{formatTimer(timerSec)}</span>
              <span className="redeem-timer-label">失效倒计时</span>
            </div>
            <div className="redeem-modal-amount">
              <p>待核销金额</p>
              <p className="redeem-modal-amount-value">¥ {formatMoney(confirmAmount)}</p>
            </div>
            {token && (
              <div style={{ marginTop: 12, textAlign: 'center' }}>
                <p className="label-md text-muted" style={{ marginBottom: 4 }}>核销码编号（供追查）</p>
                <p
                  style={{
                    fontFamily: 'ui-monospace, monospace',
                    fontSize: 12,
                    wordBreak: 'break-all',
                    padding: '0 16px',
                  }}
                >
                  {token}
                </p>
              </div>
            )}
          </div>
          <button type="button" className="redeem-modal-cancel" onClick={closeModal}>
            取消核销
          </button>
        </div>
      </div>
    </div>
  );
}
