import Taro from '@tarojs/taro';
import { useEffect, useMemo, useRef, useState } from 'react';
import { getStartPoints, getEndPoints, queryPointByName } from '../../../api/site-search';
import { checkOtp } from '../../../../utils/tools';
import { getNearestSite } from '../../../api/home';
import { _AMAP_KEY } from '../../../../constants/api';
import amapFile from '../../../../libs/amap-wx.130.js';
import { normalizeSiteItem, sortSitesByNameMatchAndDistance } from '../utils/site-search';

type Deps = {
  // 路由参数对象
  router: any;
  // 搜索关键字
  searchValue: string;
  // 推荐列表最大返回数
  maxExpandedCount: number;
  // 非运营列表最大返回数
  maxShowCount: number;
};

export default function useSiteSearch(deps: Deps) {
  // 推荐站点列表
  const [siteList, setSiteList] = useState<any[]>([]);
  // 历史站点列表
  const [historySite, setHistorySite] = useState<any[]>([]);
  // 非运营区域站点列表
  const [nonOperationalSite, setNonOperationalSite] = useState<any[]>([]);
  // 附近站点列表
  const [nearbySiteList, setNearbySiteList] = useState<any[]>([]);
  // 页面类型（start/end）
  const [pageType, setPageType] = useState('');
  // 当前关键词是否仍在搜索中（含高德补充结果）
  const [isSearching, setIsSearching] = useState(false);
  // 最近一次完成搜索的关键词
  const [lastCompletedKeyword, setLastCompletedKeyword] = useState('');
  // 初始化数据是否已完成加载
  const [isInitLoaded, setIsInitLoaded] = useState(false);
  const searchSeqRef = useRef(0);
  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const pendingSearchValueRef = useRef('');

  // 拉取附近站点
  const fetchNearbySites = async (
    lat: number,
    lon: number,
    electronicAreaId?: string,
    canUpdate?: () => boolean
  ) => {
    const selectedCity = Taro.getStorageSync('selectedCity');
    try {
      const res = await getNearestSite({
        cityCode: selectedCity?.code || '',
        latitude: Number(lat),
        longitude: Number(lon),
        electronicAreaId
      });
      if (canUpdate && !canUpdate()) {
        return;
      }
      const points = Array.isArray(res?.points) ? res.points : [];
      setNearbySiteList(points.map(normalizeSiteItem));
    } catch {
      if (canUpdate && !canUpdate()) {
        return;
      }
      setNearbySiteList([]);
    }
  };

  // 站点搜索请求与结果处理
  const searchSite = async (val?: string) => {
    const queryVal = val !== undefined ? val : deps.searchValue;
    const normalizedQuery = String(queryVal || '').trim();
    searchSeqRef.current += 1;
    const requestSeq = searchSeqRef.current;
    setNonOperationalSite([]);
    if (!normalizedQuery) {
      setIsSearching(false);
      setLastCompletedKeyword('');
      return;
    }
    setIsSearching(true);
    const { latitude, longitude, electronicAreaId } = deps.router.params;
    const selectedCity = Taro.getStorageSync('selectedCity');
    const payload = {
      cityCode: selectedCity?.code || '',
      electronicAreaId: electronicAreaId ? Number(electronicAreaId) : 0,
      lat: Number(latitude),
      lon: Number(longitude),
      pointPoi: normalizedQuery
    };
    try {
      const res = await queryPointByName(payload);
      if (requestSeq !== searchSeqRef.current) return;
      const { availablePoints } = res;
      if (Array.isArray(availablePoints)) {
        const list = availablePoints.map(normalizeSiteItem);
        const sorted = sortSitesByNameMatchAndDistance(list, normalizedQuery);
        setSiteList(sorted.slice(0, deps.maxExpandedCount));
      } else {
        setSiteList([]);
      }
      const myAmapFun = new amapFile.AMapWX({ key: _AMAP_KEY });
      await new Promise<void>((resolve) => {
        myAmapFun.getPoiAround({
          querykeywords: normalizedQuery,
          location: `${longitude},${latitude}`,
          success: (data: any) => {
            if (requestSeq !== searchSeqRef.current) {
              resolve();
              return;
            }
            if (data && data.poisData) {
              const list = data.poisData.map((item: any) => {
                const locationArr = item.location.split(',');
                return {
                  ...item,
                  longitude: Number(locationArr[0]),
                  latitude: Number(locationArr[1]),
                  ...normalizeSiteItem(item)
                };
              });
              const sorted = sortSitesByNameMatchAndDistance(list, normalizedQuery);
              setNonOperationalSite(sorted.slice(0, deps.maxShowCount));
            } else {
              setNonOperationalSite([]);
            }
            resolve();
          },
          fail: () => {
            if (requestSeq === searchSeqRef.current) {
              setNonOperationalSite([]);
            }
            resolve();
          }
        });
      });
    } catch {
      if (requestSeq !== searchSeqRef.current) return;
      setSiteList([]);
      setNonOperationalSite([]);
    } finally {
      if (requestSeq === searchSeqRef.current) {
        setIsSearching(false);
        setLastCompletedKeyword(normalizedQuery);
      }
    }
  };

  const searchSiteRef = useRef(searchSite);
  searchSiteRef.current = searchSite;

  // 搜索输入防抖
  const debouncedSearch = useMemo(() => {
    return (val: string) => {
      pendingSearchValueRef.current = val;
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
      debounceTimerRef.current = setTimeout(() => {
        debounceTimerRef.current = null;
        searchSiteRef.current(val);
      }, 300);
    };
  }, []);

  // 取消搜索输入防抖定时器
  const cancelDebouncedSearch = () => {
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
      debounceTimerRef.current = null;
    }
    pendingSearchValueRef.current = '';
  };

  // 立即执行待触发的防抖搜索
  const flushDebouncedSearch = () => {
    if (!debounceTimerRef.current) {
      return;
    }
    const pendingValue = pendingSearchValueRef.current;
    clearTimeout(debounceTimerRef.current);
    debounceTimerRef.current = null;
    pendingSearchValueRef.current = '';
    searchSiteRef.current(pendingValue);
  };

  // 确认搜索：优先使用显式关键字，其次使用防抖待执行关键字，最后回退到当前输入值
  const confirmSearch = (val?: string) => {
    const explicitValue = typeof val === 'string' ? val : '';
    const pendingValue = pendingSearchValueRef.current;
    const fallbackValue = deps.searchValue;
    const targetValue = explicitValue || pendingValue || fallbackValue || '';
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
      debounceTimerRef.current = null;
    }
    pendingSearchValueRef.current = '';
    searchSiteRef.current(targetValue);
  };

  // 清空搜索结果列表
  const clearSearchResults = () => {
    cancelDebouncedSearch();
    // 推进请求序号，使清空前已发出的请求结果失效
    searchSeqRef.current += 1;
    setSiteList([]);
    setNonOperationalSite([]);
    setIsSearching(false);
    setLastCompletedKeyword('');
  };

  useEffect(() => {
    return () => {
      cancelDebouncedSearch();
    };
  }, []);

  // 初始化：拉取附近站点、历史记录、页面类型
  useEffect(() => {
    let isUnmounted = false;
    const initPageData = async () => {
      const { pageType: type, latitude: lat, longitude: lon, electronicAreaId } = deps.router.params;
      const initTasks: Promise<unknown>[] = [];
      if (lat && lon) {
        initTasks.push(
          fetchNearbySites(
            Number(lat),
            Number(lon),
            electronicAreaId,
            () => !isUnmounted
          )
        );
      }
      initTasks.push((async () => {
        try {
          const otp = await checkOtp(false);
          if (!otp || !lat || !lon) {
            return;
          }
          const payload = { lat: Number(lat), lon: Number(lon), electronicAreaId };
          const res = type === 'start'
            ? await getStartPoints(payload)
            : type === 'end'
              ? await getEndPoints(payload)
              : [];
          if (Array.isArray(res) && !isUnmounted) {
            setHistorySite(res.map(normalizeSiteItem));
          }
        } catch { }
      })());
      if (type) {
        setPageType(type);
      }
      await Promise.allSettled(initTasks);
      if (!isUnmounted) {
        setIsInitLoaded(true);
      }
    };
    initPageData();
    return () => {
      isUnmounted = true;
    };
  }, []);

  return {
    pageType,
    siteList,
    historySite,
    nonOperationalSite,
    nearbySiteList,
    isSearching,
    lastCompletedKeyword,
    isInitLoaded,
    searchSite,
    debouncedSearch,
    cancelDebouncedSearch,
    flushDebouncedSearch,
    confirmSearch,
    clearSearchResults
  };
}
