import React from "react";
import { ButtonProps } from "../../Button";
import styling from "@devcake/styling";
import { Icon } from "../../Icon";

styling.setDefault("components.dateinput.selector.container", "absolute bg-white top-12 right-0 border border-gray-200 rounded-md");
styling.setDefault("components.dateinput.selector.header", "p-2 font-bold");
styling.setDefault("components.dateinput.selector.header.buttons", "cursor-pointer select-none");
styling.link("components.dateinput.selector.header.icons.previous", "components.icons.chevron-left");
styling.link("components.dateinput.selector.header.icons.next", "components.icons.chevron-right");
styling.setDefault("components.dateinput.selector.items.grid", "gap-2 px-2 pb-2 w-60 text-center");
styling.setDefault("components.dateinput.selector.items.dow", "font-bold select-none");
styling.setDefault("components.dateinput.selector.items.date", "w-8 h-8 -m-1 flex justify-center items-center rounded-full cursor-pointer select-none");
styling.setDefault("components.dateinput.selector.highlight.other", "text-gray-500");


interface Props {
  color: ButtonProps["color"];
  locale?: string;
  set: (date: Date) => void;
  value: Date;
}

const today = new Date();
const makeDate = (year, month, day) => {
  const date = new Date();
  date.setFullYear(year, month, day);
  return date;
};
const makeRange = (year, month) => {
  // Get the first day of the month and rewind to the previous monday
  let start = makeDate(year, month, 1);
  while (start.getDay() !== 1) {
    start.setDate(start.getDate() - 1);
  }

  // Get the last day of the month and go to the next sunday
  let end = makeDate(year, month + 1, 0);
  while (end.getDay() !== 0) {
    end.setDate(end.getDate() + 1);
  }

  // Now build a (reverse) list of all dates between start and end
  let dates = [start];
  while (dates[0] < end) {
    dates.unshift(makeDate(
      dates[0].getFullYear(),
      dates[0].getMonth(),
      dates[0].getDate() + 1
    ));
  }

  return dates.reverse();
};

export const Dropdown: React.FunctionComponent<Props> = ({ color, locale, set, value = today }) => {
  const formatMY = React.useMemo(() => new Intl.DateTimeFormat(locale, { month: "short", year: "numeric" }), [locale]);
  const labels = React.useMemo(() => [1, 2, 3, 4, 5, 6, 7].map(i => {
    const date = makeDate(2021, 1, i); // February 2021 was a square month
    return new Intl.DateTimeFormat(locale, { weekday: "short" }).format(date);
  }), [locale]);

  const [focus, setFocus] = React.useState({ year: value.getFullYear(), month: value.getMonth() });

  const dates = React.useMemo(() => makeRange(focus.year, focus.month), [focus.month, focus.year]);
  const focusDate = makeDate(focus.year, focus.month, 1);

  const previous = () => {
    let { year, month } = focus;
    month--;
    if (month < 0) {
      month = 11;
      year--;
    }
    setFocus({ year, month });
  };

  const next = () => {
    let { year, month } = focus;
    month++;
    if (month > 11) {
      month = 0;
      year++;
    }
    setFocus({ year, month });
  };

  return (
    <div className={styling.get("components.dateinput.selector.container")}>
      <div className={[
        `flex flex-row justify-between items-center bg-${color}-100 text-${color}-600`,
        styling.get("components.dateinput.selector.header")
      ].join(" ")}>
        <div
          className={styling.get("components.dateinput.selector.header.buttons")}
          onClick={previous}
        >
          <Icon icon={styling.get("components.dateinput.selector.header.icons.previous")} className='w-4 h-4'/>
        </div>
        <div>{formatMY.format(focusDate)}</div>
        <div
          className={styling.get("components.dateinput.selector.header.buttons")}
          onClick={next}
        >
          <Icon icon={styling.get("components.dateinput.selector.header.icons.next")} className='w-4 h-4'/>
        </div>
      </div>
      <div className={[
        "grid grid-flow-row grid-cols-7",
        styling.get("components.dateinput.selector.items.grid")
      ].join(" ")}>
        {labels.map(v => (
          <div
            className={styling.get("components.dateinput.selector.items.dow")}
          >
            {v}
          </div>
        ))}
        {dates.map(date => (
          <div
            className={[
              `hover:bg-${color}-100`,
              styling.get("components.dateinput.selector.items.date"),
              date.getMonth() === focus.month ? "" : styling.get("components.dateinput.selector.highlight.other"),
              date.toDateString() === value.toDateString() ? `bg-${color}-100` : ""
            ].join(" ")}
            onClick={() => set(date)}
          >
            {date.getDate()}
          </div>
        ))}
      </div>
    </div>
  );
};