/**
 * 선박 상세 모달 컴포넌트 (다중 모달 지원, 최대 3개)
 * 퍼블리시 ShipComponent.jsx의 popupMap shipInfo 구조 활용
 * 참조: mda-react-front/src/components/popup/ShipDetailModal.tsx
 *
 * - 헤더 드래그로 위치 이동 가능
 * - 선박 사진 갤러리 (없으면 기본 이미지)
 * - 새 모달은 직전 모달의 현재 위치(드래그 반영) 기준 우측 140px 오프셋으로 생성
 */
import { useRef, useState, useCallback, useEffect } from 'react';
import useShipStore from '../../stores/shipStore';
import { useTrackQueryStore } from '../../tracking/stores/trackQueryStore';
import {
  fetchVesselTracksV2,
  convertToProcessedTracks,
  buildVesselListForQuery,
  isIntegratedTargetId,
} from '../../tracking/services/trackQueryApi';
import { TrackQueryViewer } from '../../tracking/components/TrackQueryViewer';
import {
  SHIP_KIND_LABELS,
  SIGNAL_FLAG_CONFIGS,
  SPEED_THRESHOLD,
  SIGNAL_KIND_CODE_FISHING,
  SIGNAL_KIND_CODE_KCGV,
  SIGNAL_KIND_CODE_PASSENGER,
  SIGNAL_KIND_CODE_CARGO,
  SIGNAL_KIND_CODE_TANKER,
  SIGNAL_KIND_CODE_GOV,
} from '../../types/constants';
import defaultShipImg from '../../assets/img/default-ship.png';
import fishingIcon from '../../assets/img/shipDetail/detailKindIcon/fishing.svg';
import kcgvIcon from '../../assets/img/shipDetail/detailKindIcon/kcgv.svg';
import passengerIcon from '../../assets/img/shipDetail/detailKindIcon/passenger.svg';
import cargoIcon from '../../assets/img/shipDetail/detailKindIcon/cargo.svg';
import tankerIcon from '../../assets/img/shipDetail/detailKindIcon/tanker.svg';
import govIcon from '../../assets/img/shipDetail/detailKindIcon/gov.svg';
import etcIcon from '../../assets/img/shipDetail/detailKindIcon/etc.svg';
import './ShipDetailModal.scss';

/** 선종코드 → 아이콘 매핑 */
const SHIP_KIND_ICONS = {
  [SIGNAL_KIND_CODE_FISHING]: fishingIcon,
  [SIGNAL_KIND_CODE_KCGV]: kcgvIcon,
  [SIGNAL_KIND_CODE_PASSENGER]: passengerIcon,
  [SIGNAL_KIND_CODE_CARGO]: cargoIcon,
  [SIGNAL_KIND_CODE_TANKER]: tankerIcon,
  [SIGNAL_KIND_CODE_GOV]: govIcon,
};

/** 선종 아이콘 URL 반환 */
function getShipKindIcon(signalKindCode) {
  return SHIP_KIND_ICONS[signalKindCode] || etcIcon;
}

/**
 * 국기 아이콘 URL 반환 (서버 API)
 * 참조: mda-react-front/src/services/filterCheck.ts - filterNationFlag()
 * 개발 환경에서는 Vite 프록시를 통해 API 서버로 전달됨
 * @param {string} nationalCode - MID 숫자코드 (예: '440', '412')
 * @returns {string} 국기 이미지 URL
 */
function getNationalFlagUrl(nationalCode) {
  if (!nationalCode) return null;
  // 상대 경로 사용 (Vite 프록시가 /ship/image를 API 서버로 전달)
  return `/ship/image/small/${nationalCode}.svg`;
}

/**
 * receivedTime 문자열을 YYYY-MM-DD HH:mm:ss 형식으로 변환
 * 입력 예: '20241123112300' 또는 '2024-11-23 11:23:00' 또는 '2024-11-23T11:23:00'
 * @param {string} raw
 * @returns {string}
 */
function formatDateTime(raw) {
  if (!raw) return '-';

  // 이미 YYYY-MM-DD HH:mm:ss 형태면 그대로 반환
  if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(raw)) {
    return raw;
  }

  // 숫자만 추출 (구분자 제거)
  const digits = raw.replace(/\D/g, '');

  if (digits.length >= 14) {
    const y = digits.slice(0, 4);
    const M = digits.slice(4, 6);
    const d = digits.slice(6, 8);
    const h = digits.slice(8, 10);
    const m = digits.slice(10, 12);
    const s = digits.slice(12, 14);
    return `${y}-${M}-${d} ${h}:${m}:${s}`;
  }

  // 파싱 불가하면 원본 반환
  return raw;
}

/**
 * AVETDR 신호 플래그 표시
 */
function SignalFlags({ ship }) {
  const isIntegrate = useShipStore((s) => s.isIntegrate);
  // 통합선박 판별: 언더스코어 또는 integrate 플래그
  const isIntegratedShip = ship.targetId && (ship.targetId.includes('_') || ship.integrate);
  const useIntegratedMode = isIntegrate && isIntegratedShip;

  return (
    <ul className="shipTypeIco">
      {SIGNAL_FLAG_CONFIGS.map((config) => {
        let isActive = false;
        let isVisible = false;

        if (useIntegratedMode) {
          const val = ship[config.dataKey];
          if (val === '1') { isVisible = true; isActive = true; }
          else if (val === '0') { isVisible = true; }
        } else {
          if (config.signalSourceCode === ship.signalSourceCode) {
            isVisible = true;
            isActive = true;
          }
        }

        if (!isVisible) return null;

        return (
          <li
            key={config.key}
            className={isActive ? 'active' : 'inactive'}
            style={{ backgroundColor: isActive ? config.activeColor : config.inactiveColor }}
          >
            {config.key}
          </li>
        );
      })}
    </ul>
  );
}

/**
 * 선박 사진 갤러리
 * 이미지가 없으면 기본 이미지(default-ship.png) 표시
 */
function ShipGallery({ imageUrlList }) {
  const [currentIndex, setCurrentIndex] = useState(0);
  const hasImages = imageUrlList && imageUrlList.length > 0;
  const images = hasImages ? imageUrlList : [defaultShipImg];
  const total = images.length;
  const canSlide = total > 1;

  const handlePrev = useCallback(() => {
    setCurrentIndex((prev) => (prev === 0 ? total - 1 : prev - 1));
  }, [total]);

  const handleNext = useCallback(() => {
    setCurrentIndex((prev) => (prev === total - 1 ? 0 : prev + 1));
  }, [total]);

  const handleIndicatorClick = useCallback((index) => {
    setCurrentIndex(index);
  }, []);

  return (
    <div className="pmGallery">
      {canSlide && (
        <>
          <button type="button" className="navBtn prev" onClick={handlePrev}>
            <span className="blind">이전</span>
          </button>
          <button type="button" className="navBtn next" onClick={handleNext}>
            <span className="blind">다음</span>
          </button>
        </>
      )}
      <div className="galleryView">
        <img
          className="galleryImg"
          src={images[currentIndex]}
          alt="선박 이미지"
          onError={(e) => { e.target.src = defaultShipImg; }}
        />
      </div>
      {canSlide && (
        <div className="galleryIndicators">
          {images.map((_, i) => (
            <button
              type="button"
              key={i}
              className={`indicator${i === currentIndex ? ' active' : ''}`}
              onClick={() => handleIndicatorClick(i)}
              aria-label={`이미지 ${i + 1}`}
            />
          ))}
        </div>
      )}
    </div>
  );
}

/**
 * 단일 선박 상세 모달
 * @param {Object} props.modal - { ship, id, initialPos }
 */
export default function ShipDetailModal({ modal }) {
  const closeDetailModal = useShipStore((s) => s.closeDetailModal);
  const updateModalPos = useShipStore((s) => s.updateModalPos);
  const isIntegrateMode = useShipStore((s) => s.isIntegrate);

  // 항적조회 패널 상태
  const [showTrackPanel, setShowTrackPanel] = useState(false);
  const [isQuerying, setIsQuerying] = useState(false);
  const [timeRange, setTimeRange] = useState(() => {
    const now = new Date();
    const from = new Date(now.getTime() - 3 * 24 * 60 * 60 * 1000); // 3일 전
    const pad = (n) => String(n).padStart(2, '0');
    const toLocal = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
    return { fromDate: toLocal(from), toDate: toLocal(now) };
  });

  // 드래그 상태 - 초기 위치는 스토어에서 계산된 initialPos 사용
  const [position, setPosition] = useState(() => ({ ...modal.initialPos }));
  const posRef = useRef(modal.initialPos);
  const dragging = useRef(false);
  const dragStart = useRef({ x: 0, y: 0 });

  // 드래그 핸들러
  const handleMouseDown = useCallback((e) => {
    dragging.current = true;
    dragStart.current = {
      x: e.clientX - position.x,
      y: e.clientY - position.y,
    };
    e.preventDefault();
  }, [position]);

  useEffect(() => {
    const handleMouseMove = (e) => {
      if (!dragging.current) return;
      const newPos = {
        x: e.clientX - dragStart.current.x,
        y: e.clientY - dragStart.current.y,
      };
      posRef.current = newPos;
      setPosition(newPos);
    };

    const handleMouseUp = () => {
      if (dragging.current) {
        dragging.current = false;
        // 드래그 종료 시 스토어에 현재 위치 보고 (ref에서 읽어서 render 중 setState 회피)
        updateModalPos(modal.id, posRef.current);
      }
    };

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, [modal.id, updateModalPos]);

  // KST 기준 로컬 ISO 문자열 생성 (toISOString()은 UTC 기준이므로 사용하지 않음)
  const toKstISOString = useCallback((date) => {
    const pad = (n, len = 2) => String(n).padStart(len, '0');
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
  }, []);

  // 항적 조회 실행 (공용)
  const executeTrackQuery = useCallback(async (fromDate, toDate) => {
    const { ship } = modal;
    const startTime = new Date(fromDate);
    const endTime = new Date(toDate);

    if (isNaN(startTime.getTime()) || isNaN(endTime.getTime())) return;
    if (startTime >= endTime) return;

    const isIntegrated = isIntegratedTargetId(ship.targetId);
    // 모달 항적조회: 통합모드 ON이면 전체 장비 조회, OFF면 단일 장비 조회
    // isIntegration API 파라미터는 항상 '0' (개별 항적 반환)
    const queryResult = buildVesselListForQuery(ship, 'modal', isIntegrateMode);

    if (!queryResult.canQuery) {
      useTrackQueryStore.getState().setError(queryResult.errorMessage || '조회 불가');
      return;
    }

    setIsQuerying(true);
    const store = useTrackQueryStore.getState();

    try {
      const rawTracks = await fetchVesselTracksV2({
        startTime: toKstISOString(startTime),
        endTime: toKstISOString(endTime),
        vessels: queryResult.vessels,
        isIntegration: '0',
      });
      const processed = convertToProcessedTracks(rawTracks);
      if (processed.length === 0) {
        store.setError('항적 데이터가 없습니다.');
      } else {
        store.setTracks(processed, startTime.getTime());
      }
    } catch (e) {
      console.error('[ShipDetailModal] 항적 조회 실패:', e);
      store.setError('항적 조회 실패');
    }
    setIsQuerying(false);
  }, [modal, toKstISOString, isIntegrateMode]);

  // 항적조회 패널 열기 + 즉시 3일 조회
  const handleOpenTrackPanel = useCallback(async () => {
    // 이전 항적 데이터 초기화
    useTrackQueryStore.getState().reset();
    useTrackQueryStore.getState().setModalMode(true, modal.id);
    setShowTrackPanel(true);

    // 즉시 3일 항적 조회
    const now = new Date();
    const from = new Date(now.getTime() - 3 * 24 * 60 * 60 * 1000);
    const pad = (n) => String(n).padStart(2, '0');
    const toLocal = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
    const newTimeRange = { fromDate: toLocal(from), toDate: toLocal(now) };
    setTimeRange(newTimeRange);

    await executeTrackQuery(from, now);
  }, [modal.id, executeTrackQuery]);

  // 항적조회 패널 닫기
  const handleCloseTrackPanel = useCallback(() => {
    setShowTrackPanel(false);
    useTrackQueryStore.getState().reset();
  }, []);

  // 시간 폼에서 재조회
  const handleTrackQuery = useCallback(async () => {
    await executeTrackQuery(timeRange.fromDate, timeRange.toDate);
  }, [timeRange, executeTrackQuery]);

  const { ship, id } = modal;
  const isIntegrated = isIntegratedTargetId(ship.targetId);
  const kindLabel = SHIP_KIND_LABELS[ship.signalKindCode] || '기타';
  const sog = Number(ship.sog) || 0;
  const cog = Number(ship.cog) || 0;
  const isMoving = sog > SPEED_THRESHOLD;
  const draught = ship.draught ? `${(Number(ship.draught) / 10).toFixed(1)}m` : '-';
  const formattedTime = formatDateTime(ship.receivedTime);

  return (
    <div
      className="popupMap shipInfo ship-detail-modal"
      style={{
        left: position.x,
        top: position.y,
        transform: 'none',
      }}
    >
      {/* header - 드래그 핸들 */}
      <div className="pmHeader" onMouseDown={handleMouseDown}>
        <div className="rowL">
          <span className="shipTypeIcon">
            <img src={getShipKindIcon(ship.signalKindCode)} alt={kindLabel} />
          </span>
          {ship.nationalCode && (
            <span className="countryFlag">
              <img
                src={getNationalFlagUrl(ship.nationalCode)}
                alt="국기"
                onError={(e) => { e.target.style.display = 'none'; }}
              />
            </span>
          )}
          <span className="shipName" title={ship.shipName || ''}>{ship.shipName || '-'}</span>
          <span className="shipNum" title={ship.originalTargetId || ''}>{ship.originalTargetId || '-'}</span>
        </div>
        <button
          type="button"
          className="pmClose"
          aria-label="닫기"
          onClick={() => closeDetailModal(id)}
        />
      </div>

      {/* gallery */}
      <ShipGallery imageUrlList={ship.imageUrlList} />

      {/* body */}
      <div className="pmBody">
        <div className="shipAction">
          <div className="rowL">
            <button type="button" className="detailBtn">상세정보</button>
            <SignalFlags ship={ship} />
          </div>
        </div>

        <ul className="shipStatus">
          <li className="status">
            <div className="statusItem">
              <span className="statusLabel">선박상태</span>
              <span className="statusValue">{isMoving ? '항해' : '정박'}</span>
            </div>
            <div className="statusItem w13r">
              <span className="statusLabel">속도/항로</span>
              <span className="statusValue">{sog.toFixed(1)} kn / {cog.toFixed(1)}&deg;</span>
            </div>
            <div className="statusItem">
              <span className="statusLabel">흘수</span>
              <span className="statusValue">{draught}</span>
            </div>
          </li>
        </ul>

        <div className="btnWrap">
          <button
            type="button"
            className="trackBtn"
            onClick={handleOpenTrackPanel}
          >
            항적조회
          </button>
          <button type="button" className="trackBtn">항로예측</button>
        </div>
      </div>

      {/* footer */}
      <div className="pmFooter">데이터 수신시간 : {formattedTime}</div>

      {/* 항적조회 패널 (모달 모드) */}
      {showTrackPanel && (
        <TrackQueryViewer
          modalMode
          isIntegrated={isIntegrated}
          timeRange={timeRange}
          onTimeRangeChange={setTimeRange}
          onQuery={handleTrackQuery}
          isQuerying={isQuerying}
          onClose={handleCloseTrackPanel}
        />
      )}
    </div>
  );
}
