import Taro from '@tarojs/taro';
import { useState, useEffect, useRef, useCallback } from 'react';
import { getRemainingSeconds, parseFlexibleEndTimeMs } from '../../../../../utils/Robotaxi-public-method';
import { getWaitTime, queryOrderFinishTime, cancelOrder, queryFareBreakdown } from '../../../../api/begin-route';

type Props = {
    tripStatus: number;
    orderId?: string;
    estimatedWaitMinutes?: number;
    finishCountdownEnabled: boolean;
    handleCancelTimeout?: () => void;
    handleFinishTimeout?: () => void;
    priceUpdateVersion?: number;
};

const PICKUP_END_TIME_KEY = 'pickupEndTime';
const FINISH_END_TIME_KEY = 'finishEndTime';

const getTargetOrderId = (orderId?: string) => orderId || Taro.getStorageSync('orderId');

export default function useTripCountdown({
    tripStatus,
    orderId,
    estimatedWaitMinutes,
    finishCountdownEnabled,
    handleCancelTimeout,
    handleFinishTimeout,
    priceUpdateVersion
}: Props) {
    const [waitMinutes, setWaitMinutes] = useState<number | null>(null);
    const [limitMinutes, setLimitMinutes] = useState<number | null>(null);
    const [pickupCountdownSeconds, setPickupCountdownSeconds] = useState<number | null>(null);
    const [finishCountdownSeconds, setFinishCountdownSeconds] = useState<number | null>(null);
    const [fareBreakdown, setFareBreakdown] = useState<any>(null);

    const pickupTimerRef = useRef<any>(null);
    const finishTimerRef = useRef<any>(null);
    const countdownFinishedRef = useRef(false);
    const pickupTripStatusRef = useRef(tripStatus);
    const pickupEndTimeRef = useRef<number | null>(null);
    const finishEndTimeRef = useRef<number | null>(null);
    const lastFareOrderIdRef = useRef<string | null>(null);

    const requestFareBreakdown = useCallback((force = false) => {
        const targetOrderId = getTargetOrderId(orderId);
        if (!targetOrderId) return;
        if (!force && lastFareOrderIdRef.current === targetOrderId) return;
        lastFareOrderIdRef.current = targetOrderId;
        queryFareBreakdown(targetOrderId).then((res: any) => {
            setFareBreakdown(res?.data ?? res?.result ?? res);
        }).catch(() => { });
    }, [orderId]);

    const clearPickupTimer = useCallback(() => {
        if (pickupTimerRef.current) {
            clearTimeout(pickupTimerRef.current);
            pickupTimerRef.current = null;
        }
    }, []);

    const clearFinishTimer = useCallback(() => {
        if (finishTimerRef.current) {
            clearTimeout(finishTimerRef.current);
            finishTimerRef.current = null;
        }
    }, []);

    const scheduleAlignedTick = (endMs: number, runner: () => void) => {
        const now = Date.now();
        const diffMs = endMs - now;
        const delay = diffMs > 0 ? (diffMs % 1000 || 1000) : 1000;
        return setTimeout(runner, delay);
    };

    useEffect(() => {
        if (typeof priceUpdateVersion === 'number' && priceUpdateVersion > 0 && [8, 9].includes(tripStatus)) {
            requestFareBreakdown(true);
        }
    }, [priceUpdateVersion, tripStatus, requestFareBreakdown]);

    useEffect(() => {
        let active = true;
        if (tripStatus !== 3) return () => { active = false; };
        if (typeof estimatedWaitMinutes === 'number' && !Number.isNaN(estimatedWaitMinutes)) {
            setWaitMinutes(estimatedWaitMinutes);
            return () => { active = false; };
        }
        const startSite = Taro.getStorageSync('startSite');
        getWaitTime({ latitude: startSite?.latitude, longitude: startSite?.longitude })
            .then((res) => {
                const minutes = Number(res);
                if (active && !Number.isNaN(minutes)) {
                    setWaitMinutes(minutes);
                }
            })
            .catch(() => { });
        return () => {
            active = false;
        };
    }, [tripStatus, estimatedWaitMinutes]);

    useEffect(() => {
        if (tripStatus !== 4) return;
        const startSite = Taro.getStorageSync('startSite');
        const time = Number(startSite?.time);
        if (!Number.isNaN(time)) {
            setLimitMinutes(time);
        }
    }, [tripStatus]);

    useEffect(() => {
        pickupTripStatusRef.current = tripStatus;
    }, [tripStatus]);

    useEffect(() => {
        if (tripStatus !== 5) {
            clearPickupTimer();
            return;
        }

        const runPickupTick = () => {
            // 防止状态已切换后，旧定时回调仍触发取消逻辑
            if (pickupTripStatusRef.current !== 5) {
                clearPickupTimer();
                return;
            }
            const remaining = getRemainingSeconds(pickupEndTimeRef.current);
            if (remaining !== null && remaining <= 0) {
                if (!countdownFinishedRef.current) {
                    countdownFinishedRef.current = true;
                    const targetOrderId = getTargetOrderId(orderId);
                    if (targetOrderId) {
                        cancelOrder(targetOrderId).finally(() => {
                            Taro.removeStorageSync(PICKUP_END_TIME_KEY);
                            handleCancelTimeout?.();
                        });
                    } else {
                        Taro.removeStorageSync(PICKUP_END_TIME_KEY);
                        handleCancelTimeout?.();
                    }
                }
                clearPickupTimer();
                setPickupCountdownSeconds(0);
                return;
            }
            setPickupCountdownSeconds(remaining);
            if (!pickupEndTimeRef.current) return;
            pickupTimerRef.current = scheduleAlignedTick(pickupEndTimeRef.current, runPickupTick);
        };

        const startSite = Taro.getStorageSync('startSite');
        const limitMin = Number(startSite?.time);
        const cachedEndTime = Taro.getStorageSync(PICKUP_END_TIME_KEY);
        const hasValidCached = typeof cachedEndTime === 'number' && cachedEndTime > Date.now();

        if (hasValidCached) {
            pickupEndTimeRef.current = cachedEndTime;
        } else if (!Number.isNaN(limitMin) && limitMin > 0) {
            pickupEndTimeRef.current = Date.now() + limitMin * 60 * 1000;
            Taro.setStorageSync(PICKUP_END_TIME_KEY, pickupEndTimeRef.current);
        } else {
            pickupEndTimeRef.current = null;
        }

        if (!pickupEndTimeRef.current) {
            setPickupCountdownSeconds(null);
            return;
        }

        countdownFinishedRef.current = false;
        setPickupCountdownSeconds(getRemainingSeconds(pickupEndTimeRef.current));
        clearPickupTimer();
        runPickupTick();

        return () => {
            clearPickupTimer();
        };
    }, [tripStatus, orderId, handleCancelTimeout, clearPickupTimer]);

    useEffect(() => {
        if (tripStatus !== 7) {
            clearFinishTimer();
            return;
        }

        const runFinishTick = () => {
            const remaining = getRemainingSeconds(finishEndTimeRef.current);
            if (remaining !== null && remaining <= 0) {
                clearFinishTimer();
                setFinishCountdownSeconds(0);
                Taro.removeStorageSync(FINISH_END_TIME_KEY);
                handleFinishTimeout?.();
                return;
            }
            setFinishCountdownSeconds(remaining);
            if (!finishEndTimeRef.current) return;
            finishTimerRef.current = scheduleAlignedTick(finishEndTimeRef.current, runFinishTick);
        };

        const initCountdown = (endTimeMs: number | null) => {
            finishEndTimeRef.current = endTimeMs;
            if (typeof endTimeMs === 'number' && endTimeMs > Date.now()) {
                Taro.setStorageSync(FINISH_END_TIME_KEY, endTimeMs);
            } else {
                Taro.removeStorageSync(FINISH_END_TIME_KEY);
            }
            const remaining = getRemainingSeconds(endTimeMs);
            if (remaining === null) {
                setFinishCountdownSeconds(null);
                return;
            }
            setFinishCountdownSeconds(remaining);
            clearFinishTimer();
            runFinishTick();
        };

        const cachedEndTime = Taro.getStorageSync(FINISH_END_TIME_KEY);
        const hasValidCached = typeof cachedEndTime === 'number' && cachedEndTime > Date.now();
        if (hasValidCached) {
            initCountdown(cachedEndTime);
        } else {
            queryOrderFinishTime().then((res: any) => {
                initCountdown(parseFlexibleEndTimeMs(res));
            }).catch(() => {
                setFinishCountdownSeconds(null);
                finishEndTimeRef.current = null;
                Taro.removeStorageSync(FINISH_END_TIME_KEY);
            });
        }

        return () => {
            if (typeof finishEndTimeRef.current === 'number' && finishEndTimeRef.current > Date.now()) {
                Taro.setStorageSync(FINISH_END_TIME_KEY, finishEndTimeRef.current);
            }
            clearFinishTimer();
        };
    }, [tripStatus, handleFinishTimeout, finishCountdownEnabled, clearFinishTimer]);

    useEffect(() => {
        if ([8, 9].includes(tripStatus)) {
            Taro.removeStorageSync(FINISH_END_TIME_KEY);
            requestFareBreakdown();
        }
    }, [tripStatus, requestFareBreakdown]);

    return {
        waitMinutes,
        limitMinutes,
        pickupCountdownSeconds,
        finishCountdownSeconds,
        fareBreakdown
    };
}
