import { Fragment } from 'react';
import type { MouseEvent } from 'react';
import { RouteSegment } from '../RouteSegment/RouteSegment';
import type { StructureType, StructureSegment } from '../../types/timeline';
import {
  TRACK_RENDER_END_PX,
  TRACK_RENDER_START_PX,
  TRACK_START_PX,
  TRACK_WIDTH_PX,
  TRACK_WRAPPER_TRANSFORM,
} from '../../mocks/route';
import type { KmLabel, StructMark } from '../../StationBar';
import { cssVars, px } from '../../utils/cssVars';
import { MileageMarker } from '../MileageMarker/MileageMarker';
import styles from './Timeline.module.scss';

/** 미터값 → "158k160" (10m 단위). 음수면 빈 문자열. */
function fmtKm(m: number): string {
  if (m < 0) return '';
  const r = Math.round(m / 10) * 10;
  return `${Math.floor(r / 1000)}k${String(r % 1000).padStart(3, '0')}`;
}

interface TimelineProps {
  posPx: number;
  onSeekDown: (e: MouseEvent<HTMLDivElement>) => void;
  /** 통과 구간 트랙 gradient (전진=주황/후진=청록). */
  trackGradient: string;
  /** 미통과 구간 트랙 gradient (전진=회색/후진=청회색). */
  trackGradientIdle: string;
  /** 색(방향)이 바뀌는 전환점 px(스테이지 좌표) — 구분선 위치. */
  dividers: number[];
  /** 데이터 기반 측점값 라벨 (방향 전환점·시종점). */
  kmLabels: KmLabel[];
  /** 데이터 기반 구조물 (교량/터널/역사). */
  structures: StructMark[];
  /** 시점 역명 (route.json routeInfo 우선, 없으면 첫 측점 title). */
  startStationName?: string;
  /** 종점 역명 (route.json routeInfo 우선, 없으면 끝 측점 title). */
  endStationName?: string;
}

export function Timeline({
  posPx,
  onSeekDown,
  trackGradient,
  trackGradientIdle,
  dividers,
  kmLabels,
  structures,
  startStationName,
  endStationName,
}: TimelineProps) {
  // 라벨 겹침 방지: x px 순으로 gap px 이내는 1개만 표시.
  const dedup = <T extends { px: number }>(items: T[], gap: number): T[] => {
    const sorted = [...items].sort((a, b) => a.px - b.px);
    const out: T[] = [];
    for (const it of sorted) {
      if (!out.length || it.px - out[out.length - 1].px >= gap) out.push(it);
    }
    return out;
  };
  // 구조물명은 텍스트가 길어 더 넓은 간격으로 (겹침 방지).
  const structs = dedup(structures, 90);

  return (
    <>
      {/* 압축 밖 레이어: 상단 그라데이션과 역명 리더선 */}
      <div className={styles.trackFade} />

      {/* 역명 레이어: 트랙 시작/끝(단일 소스) 기준 시·종점 역명 배치 (route.json/측점 유래) */}
      <div
        className={styles.stationLayer}
        style={cssVars({
          '--track-start': px(TRACK_RENDER_START_PX),
          '--track-end': px(TRACK_RENDER_END_PX),
        })}
      >
        {/* 좌측(시점)=역방향 하늘색, 우측(종점)=정방향 주황 */}
        <div className={styles.stationStart} style={{ color: '#06a4c8' }}>{startStationName ?? ''}</div>
        <div className={styles.dotStart} style={{ background: '#06a4c8' }} />
        <div className={styles.leaderStart} style={cssVars({ '--color-station-leader': '#06a4c8' })} />
        <div className={styles.leaderEnd} style={cssVars({ '--color-station-leader': '#ff8a25' })} />
        <div className={styles.dotEnd} style={{ background: '#ff8a25' }} />
        <div className={styles.stationEnd} style={{ color: '#ff8a25' }}>{endStationName ?? ''}</div>
      </div>

      {/* 트랙 본체 (가로 압축 래퍼) */}
      <div
        className={styles.trackWrapper}
        style={{
          ...cssVars({
            '--track-x': px(TRACK_START_PX),
            '--track-w': px(TRACK_WIDTH_PX),
          }),
          transform: TRACK_WRAPPER_TRANSFORM,
        }}
      >
        <div className={styles.trackFrame} />
        <div className={styles.trackFrameStripesH} />
        <div className={styles.trackFrameStripesV} />
        <div className={styles.trackBase} />

        {/* 데이터 기반 색 트랙(그라데이션): 전진=주황 / 후진=하늘색.
            전체는 저톤(드론 순/역방향 미리보기), 재생되어 커서가 지나간 구간은 원래 색으로 복원. */}
        <div className={styles.track}>
          {/* 미재생(미통과): 회색/청회색 (전체 폭) */}
          <div
            style={{
              position: 'absolute',
              left: 0,
              top: 0,
              height: '100%',
              width: px(TRACK_WIDTH_PX),
              background: trackGradientIdle,
              opacity: 1,
              borderRadius: 'inherit',
            }}
          />
          {/* 재생된 구간: 원래 색 복원 (커서까지 clip). 폭은 CSS 변수(--pos-px)로 매 프레임
              직접 갱신되어 React 리렌더 없이 부드럽게 늘어난다. */}
          <div
            style={{
              position: 'absolute',
              left: 0,
              top: 0,
              height: '100%',
              width: `max(0px, min(${TRACK_WIDTH_PX}px, calc(var(--pos-px, ${TRACK_START_PX}px) - ${TRACK_START_PX}px)))`,
              overflow: 'hidden',
            }}
          >
            <div
              style={{
                position: 'absolute',
                left: 0,
                top: 0,
                height: '100%',
                width: px(TRACK_WIDTH_PX),
                background: trackGradient,
                borderRadius: 'inherit',
              }}
            />
          </div>
          {/* 색(방향) 전환점 구분선 — videoplayer leg 솔기와 동일(검정+흰색 점선) */}
          {dividers.map((dpx, i) => (
            <div
              key={`div-${i}`}
              style={{
                position: 'absolute',
                left: dpx - TRACK_START_PX,
                top: 0,
                width: 0,
                height: '100%',
                transform: 'translateX(-1px)',
                borderLeft: '1px dashed rgba(0, 0, 0, 0.7)',
                borderRight: '1px dashed rgba(255, 255, 255, 0.3)',
                zIndex: 3,
                pointerEvents: 'none',
              }}
            />
          ))}
        </div>

        {/* 측점값 라벨 — 각 시설물 측점값(아이콘 위) */}
        <div className={styles.mileageRow}>
          {structs.map((s, i) =>
            s.km >= 0 ? (
              <MileageMarker
                key={`stkm-${i}`}
                marker={{ id: `stkm-${i}`, value: fmtKm(s.km), left: s.px, mileage: 0 }}
              />
            ) : null,
          )}
        </div>

        {/* 구조물 아이콘 — 재생바 위에 겹쳐 표시 (videoplayer 3-slice) */}
        <div style={{ position: 'absolute', inset: 0, zIndex: 4, pointerEvents: 'none' }}>
          {structs.map((s, i) => {
            // 두 상태(무채색 upcoming / 유채색 passed) 아이콘을 겹쳐두고 opacity 로 전환 →
            // 배경이미지 교체가 없어 전환 순간 깜빡임(사라짐)이 없다.
            // 역사/터미널 → 원형 아이콘
            if (s.category === '역사' || s.category === '역') {
              const D = 18;
              // 라벨과 동일 트리거(라벨 W=22 → s.px-11). 아이콘·라벨 동시 전환.
              const passed = posPx >= s.px - 11;
              const base = import.meta.env.BASE_URL;
              const common = {
                position: 'absolute' as const,
                left: s.px - D / 2,
                top: 40.5 - D / 2,
                width: D,
                height: D,
                transition: 'opacity 0.12s',
              };
              return (
                <Fragment key={i}>
                  <img src={`${base}assets/route-segment/terminal/circle-upcoming.png`} alt="" style={{ ...common, opacity: passed ? 0 : 1 }} />
                  <img src={`${base}assets/route-segment/terminal/circle-passed.png`} alt="" style={{ ...common, opacity: passed ? 1 : 0 }} />
                </Fragment>
              );
            }
            const segType: StructureType | null =
              s.category === '터널' ? 'tunnel' : s.category === '교량' ? 'bridge' : null;
            if (!segType) return null;
            // 원본(videoplayer) 치수: 교량 22×16/cap6/top32.5, 터널 24×14/cap10/top33.75
            const isTunnel = segType === 'tunnel';
            const W = isTunnel ? 24 : 22;
            const H = isTunnel ? 14 : 16;
            const CAP = isTunnel ? 10 : 6;
            const TOP = isTunnel ? 33.75 : 32.5;
            const passed = posPx >= s.px - W / 2;
            const seg: StructureSegment = {
              id: `st-${i}`,
              type: segType,
              label: s.title,
              startMileage: 0,
              endMileage: 0,
              left: s.px - W / 2,
              top: TOP,
              width: W,
              height: H,
              capWidth: CAP,
              centerHeight: H,
              passedAtPx: 0,
            };
            const layer = (op: number) =>
              ({ position: 'absolute' as const, inset: 0, opacity: op, transition: 'opacity 0.12s' });
            return (
              <Fragment key={i}>
                <div style={layer(passed ? 0 : 1)}><RouteSegment segment={seg} state="upcoming" /></div>
                <div style={layer(passed ? 1 : 0)}><RouteSegment segment={seg} state="passed" /></div>
              </Fragment>
            );
          })}
        </div>

        {/* 구조물명 라벨 (바 아래) — 통과 시 아이콘과 함께 색 변경 */}
        <div className={styles.labelRow}>
          {structs.map((s, i) => {
            const W = s.category === '터널' ? 24 : 22;
            const passed = posPx >= s.px - W / 2;
            return (
              <div
                key={i}
                className={`${styles.segmentLabel} ${passed ? styles.accent : styles.neutral}`}
                style={cssVars({ '--x': px(s.px) })}
                title={`${s.category} · ${s.title} (${fmtKm(s.km)})`}
              >
                {s.title}
              </div>
            );
          })}
        </div>

        <div className={styles.seekArea} onMouseDown={onSeekDown} />
      </div>
    </>
  );
}
