/**
 * 항적조회 v2 REST API 서비스
 *
 * /api/v2/tracks/vessels 엔드포인트 사용
 * dark 프로젝트: axios 대신 fetch API 사용
 */
import { SOURCE_PRIORITY_RANK, SOURCE_TO_ACTIVE_KEY } from '../../types/constants';

/** API 엔드포인트 */
const API_ENDPOINT = '/api/v2/tracks/vessels';

/**
 * 선박 항적 조회 (v2 API)
 *
 * @param {Object} params 조회 파라미터
 * @param {string} params.startTime ISO 8601 형식 시작 시간
 * @param {string} params.endTime ISO 8601 형식 종료 시간
 * @param {Array<{sigSrcCd: string, targetId: string}>} params.vessels 조회 대상 선박 목록
 * @param {string} [params.isIntegration] 통합선박 조회 시 "1"
 * @returns {Promise<Array>} 항적 데이터 배열
 */
export async function fetchVesselTracksV2(params) {
  const request = {
    startTime: params.startTime,
    endTime: params.endTime,
    vessels: params.vessels,
    ...(params.isIntegration && { isIntegration: params.isIntegration }),
  };

  const response = await fetch(API_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify(request),
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result = await response.json();
  return Array.isArray(result) ? result : (result?.data || []);
}

/**
 * 단일 선박 항적 조회 헬퍼
 */
export async function fetchSingleVesselTrackV2(sigSrcCd, targetId, startTime, endTime, isIntegration) {
  const tracks = await fetchVesselTracksV2({
    startTime,
    endTime,
    vessels: [{ sigSrcCd, targetId }],
    isIntegration,
  });
  return tracks.length > 0 ? tracks[0] : null;
}

/**
 * 유효한 선명인지 확인
 */
function isValidApiShipName(name) {
  if (!name) return false;
  const trimmed = name.trim();
  if (!trimmed) return false;
  if (trimmed === '-') return false;
  if (/^\d+$/.test(trimmed)) return false;
  return true;
}

/**
 * API 응답 → 가공 데이터 변환
 * - timestamps를 밀리초로 변환
 * - 시간순 정렬 보장
 *
 * @param {Array} tracks API 응답 항적 배열
 * @returns {Array} ProcessedTrackV2 배열
 */
export function convertToProcessedTracks(tracks) {
  return tracks.map(track => {
    // timestamps를 밀리초로 변환
    const timestampsMs = track.timestamps.map(ts => {
      const num = parseInt(ts, 10);
      return num < 10000000000 ? num * 1000 : num;
    });

    // 시간순 정렬 인덱스 생성
    const sortedIndices = timestampsMs.map((_, i) => i).sort((a, b) => timestampsMs[a] - timestampsMs[b]);

    // 선명 처리
    const shipName = isValidApiShipName(track.shipName) ? track.shipName.trim() : '';

    return {
      vesselId: track.vesselId,
      targetId: track.targetId,
      sigSrcCd: track.sigSrcCd,
      shipName,
      shipKindCode: track.shipKindCode || '000027',
      nationalCode: track.nationalCode || '',
      integrationTargetId: track.integrationTargetId || undefined,
      geometry: sortedIndices.map(i => track.geometry[i]),
      timestampsMs: sortedIndices.map(i => timestampsMs[i]),
      speeds: sortedIndices.map(i => track.speeds?.[i] || 0),
      stats: {
        totalDistance: track.totalDistance,
        avgSpeed: track.avgSpeed,
        maxSpeed: track.maxSpeed,
        pointCount: track.pointCount,
      },
    };
  });
}

/**
 * 통합선박 TARGET_ID 파싱
 * 형식: AIS_VPASS_ENAV_VTSAIS_DMFHF
 *
 * @param {string} targetId 통합 TARGET_ID
 * @returns {Array<{sigSrcCd: string, targetId: string}>|null}
 */
export function parseIntegratedTargetId(targetId) {
  const parts = targetId.split('_');
  if (parts.length !== 5) return null;

  const [ais, vpass, enav, vtsAis, dmfhf] = parts;
  const vessels = [];

  if (ais) vessels.push({ sigSrcCd: '000001', targetId: ais });
  if (vpass) vessels.push({ sigSrcCd: '000003', targetId: vpass });
  if (enav) vessels.push({ sigSrcCd: '000002', targetId: enav });
  if (vtsAis) vessels.push({ sigSrcCd: '000004', targetId: vtsAis });
  if (dmfhf) vessels.push({ sigSrcCd: '000016', targetId: dmfhf });

  return vessels.length > 0 ? vessels : null;
}

/** 통합선박 여부 확인 */
export function isIntegratedVessel(signalSourceCode) {
  return signalSourceCode === '999999';
}

/** 레이더 타겟 여부 확인 */
export function isRadarTarget(signalSourceCode) {
  return signalSourceCode === '000005';
}

/**
 * 레이더 타겟 항적조회 가능 여부 확인
 *
 * @param {string} targetId 레이더 타겟의 TARGET_ID
 * @param {string} [isPriority] IS_PRIORITY 값
 * @returns {{ canQuery: boolean, vessel?: Object, errorMessage?: string }}
 */
export function checkRadarTargetForTrackQuery(targetId, isPriority) {
  const isIntegrated = targetId.includes('_');

  if (!isIntegrated) {
    return {
      canQuery: false,
      errorMessage: '레이더 타겟은 항적 정보가 존재하지 않습니다.',
    };
  }

  const parsedVessels = parseIntegratedTargetId(targetId);

  if (!parsedVessels || parsedVessels.length === 0) {
    return {
      canQuery: false,
      errorMessage: '레이더 타겟은 항적 정보가 존재하지 않습니다.',
    };
  }

  const priorityOrder = ['000004', '000001', '000003', '000002', '000016'];

  for (const sigSrcCd of priorityOrder) {
    const vessel = parsedVessels.find(v => v.sigSrcCd === sigSrcCd);
    if (vessel) {
      return { canQuery: true, vessel };
    }
  }

  return { canQuery: true, vessel: parsedVessels[0] };
}

/**
 * 통합선박 전체 장비 조회용 선박 목록 반환
 *
 * @param {string} targetId 통합선박 TARGET_ID
 * @returns {Array<{sigSrcCd: string, targetId: string}>}
 */
export function getAllVesselsForIntegratedShip(targetId) {
  if (!targetId.includes('_')) return [];
  const vessels = parseIntegratedTargetId(targetId);
  return vessels || [];
}

/**
 * 통합선박의 활성화된 장비만 조회용 선박 목록 반환
 * dark 프로젝트의 ship 객체 프로퍼티 기반
 *
 * @param {Object} ship shipStore의 선박 데이터
 * @returns {Array<{sigSrcCd: string, targetId: string}>}
 */
export function getActiveVesselsForIntegratedShip(ship) {
  const targetId = ship.targetId;
  if (!targetId || !targetId.includes('_')) return [];

  const parts = targetId.split('_');
  if (parts.length !== 5) return [];

  const [ais, vpass, enav, vtsAis, dmfhf] = parts;
  const vessels = [];

  if (ais && ship.ais === '1') vessels.push({ sigSrcCd: '000001', targetId: ais });
  if (vpass && ship.vpass === '1') vessels.push({ sigSrcCd: '000003', targetId: vpass });
  if (enav && ship.enav === '1') vessels.push({ sigSrcCd: '000002', targetId: enav });
  if (vtsAis && ship.vtsAis === '1') vessels.push({ sigSrcCd: '000004', targetId: vtsAis });
  if (dmfhf && ship.dMfHf === '1') vessels.push({ sigSrcCd: '000016', targetId: dmfhf });

  return vessels;
}

/**
 * 통합선박 TARGET_ID 여부 확인
 */
export function isIntegratedTargetId(targetId) {
  return targetId && targetId.includes('_');
}

/**
 * 통합선박에서 활성화된 장비 중 우선순위가 가장 높은 선박 반환
 * dark 프로젝트의 ship 객체 프로퍼티 기반
 *
 * @param {Object} ship shipStore의 선박 데이터
 * @returns {{ sigSrcCd: string, targetId: string }|null}
 */
export function getHighestPriorityActiveVessel(ship) {
  const targetId = ship.targetId;
  if (!targetId || !targetId.includes('_')) return null;

  const parts = targetId.split('_');
  if (parts.length !== 5) return null;

  const [ais, vpass, enav, vtsAis, dmfhf] = parts;

  // 우선순위: VTS-AIS > AIS > V-Pass > E-Nav > D-MF/HF
  // is_active 플래그는 '1'/'0' 문자열이므로 === '1'로 비교 ('0'도 truthy이므로)
  if (vtsAis && ship.vtsAis === '1') return { sigSrcCd: '000004', targetId: vtsAis };
  if (ais && ship.ais === '1') return { sigSrcCd: '000001', targetId: ais };
  if (vpass && ship.vpass === '1') return { sigSrcCd: '000003', targetId: vpass };
  if (enav && ship.enav === '1') return { sigSrcCd: '000002', targetId: enav };
  if (dmfhf && ship.dMfHf === '1') return { sigSrcCd: '000016', targetId: dmfhf };

  return null;
}

/**
 * 항적조회용 선박 목록 생성 (통합 함수)
 * dark 프로젝트의 ship 객체 기반으로 변환
 *
 * 통합선박ON (isIntegrate=true):
 *   1. 레이더 타겟인가?
 *      - 레이더 + 미통합 → 제외
 *      - 레이더 + 통합 + 통합선박(targetId에 '_') → is_active='1'인 장비 중 최고 우선순위
 *      - 레이더 + 통합 + 단독선박(targetId에 '_' 없음) → 해당 단독선박 정보 직접 전달
 *   2. 비레이더 + 통합선박 → is_active='1'인 장비 중 최고 우선순위
 *   3. 비레이더 + 단독선박 → sigSrcCd + originalTargetId 직접 전달
 *
 * 통합선박OFF (isIntegrate=false):
 *   - 레이더 타겟 → 제외
 *   - 나머지 → sigSrcCd + originalTargetId 직접 전달
 *
 * @param {Object} ship shipStore의 선박 데이터
 * @param {'modal'|'rightClick'} mode 조회 모드
 * @param {boolean} isIntegrate 통합선박 ON/OFF 상태
 * @param {Map} [features] shipStore.features (레이더+단독선박 통합 시 비레이더 탐색용)
 * @returns {{ canQuery: boolean, vessels: Array, errorMessage?: string }}
 */
export function buildVesselListForQuery(ship, mode, isIntegrate, features) {
  const sigSrcCd = ship.signalSourceCode || '';
  const targetId = ship.targetId || '';
  const isRadar = isRadarTarget(sigSrcCd);

  // ===== 통합선박 OFF =====
  if (!isIntegrate) {
    // 레이더 타겟 → 항적 조회 불가
    if (isRadar) {
      return { canQuery: false, vessels: [], errorMessage: '레이더 타겟은 항적 정보가 존재하지 않습니다.' };
    }
    // 나머지 → sigSrcCd + originalTargetId 직접 전달
    const singleTargetId = ship.originalTargetId || targetId;
    return { canQuery: true, vessels: [{ sigSrcCd, targetId: singleTargetId }] };
  }

  // ===== 통합선박 ON =====

  // 1. 레이더 타겟 처리
  if (isRadar) {
    // 1-1. 미통합 레이더 → 제외
    if (!ship.integrate) {
      return { canQuery: false, vessels: [], errorMessage: '레이더 타겟은 항적 정보가 존재하지 않습니다.' };
    }
    // 1-2. 통합된 레이더 + 통합선박 (targetId에 '_' 있음)
    if (targetId.includes('_')) {
      const activeVessel = getHighestPriorityActiveVessel(ship);
      if (activeVessel) return { canQuery: true, vessels: [activeVessel] };
      // fallback: 활성 장비 없으면 targetId 파싱해서 첫 번째라도 전달
      const parsed = parseIntegratedTargetId(targetId);
      if (parsed && parsed.length > 0) return { canQuery: true, vessels: [parsed[0]] };
      return { canQuery: false, vessels: [], errorMessage: '활성화된 장비가 없습니다.' };
    }
    // 1-3. 통합된 레이더 + 단독선박 (targetId에 '_' 없음)
    //   레이더와 통합된 단독선박 → 같은 targetId를 공유하므로, 해당 선박의 비레이더 feature 탐색
    return resolveStandaloneForRadar(ship, features);
  }

  // 2. 비레이더 + 통합선박 (targetId에 '_' 있음)
  if (targetId.includes('_')) {
    if (mode === 'modal') {
      // 모달: 전체 장비 목록 전달
      const allVessels = getAllVesselsForIntegratedShip(targetId);
      if (allVessels.length > 0) return { canQuery: true, vessels: allVessels };
    }
    // rightClick: is_active='1'인 장비 중 최고 우선순위
    const activeVessel = getHighestPriorityActiveVessel(ship);
    if (activeVessel) return { canQuery: true, vessels: [activeVessel] };
    const fallbackTargetId = ship.originalTargetId || targetId;
    return { canQuery: true, vessels: [{ sigSrcCd, targetId: fallbackTargetId }] };
  }

  // 3. 비레이더 + 단독선박
  const singleTargetId = ship.originalTargetId || targetId;
  return { canQuery: true, vessels: [{ sigSrcCd, targetId: singleTargetId }] };
}

/**
 * 레이더 + 단독선박 통합 시 비레이더 feature를 탐색하여 요청 파라미터 생성
 * shipStore.features에서 같은 targetId의 비레이더 신호원을 찾아 우선순위 기반 선택
 *
 * @param {Object} ship 레이더 타겟 ship 객체
 * @param {Map} features shipStore.features
 * @returns {{ canQuery: boolean, vessels: Array, errorMessage?: string }}
 */
function resolveStandaloneForRadar(ship, features) {
  if (!features) {
    return { canQuery: false, vessels: [], errorMessage: '통합된 단독선박 정보를 찾을 수 없습니다.' };
  }
  const targetId = ship.targetId;
  let bestVessel = null;
  let bestRank = 99;

  features.forEach((f) => {
    if (f.targetId !== targetId) return;
    if (isRadarTarget(f.signalSourceCode)) return;
    const rank = SOURCE_PRIORITY_RANK[f.signalSourceCode] ?? 99;
    const activeKey = SOURCE_TO_ACTIVE_KEY[f.signalSourceCode];
    // is_active 확인
    if (activeKey && f[activeKey] === '1' && rank < bestRank) {
      bestRank = rank;
      bestVessel = { sigSrcCd: f.signalSourceCode, targetId: f.originalTargetId || f.targetId };
    }
  });

  if (bestVessel) return { canQuery: true, vessels: [bestVessel] };

  // 활성 장비 없으면 비레이더 feature 중 아무거나
  features.forEach((f) => {
    if (bestVessel) return;
    if (f.targetId !== targetId) return;
    if (isRadarTarget(f.signalSourceCode)) return;
    bestVessel = { sigSrcCd: f.signalSourceCode, targetId: f.originalTargetId || f.targetId };
  });

  if (bestVessel) return { canQuery: true, vessels: [bestVessel] };
  return { canQuery: false, vessels: [], errorMessage: '통합된 단독선박 정보를 찾을 수 없습니다.' };
}

/**
 * 항적조회 요청 파라미터 중복 제거
 * (sigSrcCd, targetId) 조합이 동일한 항목 제거
 *
 * @param {Array<{sigSrcCd: string, targetId: string}>} vessels
 * @returns {Array<{sigSrcCd: string, targetId: string}>}
 */
export function deduplicateVessels(vessels) {
  const seen = new Set();
  return vessels.filter(v => {
    const key = `${v.sigSrcCd}_${v.targetId}`;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}
