import React from "react";
import type { Locale } from "react-day-picker";
import { DateLib } from "react-day-picker";
import {
  amET,
  getDateLib as getDateLibEthiopic,
} from "react-day-picker/ethiopic";
import * as locales from "react-day-picker/locale";
import {
  faIR,
  getDateLib as getDateLibPersian,
} from "react-day-picker/persian";

import styles from "./styles.module.css";
import type { DayPickerPropsWithCalendar } from "./useQueryStringSync";

interface CustomizationFieldsetProps {
  props: DayPickerPropsWithCalendar;
  setProps: React.Dispatch<React.SetStateAction<DayPickerPropsWithCalendar>>;
  accentColor: string;
  setAccentColor: React.Dispatch<React.SetStateAction<string>>;
}

function resolveDateLib(props: DayPickerPropsWithCalendar) {
  if (props.calendar === "persian") {
    return getDateLibPersian({
      locale: (props.locale as Locale) ?? faIR,
      timeZone: props.timeZone,
      numerals: props.numerals,
    });
  }
  if (props.calendar === "ethiopic") {
    return getDateLibEthiopic({
      locale: (props.locale as Locale) ?? (amET as Locale),
      timeZone: props.timeZone,
      numerals: props.numerals,
    });
  }
  return new DateLib({
    locale: (props.locale as Locale) ?? locales.enUS,
    timeZone: props.timeZone,
  });
}

function resolveReferenceDate(
  props: DayPickerPropsWithCalendar,
  dateLib: DateLib,
) {
  const candidates = [props.month, props.startMonth, props.defaultMonth];
  for (const candidate of candidates) {
    if (candidate instanceof Date) return candidate;
  }
  return dateLib.today();
}

export function CustomizationFieldset({
  props,
  setProps,
  accentColor,
  setAccentColor,
}: CustomizationFieldsetProps) {
  return (
    <fieldset>
      <legend>
        Customization{" "}
        <button
          type="button"
          onClick={() => {
            setProps({
              ...props,
              captionLayout: undefined,
              navLayout: undefined,
              showOutsideDays: false,
              showWeekNumber: false,
              fixedWeeks: false,
              hideWeekdays: false,
              reverseYears: false,
              startMonth: undefined,
              endMonth: undefined,
            });
            setAccentColor("");
          }}
        >
          Reset
        </button>
      </legend>
      <div className={styles.fields}>
        <label>
          Navigation Layout:
          <select
            name="navLayout"
            value={props.navLayout ?? ""}
            onChange={(e) => {
              const newProps: DayPickerPropsWithCalendar = {
                ...props,
                navLayout: (e.target.value ?? undefined) as
                  | "around"
                  | "after"
                  | undefined,
              };
              setProps(newProps);
            }}
          >
            <option value=""></option>
            <option value="around">Around</option>
            <option value="after">After</option>
          </select>
        </label>
        <label>
          Caption Layout:
          <select
            name="captionLayout"
            value={props.captionLayout ?? ""}
            onChange={(e) => {
              const newCaptionLayout = e.target.value as
                | "label"
                | "dropdown"
                | "dropdown-months"
                | "dropdown-years";
              const newProps: DayPickerPropsWithCalendar = {
                ...props,
                captionLayout: newCaptionLayout,
              };
              if (newCaptionLayout === "dropdown") {
                const dateLib = resolveDateLib(newProps);
                const referenceDate = resolveReferenceDate(newProps, dateLib);
                const hundredYearsAgo = dateLib.addYears(referenceDate, -100);
                newProps.startMonth = dateLib.startOfMonth(hundredYearsAgo);
                newProps.endMonth = dateLib.startOfMonth(referenceDate);
              } else if (newCaptionLayout === "label") {
                newProps.startMonth = undefined;
                newProps.endMonth = undefined;
              }
              setProps(newProps);
            }}
          >
            <option></option>
            <option value="label">Label</option>
            <option value="dropdown">Dropdown</option>
            <option value="dropdown-months">Dropdown Months</option>
            <option value="dropdown-years">Dropdown Years</option>
          </select>
        </label>
        {(props.captionLayout === "dropdown" ||
          props.captionLayout === "dropdown-years") && (
          <label>
            <input
              type="checkbox"
              name="reverseYears"
              checked={!!props.reverseYears}
              onChange={(e) =>
                setProps({ ...props, reverseYears: e.target.checked })
              }
              disabled={
                !(
                  props.captionLayout === "dropdown" ||
                  props.captionLayout === "dropdown-years"
                )
              }
            />
            Reverse Dropdown Years
          </label>
        )}
        <label>
          <input
            type="checkbox"
            name="showOutsideDays"
            checked={props.showOutsideDays}
            onChange={(e) =>
              setProps({ ...props, showOutsideDays: e.target.checked })
            }
          />
          Show outside days
        </label>
        <label>
          <input
            type="checkbox"
            name="showWeekNumber"
            checked={props.showWeekNumber}
            onChange={(e) =>
              setProps({ ...props, showWeekNumber: e.target.checked })
            }
          />
          Show week number
        </label>
        <label>
          <input
            type="checkbox"
            name="fixedWeeks"
            checked={props.fixedWeeks}
            onChange={(e) =>
              setProps({ ...props, fixedWeeks: e.target.checked })
            }
          />
          Fixed weeks
        </label>
        <label>
          <input
            type="checkbox"
            name="hideWeekdays"
            checked={props.hideWeekdays}
            onChange={(e) =>
              setProps({ ...props, hideWeekdays: e.target.checked })
            }
          />
          Hide weekdays
        </label>
        <label>
          Accent Color:
          <input
            value={accentColor ?? ""}
            type="color"
            name="accentColor"
            onChange={(e) => setAccentColor(e.target.value)}
          />
        </label>
      </div>
    </fieldset>
  );
}
