"use client";

import { useMemo, useState } from "react";

import { clampNumber, formatSecondsAsTimecode, parseTimecodeInput } from "@/lib/client/time-format";

interface SingleSliderSyncOptions {
  min: number;
  max: number;
  initialValue?: number;
}

export function useSingleSliderSync({
  min,
  max,
  initialValue = min
}: SingleSliderSyncOptions) {
  const safeMin = Math.min(min, max);
  const safeMax = Math.max(min, max);
  const [value, setValue] = useState(() => clampNumber(initialValue, safeMin, safeMax));
  const [inputValue, setInputValue] = useState(() =>
    formatSecondsAsTimecode(clampNumber(initialValue, safeMin, safeMax))
  );

  const syncedValue = useMemo(() => clampNumber(value, safeMin, safeMax), [value, safeMin, safeMax]);

  const setFromSlider = (nextValue: number) => {
    const clamped = clampNumber(nextValue, safeMin, safeMax);
    setValue(clamped);
    setInputValue(formatSecondsAsTimecode(clamped));
  };

  const commitInput = (rawInput: string) => {
    const parsed = parseTimecodeInput(rawInput);
    if (parsed === null) {
      setInputValue(formatSecondsAsTimecode(syncedValue));
      return syncedValue;
    }

    const clamped = clampNumber(parsed, safeMin, safeMax);
    setValue(clamped);
    setInputValue(formatSecondsAsTimecode(clamped));
    return clamped;
  };

  return {
    value: syncedValue,
    inputValue,
    setInputValue,
    setFromSlider,
    commitInput
  };
}

interface DualSliderSyncOptions {
  min: number;
  max: number;
  initialStart?: number;
  initialEnd?: number;
  minimumGap?: number;
}

export function useDualSliderSync({
  min,
  max,
  initialStart = min,
  initialEnd = max,
  minimumGap = 0
}: DualSliderSyncOptions) {
  const safeMin = Math.min(min, max);
  const safeMax = Math.max(min, max);
  const [start, setStart] = useState(() => clampNumber(initialStart, safeMin, safeMax));
  const [end, setEnd] = useState(() => clampNumber(initialEnd, safeMin, safeMax));

  const normalizedStart = Math.min(start, end);
  const normalizedEnd = Math.max(start, end);

  const [startInput, setStartInput] = useState(() => formatSecondsAsTimecode(normalizedStart));
  const [endInput, setEndInput] = useState(() => formatSecondsAsTimecode(normalizedEnd));

  const setRange = (nextStart: number, nextEnd: number) => {
    const clampedStart = clampNumber(nextStart, safeMin, safeMax);
    const clampedEnd = clampNumber(nextEnd, safeMin, safeMax);
    const orderedStart = Math.min(clampedStart, clampedEnd);
    const orderedEnd = Math.max(clampedStart, clampedEnd);
    const gapSafeEnd = Math.max(orderedEnd, orderedStart + minimumGap);
    const finalEnd = clampNumber(gapSafeEnd, safeMin, safeMax);
    const finalStart = clampNumber(Math.min(orderedStart, finalEnd - minimumGap), safeMin, safeMax);

    setStart(finalStart);
    setEnd(finalEnd);
    setStartInput(formatSecondsAsTimecode(finalStart));
    setEndInput(formatSecondsAsTimecode(finalEnd));
  };

  const commitStartInput = (rawInput: string) => {
    const parsed = parseTimecodeInput(rawInput);
    if (parsed === null) {
      setStartInput(formatSecondsAsTimecode(normalizedStart));
      return normalizedStart;
    }

    const nextStart = clampNumber(parsed, safeMin, normalizedEnd - minimumGap);
    setRange(nextStart, normalizedEnd);
    return nextStart;
  };

  const commitEndInput = (rawInput: string) => {
    const parsed = parseTimecodeInput(rawInput);
    if (parsed === null) {
      setEndInput(formatSecondsAsTimecode(normalizedEnd));
      return normalizedEnd;
    }

    const nextEnd = clampNumber(parsed, normalizedStart + minimumGap, safeMax);
    setRange(normalizedStart, nextEnd);
    return nextEnd;
  };

  return {
    start: normalizedStart,
    end: normalizedEnd,
    startInput,
    endInput,
    setStartInput,
    setEndInput,
    setRange,
    commitStartInput,
    commitEndInput
  };
}
