import Taro from '@tarojs/taro';
import { useEffect, useRef, useState } from 'react';

type Deps = {
  tripStatus: number;
  statusRule: any;
  isAndroid: boolean;
  startSite: any;
  endSite: any;
  vehicleLocation: { latitude: number; longitude: number } | null;
  vehicleDirection: number | null;
  vehicleMarkerId: number;
  arrivedMarkerReady: boolean;
  arrivedTooltipReady: boolean;
};

const defaultDeps: Deps = {
  tripStatus: 1,
  statusRule: { showPickup: true, showDropoff: true, showCar: false },
  isAndroid: false,
  startSite: null,
  endSite: null,
  vehicleLocation: null,
  vehicleDirection: null,
  vehicleMarkerId: 3,
  arrivedMarkerReady: false,
  arrivedTooltipReady: false
};

export default function useMapMarkers(rawDeps?: Partial<Deps>) {
  const deps = { ...defaultDeps, ...(rawDeps || {}) } as Deps;
  // 地图 marker 集合
  const [markers, setMarkers] = useState<any[]>([]);
  const markersRef = useRef<any[]>([]);
  const markersSignatureRef = useRef<string>('');
  const carMarkerInitialized = useRef(false);
  const tripStatus6MarkerRefreshedRef = useRef(false);

  // 构建上车点 marker
  const createPickupMarker = (pickupSite: any, useAndroidNativeTrip1Callout: boolean) => {
    if (!(pickupSite?.latitude && pickupSite?.longitude)) return null;
    return {
      id: 1,
      latitude: pickupSite.latitude,
      longitude: pickupSite.longitude,
      iconPath: 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-up.png',
      width: 22,
      height: 40,
      anchor: { x: 0.5, y: 1 },
      zIndex: 1,
      name: pickupSite?.name || '上车点',
      ...(useAndroidNativeTrip1Callout
        ? {
          callout: {
            content: deps.tripStatus === 1 ? `${pickupSite?.name || '上车点'} >` : (pickupSite?.name || '上车点'),
            color: '#000000',
            fontSize: 12,
            bgColor: '#FFFFFF',
            borderRadius: 8,
            padding: 8,
            display: 'ALWAYS',
            textAlign: 'center',
          },
        }
        : {
          customCallout: { anchorY: [2, 3].includes(deps.tripStatus) ? 150 : -5, anchorX: 0, display: 'ALWAYS' },
        })
    };
  };

  // 构建下车点 marker
  const createDropoffMarker = (dropoffSite: any, useAndroidNativeTrip1Callout: boolean) => {
    if (!(dropoffSite?.latitude && dropoffSite?.longitude)) return null;
    const dropoffName = [7].includes(deps.tripStatus) ? '已到达' : (dropoffSite.name || '目的地');
    return {
      id: 2,
      latitude: dropoffSite.latitude,
      longitude: dropoffSite.longitude,
      iconPath: 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/maker-down.png',
      width: 22,
      height: 40,
      anchor: { x: 0.5, y: 1 },
      zIndex: 1,
      name: dropoffName,
      ...(useAndroidNativeTrip1Callout || deps.tripStatus == 6
        ? {
          callout: {
            content: deps.tripStatus === 1 ? `${dropoffName} >` : dropoffName,
            color: '#000000',
            fontSize: 12,
            bgColor: '#FFFFFF',
            borderRadius: 8,
            padding: 8,
            display: 'ALWAYS',
            textAlign: 'center',
          },
        }
        : {
          customCallout: { anchorY: -5, anchorX: 0, display: 'ALWAYS' },
        })
    };
  };

  // 构建车辆 marker
  const createCarMarker = () => {
    if (!deps.vehicleLocation) return null;
    return {
      id: deps.vehicleMarkerId,
      latitude: deps.vehicleLocation.latitude,
      longitude: deps.vehicleLocation.longitude,
      iconPath: 'https://s.xiaopeng.com/xp-fe/robot-taxi/imgs/marker-car.png',
      width: 20,
      height: 40,
      anchor: { x: 0.5, y: 0.5 },
      zIndex: 2,
      rotate: typeof deps.vehicleDirection === 'number' ? deps.vehicleDirection : 0,
      name: '车辆位置',
      customCallout: { anchorY: 70, anchorX: 0, display: 'ALWAYS' }
    };
  };

  // 应用 marker 状态并处理状态6刷新标记
  const applyMarkerState = (nextMarkers: any[], nextMarkersSignature: string, shouldSkipUpdate: boolean, carMarker: any) => {
    if (shouldSkipUpdate) {
      // 跳过整包 markers 更新时，仍兜底同步车辆 marker 位置与角度，避免朝向卡旧值
      setMarkers((prevMarkers: any[]) => {
        const targetCarIndex = prevMarkers.findIndex((item: any) => item.id === deps.vehicleMarkerId);
        if (targetCarIndex === -1) {
          if (markersSignatureRef.current !== nextMarkersSignature) {
            markersSignatureRef.current = nextMarkersSignature;
            return nextMarkers;
          }
          return prevMarkers;
        }
        const prevCar = prevMarkers[targetCarIndex] || {};
        const nextCarRotate = typeof carMarker?.rotate === 'number' ? carMarker.rotate : prevCar.rotate;
        const carLocationChanged =
          Number(prevCar.latitude) !== Number(carMarker?.latitude) ||
          Number(prevCar.longitude) !== Number(carMarker?.longitude);
        const carRotateChanged = Number(prevCar.rotate) !== Number(nextCarRotate);
        if (!carLocationChanged && !carRotateChanged) {
          return prevMarkers;
        }
        const next = [...prevMarkers];
        next[targetCarIndex] = {
          ...prevCar,
          latitude: carMarker?.latitude,
          longitude: carMarker?.longitude,
          rotate: nextCarRotate
        };
        return next;
      });
    }
    if (!shouldSkipUpdate && markersSignatureRef.current !== nextMarkersSignature) {
      markersSignatureRef.current = nextMarkersSignature;
      setMarkers(nextMarkers);
    }
    if (!deps.isAndroid && deps.tripStatus === 6 && deps.statusRule.showCar && !!carMarker && !tripStatus6MarkerRefreshedRef.current) {
      tripStatus6MarkerRefreshedRef.current = true;
    }
    carMarkerInitialized.current = deps.statusRule.showCar && !!carMarker;
  };

  useEffect(() => {
    markersRef.current = markers;
  }, [markers]);

  useEffect(() => {
    const pickupSite = deps.startSite?.latitude && deps.startSite?.longitude ? deps.startSite : Taro.getStorageSync('startSite');
    const dropoffSite = deps.endSite?.latitude && deps.endSite?.longitude ? deps.endSite : Taro.getStorageSync('endSite');
    const useAndroidNativeTrip1Callout = deps.isAndroid && [1, 5, 8, 9, 10].includes(deps.tripStatus);
    const pickupMarker = createPickupMarker(pickupSite, useAndroidNativeTrip1Callout);
    const dropoffMarker = createDropoffMarker(dropoffSite, useAndroidNativeTrip1Callout);
    const shouldWaitArrivedDirection = deps.tripStatus === 7 && !deps.arrivedMarkerReady;
    const effectiveShowCar = deps.statusRule.showCar && !shouldWaitArrivedDirection;
    const carMarker = createCarMarker();
    const nextMarkers: any[] = [];
    if (deps.statusRule.showPickup && pickupMarker) nextMarkers.push(pickupMarker);
    if (effectiveShowCar && carMarker) nextMarkers.push(carMarker);
    if (deps.statusRule.showDropoff && dropoffMarker) nextMarkers.push(dropoffMarker);
    const nextMarkersSignature = nextMarkers
      .map((m: any) => [
        m.id,
        Number(m.latitude).toFixed(6),
        Number(m.longitude).toFixed(6),
        m.name || '',
        typeof m.rotate === 'number' ? m.rotate : '',
        m?.customCallout?.anchorY ?? '',
      ].join('|'))
      .join(';');
    const hasDropoffMarker = markersRef.current.some((m: any) => m.id === 2);
    const shouldHoldMarkerByTranslate = [4, 6].includes(deps.tripStatus) && carMarkerInitialized.current && deps.statusRule.showCar && (!deps.statusRule.showDropoff || hasDropoffMarker);
    const shouldSkipUpdate = shouldHoldMarkerByTranslate && (deps.isAndroid || tripStatus6MarkerRefreshedRef.current);
    applyMarkerState(nextMarkers, nextMarkersSignature, shouldSkipUpdate, carMarker);
  }, [deps.tripStatus, deps.startSite?.name, deps.startSite?.latitude, deps.startSite?.longitude, deps.endSite?.name, deps.endSite?.latitude, deps.endSite?.longitude, deps.vehicleLocation, deps.vehicleDirection, deps.vehicleMarkerId, deps.isAndroid, deps.statusRule.showPickup, deps.statusRule.showCar, deps.statusRule.showDropoff]);

  return {
    markers,
    setMarkers,
    markersRef,
    markersSignatureRef,
    carMarkerInitialized,
    tripStatus6MarkerRefreshedRef
  };
}
