'use client';

import { useEffect, useRef, useState, useCallback } from 'react';

interface GoogleMapProps {
  siteLocation: {
    lat: number;
    lng: number;
    radius: number;
    name: string;
  };
  onDistanceChange?: (distance: number, isInRange: boolean, userLocation?: { lat: number; lng: number }) => void;
}

// Window에 initGoogleMap 콜백 추가
declare global {
  interface Window {
    initGoogleMap?: () => void;
    googleMapsLoading?: boolean;
  }
}

export default function GoogleMap({ siteLocation, onDistanceChange }: GoogleMapProps) {
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<google.maps.Map | null>(null);
  const markerRef = useRef<google.maps.Marker | null>(null);
  const circleRef = useRef<google.maps.Circle | null>(null);
  const [mounted, setMounted] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 클라이언트 마운트 확인
  useEffect(() => {
    setMounted(true);
  }, []);

  // 거리 계산 함수 (Haversine formula)
  const calculateDistance = useCallback(
    (lat1: number, lon1: number, lat2: number, lon2: number): number => {
      const R = 6371000; // 지구 반지름 (미터)
      const dLat = toRad(lat2 - lat1);
      const dLon = toRad(lon2 - lon1);
      const a =
        Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(toRad(lat1)) *
          Math.cos(toRad(lat2)) *
          Math.sin(dLon / 2) *
          Math.sin(dLon / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      return R * c;
    },
    []
  );

  // 구글맵 스크립트 로드 (마운트 후에만)
  useEffect(() => {
    if (!mounted) return;

    const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY;


    if (!apiKey) {
      setError('구글맵 API 키가 설정되지 않았습니다.');
      return;
    }

    // 이미 로드된 경우
    if (window.google && window.google.maps) {
      setIsLoaded(true);
      return;
    }

    // 로딩 중인 경우 (중복 로드 방지)
    if (window.googleMapsLoading) {
      // 로딩 완료 대기
      const checkLoaded = setInterval(() => {
        if (window.google && window.google.maps) {
          clearInterval(checkLoaded);
          setIsLoaded(true);
        }
      }, 100);
      return () => clearInterval(checkLoaded);
    }

    // 기존 스크립트 태그 확인 (중복 방지)
    const existingScript = document.querySelector('script[src*="maps.googleapis.com"]');
    if (existingScript) {
      const checkLoaded = setInterval(() => {
        if (window.google && window.google.maps) {
          clearInterval(checkLoaded);
          setIsLoaded(true);
        }
      }, 100);
      return () => clearInterval(checkLoaded);
    }

    // 로딩 시작 플래그
    window.googleMapsLoading = true;

    // 콜백 함수 등록
    window.initGoogleMap = () => {
      window.googleMapsLoading = false;
      setIsLoaded(true);
    };

    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initGoogleMap`;
    script.async = true;
    script.defer = true;

    script.onerror = (e) => {
      console.error('[GoogleMap] 스크립트 로드 실패:', e);
      window.googleMapsLoading = false;
      setError('구글맵 스크립트 로드 실패');
    };

    document.head.appendChild(script);

    return () => {
      // cleanup - 스크립트는 제거하지 않음 (다른 컴포넌트에서 사용 가능)
    };
  }, [mounted]);

  // 지도 초기화
  useEffect(() => {
    if (!isLoaded || !mapRef.current || !window.google) return;

    // 좌표 유효성 검사 - 우림블루나인비즈니스센터 기본값 (강서구 염창동)
    const lat = typeof siteLocation.lat === 'number' && !isNaN(siteLocation.lat) ? siteLocation.lat : 37.5458;
    const lng = typeof siteLocation.lng === 'number' && !isNaN(siteLocation.lng) ? siteLocation.lng : 126.8718;


    const map = new window.google.maps.Map(mapRef.current, {
      center: { lat, lng },
      zoom: 17,
      disableDefaultUI: true,
      zoomControl: true,
      mapTypeControl: false,
      streetViewControl: false,
      fullscreenControl: false,
    });

    mapInstanceRef.current = map;

    // radius 유효성 검사
    const radius = typeof siteLocation.radius === 'number' && siteLocation.radius > 0 ? siteLocation.radius : 100;

    // 반경 원 그리기 (파란색)
    const circle = new window.google.maps.Circle({
      map: map,
      center: { lat, lng },
      radius: radius,
      strokeColor: '#3B82F6',
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: '#3B82F6',
      fillOpacity: 0.15,
    });

    circleRef.current = circle;

    // 현장 중심 마커 (파란색)
    new window.google.maps.Marker({
      map: map,
      position: { lat, lng },
      icon: {
        path: window.google.maps.SymbolPath.CIRCLE,
        scale: 8,
        fillColor: '#3B82F6',
        fillOpacity: 1,
        strokeColor: '#FFFFFF',
        strokeWeight: 2,
      },
    });

  }, [isLoaded, siteLocation]);

  // GPS 위치 추적
  useEffect(() => {
    if (!isLoaded || !mapInstanceRef.current || !window.google) return;

    if (!navigator.geolocation) {
      setError('GPS를 지원하지 않는 브라우저입니다.');
      return;
    }


    // 위치 업데이트 핸들러
    const handlePositionUpdate = (latitude: number, longitude: number) => {

      // 기존 마커 제거
      if (markerRef.current) {
        markerRef.current.setMap(null);
      }

      // 내 위치 마커 생성 (빨간색)
      const marker = new window.google.maps.Marker({
        map: mapInstanceRef.current!,
        position: { lat: latitude, lng: longitude },
        icon: {
          path: window.google.maps.SymbolPath.CIRCLE,
          scale: 10,
          fillColor: '#EF4444',
          fillOpacity: 1,
          strokeColor: '#FFFFFF',
          strokeWeight: 2,
        },
      });

      markerRef.current = marker;

      // 거리 계산
      const distance = calculateDistance(
        latitude,
        longitude,
        siteLocation.lat,
        siteLocation.lng
      );

      const isInRange = distance <= siteLocation.radius;

      if (onDistanceChange) {
        onDistanceChange(distance, isInRange, { lat: latitude, lng: longitude });
      }
    };

    const watchId = navigator.geolocation.watchPosition(
      (position) => {
        const { latitude, longitude } = position.coords;
        handlePositionUpdate(latitude, longitude);
      },
      (err) => {
        console.error('[GoogleMap] GPS 오류 코드:', err.code, '메시지:', err.message);

        // 개발 환경 체크 (localhost, 127.0.0.1, 또는 NODE_ENV=development)
        const hostname = window.location.hostname;
        const isDevelopment =
          hostname === 'localhost' ||
          hostname === '127.0.0.1' ||
          hostname.startsWith('192.168.') ||
          hostname === 'dev.sam.kr' ||
          hostname === 'dev.codebridge-x.com' ||
          process.env.NODE_ENV === 'development';


        // 개발 환경에서 GPS 실패 시 테스트 위치로 시뮬레이션
        if (isDevelopment) {
          // 본사 좌표에서 약간 떨어진 위치 (약 50m)
          const testLat = siteLocation.lat + 0.0003;
          const testLng = siteLocation.lng + 0.0003;
          handlePositionUpdate(testLat, testLng);
          return;
        }

        if (err.code === 1) {
          setError('위치 권한이 거부되었습니다. 설정에서 위치 권한을 허용해주세요.');
        } else if (err.code === 2) {
          setError('위치를 확인할 수 없습니다.');
        } else {
          setError('위치 확인 시간이 초과되었습니다.');
        }
      },
      {
        enableHighAccuracy: true,
        timeout: 15000,
        maximumAge: 5000,
      }
    );

    return () => {
      navigator.geolocation.clearWatch(watchId);
    };
  }, [isLoaded, siteLocation, onDistanceChange, calculateDistance]);

  // 마운트 전 또는 로딩 중일 때 로딩 UI 표시
  if (!mounted || !isLoaded) {
    return (
      <div className="w-full h-full flex items-center justify-center bg-gray-100 rounded-xl">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto mb-2"></div>
          <p className="text-gray-500 text-sm">지도 로딩 중...</p>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="w-full h-full flex items-center justify-center bg-gray-100 rounded-xl">
        <div className="text-center p-4">
          <p className="text-red-500 text-sm">{error}</p>
        </div>
      </div>
    );
  }

  return (
    <div
      ref={mapRef}
      className="w-full h-full rounded-xl overflow-hidden"
      style={{ minHeight: '300px' }}
    />
  );
}

function toRad(deg: number): number {
  return deg * (Math.PI / 180);
}
