import { formatDate } from '@transferwise/formatting';
import { useIntl } from 'react-intl';

import { getFocusableTime } from '../../getFocusableTime/getFocusableTime';
import TableLink from '../../tableLink';

interface MonthCalendarTableProps {
  selectedDate: Date | null;
  min: Date | null;
  max: Date | null;
  viewYear: number;
  placeholder: string;
  onSelect: (date: number) => void;
}

const ROWS = 3;
const COLS = 4;
const MONTH_ONLY_FORMAT: Intl.DateTimeFormatOptions = { month: 'short' };

const MonthCalendarTable = ({
  selectedDate,
  min,
  max,
  viewYear,
  placeholder,
  onSelect,
}: MonthCalendarTableProps) => {
  const { locale } = useIntl();

  const getLink = (month: number) => {
    return (
      <TableLink
        item={month}
        type="month"
        title={formatDate(new Date(viewYear, month), locale, MONTH_ONLY_FORMAT)}
        active={isActive(month)}
        disabled={isDisabled(month)}
        today={viewYear === new Date().getFullYear() && month === new Date().getMonth()}
        autofocus={autofocusMonth === month}
        onClick={onSelect}
      />
    );
  };

  const isActive = (month: number) => {
    return !!(
      selectedDate &&
      month === selectedDate.getMonth() &&
      viewYear === selectedDate.getFullYear()
    );
  };

  const isThisMonth = (month: number) => {
    return viewYear === new Date().getFullYear() && month === new Date().getMonth();
  };

  const isDisabled = (month: number) => {
    const date = new Date(viewYear, month);
    return !!(
      (min && date < new Date(min.getFullYear(), min.getMonth())) ||
      (max && date > new Date(max.getFullYear(), max.getMonth()))
    );
  };

  const autofocusMonth = (() => {
    const months = Array.from({ length: ROWS * COLS }, (_, index) => index);
    return getFocusableTime({ isActive, isNow: isThisMonth, isDisabled, timeSpan: months });
  })();

  return (
    <table className="table table-condensed table-bordered tw-date-lookup-calendar np-text-body-default-bold m-b-0">
      <thead className="sr-only">
        <tr>
          <th colSpan={COLS}>{placeholder}</th>
        </tr>
      </thead>
      <tbody>
        {Array.from({ length: ROWS }, (_, rowIndex) => (
          <tr key={rowIndex}>
            {Array.from({ length: COLS }, (_, colIndex) => (
              <td key={colIndex}>{getLink(rowIndex * COLS + colIndex)}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default MonthCalendarTable;
