import { useCallback, useEffect, useRef, useState } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import { REDEEM_TOKEN_TTL_SECONDS } from '@dukang/shared-types';
import PageShell from '../../components/PageShell';
import RedeemQrCode from '../../components/RedeemQrCode';
import SubPageHeader from '../../components/SubPageHeader';
import { request, toast } from '../../lib/api';
import { formatMoney } from '../../lib/money';

const POLL_INTERVAL_MS = 2500;
const LAST_REDEEM_RECORD_KEY = 'lastRedeemRecordId';
const LAST_REDEEM_RESULT_KEY = 'lastRedeemResult';

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 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 RedeemCodePage() {
  const router = useRouter();
  const token = decodeURIComponent(router.params.token ?? '');
  const amount = Number(router.params.amount ?? 0);

  const [timerSec, setTimerSec] = useState(REDEEM_TOKEN_TTL_SECONDS);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const successHandled = useRef(false);
  const lastTokenTapAt = useRef(0);

  function onTokenTap() {
    if (!token) return;
    const now = Date.now();
    if (now - lastTokenTapAt.current < 350) {
      lastTokenTapAt.current = 0;
      void Taro.setClipboardData({ data: token })
        .then(() => toast('核销码编号已复制', 'success'))
        .catch(() => toast('复制失败'));
      return;
    }
    lastTokenTapAt.current = now;
  }

  const stopTimer = useCallback(() => {
    if (timerRef.current != null) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
  }, []);

  const handleRedeemExpired = useCallback(() => {
    if (successHandled.current) return;
    successHandled.current = true;
    stopTimer();
    toast('核销码已失效，请重新生成');
    setTimeout(() => {
      Taro.navigateBack();
    }, 1500);
  }, [stopTimer]);

  const handleRedeemSuccess = useCallback(
    (record: NonNullable<Extract<RedeemTokenStatus, { status: 'CONSUMED' }>['record']>) => {
      if (successHandled.current) return;
      successHandled.current = true;
      stopTimer();
      Taro.setStorageSync(LAST_REDEEM_RECORD_KEY, record.id);
      Taro.setStorageSync(LAST_REDEEM_RESULT_KEY, JSON.stringify(record));
      Taro.redirectTo({
        url: `/pages/redeem-success/index?amount=${record.amount}`,
      });
    },
    [stopTimer],
  );

  useEffect(() => {
    if (!token) {
      toast('核销码无效，请重新生成');
      Taro.navigateBack();
      return undefined;
    }

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

    return () => stopTimer();
  }, [token, stopTimer, handleRedeemExpired]);

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

    let cancelled = false;

    async function pollStatus() {
      try {
        const status = await request<RedeemTokenStatus>(`/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 = setInterval(() => void pollStatus(), POLL_INTERVAL_MS);
    return () => {
      cancelled = true;
      clearInterval(pollId);
    };
  }, [token, handleRedeemSuccess, handleRedeemExpired]);

  return (
    <PageShell variant="sub" className="redeem-code-page">
      <SubPageHeader title="核销码" />
      <View className="sub-page-body">
        <View className="redeem-code-panel">
          <Text className="redeem-code-head">请向收银员出示此码</Text>
          <View className="redeem-qr-wrap">
            <RedeemQrCode token={token} />
          </View>
          <View className={`redeem-timer${timerSec > 0 && timerSec < REDEEM_TOKEN_TTL_SECONDS ? ' redeem-timer--active' : ''}`}>
            <Text className="redeem-timer-value">{formatTimer(timerSec)}</Text>
            <Text className="redeem-timer-label">失效倒计时</Text>
          </View>
          <Text className="u-muted">待核销金额</Text>
          <Text className="redeem-code-amount">¥ {formatMoney(amount)}</Text>
          {token ? (
            <View className="redeem-code-token-wrap" onClick={onTokenTap}>
              <Text className="redeem-code-token-label">核销码编号（供追查）</Text>
              <Text className="redeem-code-token">{token}</Text>
              <Text className="redeem-code-token-hint">双击复制</Text>
            </View>
          ) : null}
        </View>
        <View className="redeem-cancel-btn" onClick={() => Taro.navigateBack()}>
          <Text>取消核销</Text>
        </View>
      </View>
    </PageShell>
  );
}
