import { useMemo } from 'react';

import type { FC } from 'react';
import type { SelectButtonProps, SelectProps } from '../Select2/types';
import type { TimePickerOption } from './types';

import useIsLargeScreen from '~/src/hooks/useIsLargeScreen';
import Button from '../Button';
import ClockIcon from '../Icon/ClockIcon';
import { FastSelectOption, Select } from '../Select2';
import { isTime } from './utils';

export interface TimePickerProps
  extends Omit<
    SelectProps<TimePickerOption>,
    'testId' | 'placeholder' | 'renderButton' | 'renderOption' | 'options'
  > {
  testId?: string;
  step?: number; // in minutes
}

const PLACEHOLDER = 'Select time';

export const TimePicker: FC<TimePickerProps> = ({
  testId = 'timePicker',
  step,
  ...selectProps
}) => {
  const options = useMemo(() => generateTimeOptions(step), [step]);

  return (
    <Select<TimePickerOption>
      {...selectProps}
      testId={testId}
      placeholder={PLACEHOLDER}
      options={options}
      renderOption={(props) => <FastSelectOption {...props} />}
      renderButton={(props) => <TimeButton {...props} />}
    />
  );
};

const TimeButton = ({
  testId,
  option,
  isEmpty,
  isDisabled,
  open,
}: SelectButtonProps<TimePickerOption>) => {
  const isLargeScreen = useIsLargeScreen();

  return (
    <Button
      testId={`${testId}Button`}
      text={option?.text ?? PLACEHOLDER}
      withDisabledStyle={false}
      isUppercase={false}
      isCentered={false}
      isDisabled={isDisabled}
      textProps={{
        color: isEmpty ? '#999' : '#fff',
        margin: '0 2.6rem 0 0',
        size: isLargeScreen ? '1.4rem' : '1.7rem',
      }}
      renderAfter={() => <ClockIcon size="2rem" color="#666" />}
      onClick={open}
    />
  );
};

const generateTimeOptions = (
  step: TimePickerProps['step'] = 1
): TimePickerOption[] => {
  if (step < 1) {
    throw new Error('Invalid step value (must be at least 1)');
  }

  const options: TimePickerOption[] = [];

  for (let total = 0; total < 24 * 60; total += step) {
    const hours = Math.floor(total / 60);
    const minutes = total % 60;

    const hour = hours.toString().padStart(2, '0');
    const min = minutes.toString().padStart(2, '0');

    const time = `${hour}:${min}`;

    if (isTime(time)) {
      options.push({
        id: time,
        text: time,
      });
    }
  }

  return options;
};
