import { useState, useEffect, useCallback } from "react";
import { Stack, Text, Group, TextInput, Button } from "@mantine/core";
import { Trans, useLingui } from "@lingui/react/macro";

interface DurationPickerProps {
  songDurationMs: number;
  initialStart?: number;
  initialEnd?: number;
  onChange: (startSeconds: number, endSeconds: number) => void;
  disabled?: boolean;
}

interface IncrementButtonsProps {
  onAdjust: (seconds: number) => void;
  disabled: boolean;
  isPositive?: boolean;
}

const IncrementButtons = ({ onAdjust, disabled, isPositive = true }: IncrementButtonsProps) => {
  const { t } = useLingui();
  const increments = [1, 5, 30, 60];
  const labels = [t`1s`, t`5s`, t`30s`, t`1m`];

  return (
    <Group gap={3} wrap="nowrap" flex={1}>
      {increments.map((increment, index) => (
        <Button
          key={increment}
          variant={isPositive ? "light" : "outline"}
          color={isPositive ? "blue" : "gray"}
          size="xs"
          disabled={disabled}
          onClick={() => onAdjust(isPositive ? increment : -increment)}
          flex={1}
          h={24}
          style={{
            fontSize: '10px',
            fontWeight: 500,
            minWidth: 0
          }}
        >
          {isPositive ? '+' : '-'}{labels[index]}
        </Button>
      ))}
    </Group>
  );
};

const DurationPicker = ({
  songDurationMs,
  initialStart = 0,
  initialEnd = 15,
  onChange,
  disabled = false,
}: DurationPickerProps) => {
  const { t } = useLingui();
  const songDurationSeconds = Math.floor(songDurationMs / 1000);

  const formatTime = useCallback((seconds: number) => {
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
  }, []);

  const [startTime, setStartTime] = useState(initialStart);
  const [endTime, setEndTime] = useState(initialEnd);
  const [isValid, setIsValid] = useState(true);
  const [startInputValue, setStartInputValue] = useState(formatTime(initialStart));
  const [endInputValue, setEndInputValue] = useState(formatTime(initialEnd));

  const parseTimeInput = useCallback((input: string): number | null => {
    if (input.includes(':')) {
      const parts = input.split(':');
      if (parts.length === 2) {
        const minutes = parseInt(parts[0]) || 0;
        const seconds = parseInt(parts[1]) || 0;
        return minutes * 60 + seconds;
      }
    }
    const parsed = parseInt(input);
    return isNaN(parsed) ? null : parsed;
  }, []);

  const validateTimes = useCallback(
    (start: number, end: number) => {
      const duration = end - start;
      const withinBounds = start >= 0 && end <= songDurationSeconds;
      const validDuration = duration >= 10 && duration <= 15;
      return withinBounds && validDuration;
    },
    [songDurationSeconds]
  );

  const getValidationMessage = useCallback((start: number, end: number) => {
    const duration = end - start;
    if (start < 0 || end > songDurationSeconds) {
      return t`Segment must be within song duration`;
    }
    if (duration < 10) {
      return t`Segment must be at least 10 seconds`;
    }
    if (duration > 15) {
      return t`Segment must be no more than 15 seconds`;
    }
    return null;
  }, [songDurationSeconds, t]);

  const updateTimes = useCallback((newStart: number, newEnd: number) => {
    const clampedStart = Math.max(0, Math.min(newStart, songDurationSeconds - 10));
    const clampedEnd = Math.min(songDurationSeconds, Math.max(newEnd, clampedStart + 10));

    setStartTime(clampedStart);
    setEndTime(clampedEnd);
    setStartInputValue(formatTime(clampedStart));
    setEndInputValue(formatTime(clampedEnd));

    const valid = validateTimes(clampedStart, clampedEnd);
    setIsValid(valid);

    if (valid) {
      onChange(clampedStart, clampedEnd);
    }
  }, [songDurationSeconds, validateTimes, onChange, formatTime]);

  const handleStartInputChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    setStartInputValue(event.target.value);
  }, []);

  const handleEndInputChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    setEndInputValue(event.target.value);
  }, []);

  const handleStartBlur = useCallback(() => {
    const parsed = parseTimeInput(startInputValue);
    if (parsed !== null) {
      updateTimes(parsed, endTime);
    } else {
      setStartInputValue(formatTime(startTime));
    }
  }, [startInputValue, endTime, updateTimes, parseTimeInput, formatTime, startTime]);

  const handleEndBlur = useCallback(() => {
    const parsed = parseTimeInput(endInputValue);
    if (parsed !== null) {
      updateTimes(startTime, parsed);
    } else {
      setEndInputValue(formatTime(endTime));
    }
  }, [endInputValue, startTime, updateTimes, parseTimeInput, formatTime, endTime]);

  const adjustStartTime = useCallback((seconds: number) => {
    updateTimes(startTime + seconds, endTime);
  }, [startTime, endTime, updateTimes]);

  const adjustEndTime = useCallback((seconds: number) => {
    updateTimes(startTime, endTime + seconds);
  }, [startTime, endTime, updateTimes]);

  useEffect(() => {
    if (!validateTimes(initialStart, initialEnd)) {
      const defaultStart = Math.min(30, Math.max(0, songDurationSeconds - 15));
      const defaultEnd = Math.min(defaultStart + 15, songDurationSeconds);
      updateTimes(defaultStart, defaultEnd);
    }
  }, [initialStart, initialEnd, songDurationSeconds, validateTimes, updateTimes]);

  const segmentDuration = endTime - startTime;

  return (
    <Stack gap="sm" opacity={disabled ? 0.5 : 1}>
      <Text size="sm" fw={500} c={disabled ? "dimmed" : undefined} ta="center">
        <Trans>Walkout Segment ({segmentDuration}s)</Trans>
      </Text>

      <Stack gap="sm">
        <Stack gap={4}>
          <Group justify="space-between" align="center">
            <Text size="xs" fw={500} c={disabled ? "dimmed" : undefined}>
              <Trans>Start</Trans>
            </Text>
            <TextInput
              value={startInputValue}
              onChange={handleStartInputChange}
              onBlur={handleStartBlur}
              disabled={disabled}
              size="xs"
              w={70}
              placeholder="0:00"
              ta="center"
              styles={{
                input: {
                  fontWeight: 600,
                  fontSize: '12px'
                }
              }}
            />
          </Group>
          <Group gap={4}>
            <IncrementButtons
              onAdjust={adjustStartTime}
              disabled={disabled || startTime <= 0}
              isPositive={false}
            />
            <IncrementButtons
              onAdjust={adjustStartTime}
              disabled={disabled || startTime >= songDurationSeconds - 10}
              isPositive={true}
            />
          </Group>
        </Stack>

        <Stack gap={4}>
          <Group justify="space-between" align="center">
            <Text size="xs" fw={500} c={disabled ? "dimmed" : undefined}>
              <Trans>End</Trans>
            </Text>
            <TextInput
              value={endInputValue}
              onChange={handleEndInputChange}
              onBlur={handleEndBlur}
              disabled={disabled}
              size="xs"
              w={70}
              placeholder="0:15"
              ta="center"
              styles={{
                input: {
                  fontWeight: 600,
                  fontSize: '12px'
                }
              }}
            />
          </Group>
          <Group gap={4}>
            <IncrementButtons
              onAdjust={adjustEndTime}
              disabled={disabled || endTime <= startTime + 10}
              isPositive={false}
            />
            <IncrementButtons
              onAdjust={adjustEndTime}
              disabled={disabled || endTime >= songDurationSeconds}
              isPositive={true}
            />
          </Group>
        </Stack>
      </Stack>

      {!isValid && (
        <Text size="xs" c="red" ta="center">
          {getValidationMessage(startTime, endTime)}
        </Text>
      )}
    </Stack>
  );
};

export default DurationPicker;
