import { DateTime } from 'luxon';
import React, { useState } from 'react';
import { noop } from '../../../helpers/utils';
import { ScrollColumn } from './ScrollColumn/ScrollColumn';
import classes from './TimePicker.scss';

export interface TimePickerProps {
  /** Current value  */
  value: DateTime;

  /** Whether seconds column should be shown. (Default: false) */
  showSeconds?: boolean;

  /** Whether the time picker should be showin in 12 hour format or 24 hour format. (Default: false) */
  hours12?: boolean;

  /** Callback triggered when a new value is selected */
  onSelected?: (value: DateTime) => void;
}

enum ActiveSelector {
  Hours = 'Hours',
  Minutes = 'Minutes',
  Seconds = 'Seconds',
  AMPM = 'AM / PM',
}

export const TimePicker: React.FC<TimePickerProps> = ({
  value,
  showSeconds = false,
  hours12 = false,
  onSelected = noop,
}) => {
  const [time, setTime] = useState<DateTime>(value);

  const [active, setActive] = useState<ActiveSelector>();
  const [ampm, setAmPm] = useState<'AM' | 'PM'>(time.hour > 12 ? 'PM' : 'AM');

  return (
    <div className={classes.container}>
      <div className={classes.title}>{active ?? 'Time'}</div>
      <ScrollColumn
        items={hours12 ? [...Array(12).keys()] : [...Array(24).keys()]}
        selectedItem={hours12 ? time.hour % 12 : time.hour}
        onSelected={(value) => {
          if (active !== ActiveSelector.Hours) {
            setActive(ActiveSelector.Hours);
          } else if (time.hour !== value) {
            const newTime = time.set({
              hour: hours12 && ampm === 'PM' ? value + 12 : value,
            });

            setTime(newTime);
            onSelected(newTime);
          } else {
            setActive(undefined);
          }
        }}
        isActive={active === ActiveSelector.Hours}
        inActiveTitle={ActiveSelector.Hours}
      />
      <ScrollColumn
        items={Array.from({ length: 12 }, (_, i) => i * 5)}
        selectedItem={time.minute}
        onSelected={(value) => {
          if (active !== ActiveSelector.Minutes) {
            setActive(ActiveSelector.Minutes);
          } else if (time.minute !== value) {
            const newTime = time.set({ minute: value });

            setTime(newTime);
            onSelected(newTime);
          } else {
            setActive(undefined);
          }
        }}
        isActive={active === ActiveSelector.Minutes}
        inActiveTitle={ActiveSelector.Minutes}
      />
      {showSeconds && (
        <ScrollColumn
          items={Array.from({ length: 12 }, (_, i) => i * 5)}
          selectedItem={time.second}
          onSelected={(value) => {
            if (active !== ActiveSelector.Seconds) {
              setActive(ActiveSelector.Seconds);
            } else if (time.second !== value) {
              const newTime = time.set({ second: value });

              setTime(newTime);
              onSelected(newTime);
            } else {
              setActive(undefined);
            }
          }}
          isActive={active === ActiveSelector.Seconds}
          inActiveTitle={ActiveSelector.Seconds}
        />
      )}
      {hours12 && (
        <ScrollColumn<'AM' | 'PM'>
          items={['AM', 'PM']}
          selectedItem={ampm}
          onSelected={(value) => {
            if (active !== ActiveSelector.AMPM) {
              setActive(ActiveSelector.AMPM);
            } else if (ampm !== value) {
              setAmPm(value);

              const newTime = time.set({
                hour: value === 'PM' ? time.hour + 12 : time.hour,
              });

              setTime(newTime);
              onSelected(newTime);
            } else {
              setActive(undefined);
            }
          }}
          isActive={active === ActiveSelector.AMPM}
          inActiveTitle={ActiveSelector.AMPM}
        />
      )}
    </div>
  );
};
