import { useCallback, useMemo, useState } from 'react';
import { useTrackPlaybackStore, TRACK_PLAYBACK_SPEED_OPTIONS } from '../../features/trackReplay/stores/trackPlaybackStore';
import { useTrackQueryStore } from '../../features/trackReplay/stores/trackQueryStore';
import { exportTrackCsv } from '../../features/trackReplay/lib/csvExport';
import { SHIP_KIND_COLORS } from '../../shared/lib/map/shipKind';
import type { ProcessedTrack } from '../../features/trackReplay/model/track.types';
import { MAX_QUERY_DAYS } from '../../features/vesselSelect/model/types';

function formatDateTime(ms: number): string {
  if (!Number.isFinite(ms) || ms <= 0) return '--';
  const date = new Date(ms);
  const pad = (value: number) => String(value).padStart(2, '0');
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(
    date.getMinutes(),
  )}:${pad(date.getSeconds())}`;
}

function toDateTimeLocalKST(ms: number): string {
  if (!Number.isFinite(ms) || ms <= 0) return '';
  const kstDate = new Date(ms + 9 * 3600_000);
  return kstDate.toISOString().slice(0, 16);
}

function fromDateTimeLocalKST(value: string): string {
  return `${value}:00+09:00`;
}

const inputStyle: React.CSSProperties = {
  flex: 1,
  fontSize: 11,
  padding: '3px 6px',
  borderRadius: 4,
  border: '1px solid rgba(148,163,184,0.35)',
  background: 'rgba(30,41,59,0.8)',
  color: '#e2e8f0',
  colorScheme: 'dark',
};

const btnBase: React.CSSProperties = {
  padding: '6px 10px',
  borderRadius: 6,
  border: '1px solid rgba(148,163,184,0.45)',
  background: 'rgba(30,41,59,0.8)',
  color: '#e2e8f0',
  cursor: 'pointer',
};

interface GlobalTrackReplayPanelProps {
  isVesselListOpen?: boolean;
  onToggleVesselList?: () => void;
}

export function GlobalTrackReplayPanel({ isVesselListOpen, onToggleVesselList }: GlobalTrackReplayPanelProps) {
  const tracks = useTrackQueryStore((state) => state.tracks);
  const isLoading = useTrackQueryStore((state) => state.isLoading);
  const error = useTrackQueryStore((state) => state.error);
  const queryContext = useTrackQueryStore((state) => state.queryContext);
  const multiQueryContext = useTrackQueryStore((state) => state.multiQueryContext);
  const disabledVesselIds = useTrackQueryStore((state) => state.disabledVesselIds);
  const showPoints = useTrackQueryStore((state) => state.showPoints);
  const showLabels = useTrackQueryStore((state) => state.showLabels);
  const showTrail = useTrackQueryStore((state) => state.showTrail);
  const hideLiveShips = useTrackQueryStore((state) => state.hideLiveShips);
  const setShowPoints = useTrackQueryStore((state) => state.setShowPoints);
  const setShowLabels = useTrackQueryStore((state) => state.setShowLabels);
  const setShowTrail = useTrackQueryStore((state) => state.setShowTrail);
  const setHideLiveShips = useTrackQueryStore((state) => state.setHideLiveShips);
  const closeTrackQuery = useTrackQueryStore((state) => state.closeQuery);
  const requery = useTrackQueryStore((state) => state.requery);
  const toggleVesselEnabled = useTrackQueryStore((state) => state.toggleVesselEnabled);

  const isPlaying = useTrackPlaybackStore((state) => state.isPlaying);
  const currentTime = useTrackPlaybackStore((state) => state.currentTime);
  const startTime = useTrackPlaybackStore((state) => state.startTime);
  const endTime = useTrackPlaybackStore((state) => state.endTime);
  const playbackSpeed = useTrackPlaybackStore((state) => state.playbackSpeed);
  const play = useTrackPlaybackStore((state) => state.play);
  const pause = useTrackPlaybackStore((state) => state.pause);
  const stop = useTrackPlaybackStore((state) => state.stop);
  const setCurrentTime = useTrackPlaybackStore((state) => state.setCurrentTime);
  const setPlaybackSpeed = useTrackPlaybackStore((state) => state.setPlaybackSpeed);

  const timeSyncKey = `${startTime}:${endTime}`;
  const [editState, setEditState] = useState({ start: '', end: '', syncKey: '' });
  if (editState.syncKey !== timeSyncKey && startTime > 0 && endTime > 0) {
    setEditState({
      start: toDateTimeLocalKST(startTime),
      end: toDateTimeLocalKST(endTime),
      syncKey: timeSyncKey,
    });
  }
  const editStartTime = editState.start;
  const editEndTime = editState.end;
  const setEditStartTime = (v: string) => setEditState((prev) => ({ ...prev, start: v }));
  const setEditEndTime = (v: string) => setEditState((prev) => ({ ...prev, end: v }));

  const [requeryWarning, setRequeryWarning] = useState<string | null>(null);
  const handleRequery = useCallback(() => {
    if (!editStartTime || !editEndTime) return;
    const sMs = new Date(fromDateTimeLocalKST(editStartTime)).getTime();
    const eMs = new Date(fromDateTimeLocalKST(editEndTime)).getTime();
    const maxMs = MAX_QUERY_DAYS * 86_400_000;
    if (eMs - sMs > maxMs) {
      const clamped = toDateTimeLocalKST(sMs + maxMs);
      setEditEndTime(clamped);
      setRequeryWarning(`최대 ${MAX_QUERY_DAYS}일 초과 — 종료일을 자동 조정했습니다`);
      return;
    }
    setRequeryWarning(null);
    requery(fromDateTimeLocalKST(editStartTime), fromDateTimeLocalKST(editEndTime));
  }, [editStartTime, editEndTime, requery]);

  const handleExportCsv = useCallback(() => {
    if (tracks.length === 0) return;
    exportTrackCsv(tracks, queryContext, multiQueryContext);
  }, [tracks, queryContext, multiQueryContext]);

  const progress = useMemo(() => {
    if (endTime <= startTime) return 0;
    return ((currentTime - startTime) / (endTime - startTime)) * 100;
  }, [startTime, endTime, currentTime]);

  const isVisible = isLoading || tracks.length > 0 || !!error;
  const isMultiMode = multiQueryContext != null;
  const vesselCount = tracks.length;
  const [isVesselListExpanded, setIsVesselListExpanded] = useState(false);
  const hasRequeryContext = isMultiMode || !!queryContext;

  if (!isVisible) return null;

  return (
    <div
      style={{
        position: 'absolute',
        bottom: 12,
        left: '50%',
        transform: 'translateX(-50%)',
        width: 'min(95vw, 700px)',
        background: 'rgba(15,23,42,0.94)',
        border: '1px solid rgba(148,163,184,0.35)',
        borderRadius: 12,
        padding: 12,
        color: '#e2e8f0',
        zIndex: 40,
        backdropFilter: 'blur(8px)',
        boxShadow: '0 8px 24px rgba(2,6,23,0.45)',
      }}
    >
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
        <strong style={{ fontSize: 13 }}>
          Track Replay{vesselCount > 0 ? ` (${vesselCount}척)` : ''}
        </strong>
        <div style={{ display: 'flex', gap: 6 }}>
          {onToggleVesselList && (
            <button
              type="button"
              onClick={onToggleVesselList}
              style={{
                fontSize: 11,
                padding: '4px 8px',
                borderRadius: 6,
                border: `1px solid ${isVesselListOpen ? 'rgba(96,165,250,0.7)' : 'rgba(96,165,250,0.35)'}`,
                background: isVesselListOpen ? 'rgba(37,99,235,0.35)' : 'rgba(37,99,235,0.12)',
                color: isVesselListOpen ? '#bfdbfe' : '#93c5fd',
                cursor: 'pointer',
              }}
            >
              선박 목록
            </button>
          )}
          <button
            type="button"
            onClick={() => closeTrackQuery()}
            style={{
              fontSize: 11,
              padding: '4px 8px',
              borderRadius: 6,
              border: '1px solid rgba(148,163,184,0.5)',
              background: 'rgba(30,41,59,0.7)',
              color: '#e2e8f0',
              cursor: 'pointer',
            }}
          >
            닫기
          </button>
        </div>
      </div>

      {error ? <div style={{ marginBottom: 8, color: '#fca5a5', fontSize: 12 }}>{error}</div> : null}
      {requeryWarning ? <div style={{ marginBottom: 8, color: '#fbbf24', fontSize: 12 }}>{requeryWarning}</div> : null}
      {isLoading ? <div style={{ marginBottom: 8, fontSize: 12 }}>항적 조회 중...</div> : null}

      {/* Vessel list — dynamic layout */}
      {isMultiMode && vesselCount > 0 ? (
        <VesselListSection
          tracks={tracks}
          disabledVesselIds={disabledVesselIds}
          toggleVesselEnabled={toggleVesselEnabled}
          vesselCount={vesselCount}
          isExpanded={isVesselListExpanded}
          onToggleExpand={() => setIsVesselListExpanded((v) => !v)}
        />
      ) : vesselCount > 0 ? (
        <div style={{ fontSize: 11, color: '#93c5fd', marginBottom: 6 }}>선박 {vesselCount}척</div>
      ) : null}

      {/* Date range editing */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 4, marginBottom: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <label style={{ fontSize: 11, minWidth: 28, color: '#94a3b8' }}>시작</label>
          <input type="datetime-local" title="시작 시각" value={editStartTime} onChange={(e) => setEditStartTime(e.target.value)} disabled={isLoading || !hasRequeryContext} style={inputStyle} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <label style={{ fontSize: 11, minWidth: 28, color: '#94a3b8' }}>종료</label>
          <input type="datetime-local" title="종료 시각" value={editEndTime} onChange={(e) => setEditEndTime(e.target.value)} disabled={isLoading || !hasRequeryContext} style={inputStyle} />
        </div>
        <div style={{ display: 'flex', gap: 6 }}>
          <button type="button" onClick={handleRequery} disabled={isLoading || !hasRequeryContext || !editStartTime || !editEndTime} style={{ flex: 1, padding: '5px 8px', fontSize: 11, borderRadius: 6, border: '1px solid rgba(96,165,250,0.5)', background: 'rgba(37,99,235,0.25)', color: '#93c5fd', cursor: 'pointer' }}>
            재조회
          </button>
          <button type="button" onClick={handleExportCsv} disabled={isLoading || tracks.length === 0} style={{ flex: 1, padding: '5px 8px', fontSize: 11, borderRadius: 6, border: '1px solid rgba(74,222,128,0.5)', background: 'rgba(22,163,74,0.2)', color: '#86efac', cursor: 'pointer' }}>
            CSV 다운로드
          </button>
        </div>
      </div>

      {/* Playback controls */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 10 }}>
        <button type="button" onClick={() => (isPlaying ? pause() : play())} disabled={tracks.length === 0} style={btnBase}>
          {isPlaying ? '일시정지' : '재생'}
        </button>
        <button type="button" onClick={() => stop()} disabled={tracks.length === 0} style={btnBase}>
          정지
        </button>
        <label style={{ fontSize: 12, display: 'flex', alignItems: 'center', gap: 4 }}>
          배속
          <select value={playbackSpeed} onChange={(event) => setPlaybackSpeed(Number(event.target.value))} style={{ background: 'rgba(30,41,59,0.85)', border: '1px solid rgba(148,163,184,0.45)', borderRadius: 6, color: '#e2e8f0', fontSize: 12, padding: '4px 6px' }}>
            {TRACK_PLAYBACK_SPEED_OPTIONS.map((speed) => (
              <option key={speed} value={speed}>{speed}x</option>
            ))}
          </select>
        </label>
      </div>

      {/* Timeline slider */}
      <div style={{ marginBottom: 10 }}>
        <input type="range" title="타임라인" min={startTime} max={endTime || startTime + 1} value={currentTime} onChange={(event) => setCurrentTime(Number(event.target.value))} style={{ width: '100%' }} disabled={tracks.length === 0 || endTime <= startTime} />
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: '#94a3b8' }}>
          <span>{formatDateTime(currentTime)}</span>
          <span>{Math.max(0, Math.min(100, progress)).toFixed(1)}%</span>
        </div>
      </div>

      {/* Display toggles */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', gap: 6, fontSize: 12 }}>
        <label><input type="checkbox" checked={showPoints} onChange={(event) => setShowPoints(event.target.checked)} /> 포인트</label>
        <label><input type="checkbox" checked={showLabels} onChange={(event) => setShowLabels(event.target.checked)} /> 선명</label>
        <label><input type="checkbox" checked={showTrail} onChange={(event) => setShowTrail(event.target.checked)} /> 잔상</label>
        <label><input type="checkbox" checked={hideLiveShips} onChange={(event) => setHideLiveShips(event.target.checked)} /> 라이브 숨김</label>
      </div>
    </div>
  );
}

/* ── Vessel list sub-component ── */

interface VesselListSectionProps {
  tracks: ProcessedTrack[];
  disabledVesselIds: Set<string>;
  toggleVesselEnabled: (vesselId: string) => void;
  vesselCount: number;
  isExpanded: boolean;
  onToggleExpand: () => void;
}

function VesselListSection({ tracks, disabledVesselIds, toggleVesselEnabled, vesselCount, isExpanded, onToggleExpand }: VesselListSectionProps) {
  const showExpandToggle = vesselCount >= 5;
  const alwaysShow = vesselCount <= 4;
  const isListVisible = alwaysShow || isExpanded;

  return (
    <div style={{ marginBottom: 8 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
        <span style={{ fontSize: 11, color: '#93c5fd' }}>선박 {vesselCount}척</span>
        {showExpandToggle && (
          <button type="button" onClick={onToggleExpand} style={{ fontSize: 10, color: '#94a3b8', background: 'none', border: 'none', cursor: 'pointer', padding: '2px 4px' }}>
            {isExpanded ? '▴ 접기' : '▾ 펼치기'}
          </button>
        )}
      </div>
      {isListVisible && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, maxHeight: showExpandToggle ? 120 : undefined, overflowY: showExpandToggle ? 'auto' : undefined }}>
          {tracks.map((track) => {
            const isEnabled = !disabledVesselIds.has(track.vesselId);
            const kindColor = SHIP_KIND_COLORS[track.shipKindCode] || '#607D8B';
            return (
              <label key={track.vesselId} style={{ display: 'inline-flex', alignItems: 'center', gap: 3, padding: '2px 6px', borderRadius: 999, background: isEnabled ? 'rgba(148,163,184,0.12)' : 'rgba(148,163,184,0.04)', fontSize: 10, color: isEnabled ? '#cbd5e1' : '#64748B', cursor: 'pointer', opacity: isEnabled ? 1 : 0.5 }}>
                <input type="checkbox" checked={isEnabled} onChange={() => toggleVesselEnabled(track.vesselId)} style={{ width: 10, height: 10, accentColor: kindColor }} />
                <span style={{ width: 6, height: 6, borderRadius: '50%', background: kindColor, flexShrink: 0 }} />
                {track.shipName}
                <span style={{ color: '#64748B' }}>({track.targetId.slice(-5)})</span>
              </label>
            );
          })}
        </div>
      )}
    </div>
  );
}
