import axios from 'axios';

// API Key를 환경변수에서 로드 (소스코드 노출 방지)
const AIS_API_KEY = import.meta.env.VITE_AIS_API_KEY || '';
const AIS_BASE_URL = import.meta.env.VITE_AIS_API_URL || 'https://ais-api.spgi.kr/api/v1';

// 선박 위치 데이터 타입
export interface VesselPosition {
  mmsi: string; // Maritime Mobile Service Identity
  imo?: string; // International Maritime Organization number
  shipName: string; // 선박명
  callSign?: string; // 호출부호
  shipType: number; // 선박 유형 코드
  shipTypeText?: string; // 선박 유형 (한글)
  latitude: number; // 위도
  longitude: number; // 경도
  speed: number; // 속도 (노트)
  course: number; // 침로 (0-359도)
  heading: number; // 선수방위
  navStatus: number; // 항해 상태 코드
  navStatusText?: string; // 항해 상태 (한글)
  timestamp: string; // 데이터 수신 시각
  destination?: string; // 목적지
  eta?: string; // 예정 도착 시각
  draught?: number; // 흘수 (미터)
  length?: number; // 전장 (미터)
  width?: number; // 폭 (미터)
}

// 영역 내 선박 조회 파라미터
export interface BoundingBox {
  minLat: number; // 최소 위도
  maxLat: number; // 최대 위도
  minLng: number; // 최소 경도
  maxLng: number; // 최대 경도
}

// 선박 유형 코드 → 텍스트 변환
export function getShipTypeText(code: number): string {
  const types: { [key: number]: string } = {
    0: '미상',
    30: '어선',
    31: '예인선',
    32: '예인선',
    33: '준설선',
    34: '잠수작업선',
    35: '군사작전선',
    36: '범선',
    37: '레저선',
    50: '도선선',
    51: '구조선',
    52: '예인선',
    53: '항만선',
    54: '오염방지선',
    55: '법집행선',
    60: '여객선',
    61: '여객선',
    62: '여객선',
    63: '여객선',
    64: '여객선',
    65: '여객선',
    66: '여객선',
    67: '여객선',
    68: '여객선',
    69: '여객선',
    70: '화물선',
    71: '화물선',
    72: '화물선',
    73: '화물선',
    74: '화물선',
    75: '화물선',
    76: '화물선',
    77: '화물선',
    78: '화물선',
    79: '화물선',
    80: '유조선',
    81: '유조선',
    82: '유조선',
    83: '유조선',
    84: '유조선',
    85: '유조선',
    86: '유조선',
    87: '유조선',
    88: '유조선',
    89: '유조선',
    90: '기타선박',
  };
  return types[code] || `선박(${code})`;
}

// 항해 상태 코드 → 텍스트 변환
export function getNavStatusText(code: number): string {
  const statuses: { [key: number]: string } = {
    0: '기관 사용 항해중',
    1: '정박중',
    2: '조종 불능',
    3: '조종 제한',
    4: '흘수 제약',
    5: '계류중',
    6: '좌초',
    7: '어로중',
    8: '범주 항해중',
    9: '예약',
    10: '예약',
    11: '예약',
    12: '예약',
    13: '예약',
    14: '예약',
    15: '미정의',
  };
  return statuses[code] || '알 수 없음';
}

// 1. 특정 선박 위치 조회 (MMSI 기반)
export async function getVesselByMMSI(mmsi: string): Promise<VesselPosition | null> {
  try {
    const response = await axios.get(`${AIS_BASE_URL}/vessel/${mmsi}`, {
      headers: {
        Authorization: `Bearer ${AIS_API_KEY}`,
        'Content-Type': 'application/json',
      },
    });

    const data = response.data;
    return {
      ...data,
      shipTypeText: getShipTypeText(data.shipType),
      navStatusText: getNavStatusText(data.navStatus),
    };
  } catch (error) {
    console.error(`선박 조회 오류 (MMSI: ${mmsi}):`, error);
    return null;
  }
}

// 2. 영역 내 모든 선박 조회 (Bounding Box)
export async function getVesselsInArea(bbox: BoundingBox): Promise<VesselPosition[]> {
  try {
    const response = await axios.get(`${AIS_BASE_URL}/vessels/area`, {
      headers: {
        Authorization: `Bearer ${AIS_API_KEY}`,
        'Content-Type': 'application/json',
      },
      params: {
        minLat: bbox.minLat,
        maxLat: bbox.maxLat,
        minLng: bbox.minLng,
        maxLng: bbox.maxLng,
      },
    });

    return response.data.map((vessel: Record<string, unknown>) => ({
      ...vessel,
      shipTypeText: getShipTypeText(vessel.shipType as number),
      navStatusText: getNavStatusText(vessel.navStatus as number),
    }));
  } catch (error) {
    console.error('영역 내 선박 조회 오류:', error);
    return [];
  }
}

// 3. 중심점 기반 반경 내 선박 조회
export async function getVesselsNearby(
  lat: number,
  lng: number,
  radiusKm: number = 10,
): Promise<VesselPosition[]> {
  // 대략적인 BBox 계산 (1도 ≈ 111km)
  const latDelta = radiusKm / 111;
  const lngDelta = radiusKm / (111 * Math.cos((lat * Math.PI) / 180));

  const bbox: BoundingBox = {
    minLat: lat - latDelta,
    maxLat: lat + latDelta,
    minLng: lng - lngDelta,
    maxLng: lng + lngDelta,
  };

  return getVesselsInArea(bbox);
}

// 4. 선박 이동 경로 조회 (Track)
export async function getVesselTrack(
  mmsi: string,
  startTime: string,
  endTime: string,
): Promise<VesselPosition[]> {
  try {
    const response = await axios.get(`${AIS_BASE_URL}/vessel/${mmsi}/track`, {
      headers: {
        Authorization: `Bearer ${AIS_API_KEY}`,
        'Content-Type': 'application/json',
      },
      params: {
        start: startTime, // ISO 8601 format: '2025-02-10T00:00:00Z'
        end: endTime,
      },
    });

    return response.data.map((position: Record<string, unknown>) => ({
      ...position,
      shipTypeText: getShipTypeText(position.shipType as number),
      navStatusText: getNavStatusText(position.navStatus as number),
    }));
  } catch (error) {
    console.error(`선박 경로 조회 오류 (MMSI: ${mmsi}):`, error);
    return [];
  }
}

// 5. 선박 유형별 필터링
export async function getVesselsByType(
  bbox: BoundingBox,
  shipTypes: number[],
): Promise<VesselPosition[]> {
  const allVessels = await getVesselsInArea(bbox);
  return allVessels.filter((v) => shipTypes.includes(v.shipType));
}

// 6. 위험 선박 필터링 (정박/좌초/조종불능)
export async function getDangerousVessels(bbox: BoundingBox): Promise<VesselPosition[]> {
  const allVessels = await getVesselsInArea(bbox);
  const dangerStatuses = [2, 3, 6]; // 조종 불능, 조종 제한, 좌초
  return allVessels.filter((v) => dangerStatuses.includes(v.navStatus));
}

// 7. 유조선만 필터링 (유출 사고 대비)
export async function getTankers(bbox: BoundingBox): Promise<VesselPosition[]> {
  const tankerTypes = [80, 81, 82, 83, 84, 85, 86, 87, 88, 89];
  return getVesselsByType(bbox, tankerTypes);
}

// 8. 선박 속도로 필터링 (정박 중 판단)
export function filterBySpeed(
  vessels: VesselPosition[],
  minSpeed: number = 0,
  maxSpeed: number = 100,
): VesselPosition[] {
  return vessels.filter((v) => v.speed >= minSpeed && v.speed <= maxSpeed);
}

// 9. 거리 계산 (Haversine formula)
export function calculateDistance(lat1: number, lng1: number, lat2: number, lng2: number): number {
  const R = 6371; // 지구 반경 (km)
  const dLat = ((lat2 - lat1) * Math.PI) / 180;
  const dLng = ((lng2 - lng1) * Math.PI) / 180;
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos((lat1 * Math.PI) / 180) *
      Math.cos((lat2 * Math.PI) / 180) *
      Math.sin(dLng / 2) *
      Math.sin(dLng / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
}

// 10. 가장 가까운 선박 찾기
export function findNearestVessel(
  targetLat: number,
  targetLng: number,
  vessels: VesselPosition[],
): VesselPosition | null {
  if (vessels.length === 0) return null;

  let nearest = vessels[0];
  let minDistance = calculateDistance(targetLat, targetLng, nearest.latitude, nearest.longitude);

  vessels.forEach((vessel) => {
    const distance = calculateDistance(targetLat, targetLng, vessel.latitude, vessel.longitude);
    if (distance < minDistance) {
      minDistance = distance;
      nearest = vessel;
    }
  });

  return nearest;
}

// 11. Mock 데이터 (테스트용)
export function getMockVessels(): VesselPosition[] {
  return [
    {
      mmsi: '440123456',
      imo: 'IMO9123456',
      shipName: '씨프린스호',
      callSign: 'HLCS',
      shipType: 80,
      shipTypeText: '유조선',
      latitude: 34.5,
      longitude: 127.8,
      speed: 0.2,
      course: 135,
      heading: 140,
      navStatus: 1,
      navStatusText: '정박중',
      timestamp: new Date().toISOString(),
      destination: 'YEOSU',
      draught: 12.5,
      length: 180,
      width: 32,
    },
    {
      mmsi: '440234567',
      shipName: '여수경비정',
      shipType: 55,
      shipTypeText: '법집행선',
      latitude: 34.52,
      longitude: 127.82,
      speed: 12.5,
      course: 270,
      heading: 268,
      navStatus: 0,
      navStatusText: '기관 사용 항해중',
      timestamp: new Date().toISOString(),
      destination: 'PATROL',
      length: 45,
      width: 8,
    },
  ];
}
