import type { RouteProgressState, StructureSegment, TerminalMarker } from '../types/timeline';

/** Resolves bridge/tunnel marker state from cursor position and segment metadata. */
export function resolveStructureState(
  posPx: number,
  segment: StructureSegment,
): Extract<RouteProgressState, 'upcoming' | 'passed' | 'revisit'> {
  if (segment.appearance === 'passed') {
    return 'passed';
  }
  if (segment.appearance === 'revisit') {
    // 같은 구간을 두 번째로 지나는 아이콘:
    // 방향 전환점(flipAtPx) 전엔 반전(revisit), 이후엔 일반 upcoming →
    // 커서가 지나면(passedAtPx) passed.
    if (segment.flipAtPx !== undefined) {
      if (posPx < segment.flipAtPx) return 'revisit';
      return posPx >= segment.passedAtPx ? 'passed' : 'upcoming';
    }
    // 반복쌍의 뒤 아이콘: 메인이 교환되는 지점을 지나면 passed, 그 전엔 revisit
    if (segment.swapAtPx !== undefined) {
      return posPx >= segment.swapAtPx ? 'passed' : 'revisit';
    }
    return posPx >= segment.passedAtPx ? 'revisit' : 'upcoming';
  }
  // 메인 아이콘: upcoming → (시작점 통과) passed → (아이콘 벗어남) revisit
  if (segment.swapAtPx !== undefined && posPx >= segment.swapAtPx) {
    return 'revisit';
  }
  return posPx >= segment.passedAtPx ? 'passed' : 'upcoming';
}

/** Resolves terminal circle state. Passed terminals keep orange permanently. */
export function resolveTerminalState(
  posPx: number,
  marker: TerminalMarker,
): Extract<RouteProgressState, 'upcoming' | 'passed' | 'revisit'> {
  if (marker.state === 'revisit') return 'revisit';
  if (marker.state === 'passed' && marker.passedAtPx === undefined) return 'passed';
  if (marker.passedAtPx !== undefined) {
    return posPx >= marker.passedAtPx ? 'passed' : 'upcoming';
  }
  return marker.state;
}

/** Derives segment progress state from mileage range and current mileage. */
export function resolveSegmentStateFromMileage(
  currentMileage: number,
  startMileage: number,
  endMileage: number,
  appearance: StructureSegment['appearance'] = 'dynamic',
): RouteProgressState {
  const lo = Math.min(startMileage, endMileage);
  const hi = Math.max(startMileage, endMileage);

  if (appearance === 'passed') return 'passed';
  if (appearance === 'revisit') {
    return currentMileage >= lo ? 'revisit' : 'upcoming';
  }
  if (currentMileage > hi) return 'passed';
  if (currentMileage >= lo && currentMileage <= hi) return 'current';
  return 'upcoming';
}
