import dayPickr from "daypickr/esm";
import { dateToYYYYMMDD } from "../../../utils";

export interface DayPickrWeekday {
  name: string;
  shortname: string;
}

export interface DayPickrL10n {
  prevMonth: string;
  nextMonth: string;
  month: string;
  year: string;
  weekdays: DayPickrWeekday[];
  months: string[];
  openButton: string;
  closeButton: string;
}

export interface DayPickrClasses {
  wrapper?: string;
  header?: string;
  select?: string;
  selectDisplay?: string;
  monthSelect?: string;
  yearSelect?: string;
  button?: string;
  paginationButton?: string;
  nextMonthButton?: string;
  prevMonthButton?: string;
  yearMonthWrapper?: string;
  pagination?: string;
  table?: string;
  tableRow?: string;
  tableCell?: string;
  tableHeaderRow?: string;
  tableHeaderCell?: string;
  dayButton?: string;
  isToday?: string;
  isSelected?: string;
  srOnly?: string;
  input?: string;
  closeButton?: string;
  toggleButton?: string;
}

export interface DayPickrIcon {
  type: string;
  xmlns?: string;
  viewBox?: string;
  className?: string;
  children?: Array<{
    type: string;
    d?: string;
    "fill-rule"?: string;
  }>;
}

export interface DayPickrConfig {
  locale?: string;
  classes?: DayPickrClasses;
  firstDayOfWeek?: number;
  l10n?: Partial<DayPickrL10n>;
  parseDate?: (date: string) => Date | false;
  calendarIcon?: DayPickrIcon;
  disabledDayFn?: (date: Date) => boolean;
}

export const defaultConfig: DayPickrConfig = {
  locale: "sk",
  classes: {
    wrapper: "daypickr",
    header: "daypickr__header",
    select: "daypickr__select",
    selectDisplay: "daypickr__select-display",
    monthSelect: "daypickr__select--month",
    yearSelect: "daypickr__select--year",
    button: "daypickr__button",
    paginationButton: "daypickr__button--pagination ",
    nextMonthButton:
      "daypickr__button--pagination-next btn btn--ghost btn--square btn--small",
    prevMonthButton:
      "daypickr__button--pagination-prev btn btn--ghost btn--square btn--small",
    yearMonthWrapper: "daypickr__year-month-wrapper",
    pagination: "daypickr__pagination",
    table: "daypickr__calendar",
    tableRow: "daypickr__calendar-row",
    tableCell: "daypickr__calendar-cell",
    tableHeaderRow: "daypickr__calendar-header-row",
    tableHeaderCell: "daypickr__calendar-header-cell",
    dayButton: "daypickr__day",
    isToday: "isToday",
    isSelected: "isSelected",
    srOnly: "sr-only",
    input: "form-group__item text-input",
    closeButton: "daypickr__button--close btn mb-none",
    toggleButton: "form-group__item btn btn--square",
  },
  firstDayOfWeek: 1,
  l10n: {
    prevMonth: "predchádzajúci mesiac",
    nextMonth: "nasledujúci mesiac",
    month: "Mesiac",
    year: "Rok",
    weekdays: [
      { name: "Nedeľa", shortname: "Ne" },
      { name: "Pondelok", shortname: "Po" },
      { name: "Utorok", shortname: "Ut" },
      { name: "Streda", shortname: "St" },
      { name: "Štvrtok", shortname: "Št" },
      { name: "Piatok", shortname: "Pi" },
      { name: "Sobota", shortname: "So" },
    ],
    months: [
      "Január",
      "Február",
      "Marec",
      "Apríl",
      "Máj",
      "Jún",
      "Júl",
      "August",
      "September",
      "Október",
      "November",
      "December",
    ],
    openButton: "Vyberte dátum",
    closeButton: "Zatvoriť",
  },
  parseDate: (date: string): Date | false => {
    const matches = date.match(/(\d{1,2})\. ?(\d{1,2})\. ?(\d{4})/);
    if (matches) {
      return new Date(
        Number(matches[3]),
        Number(matches[2]) - 1,
        Number(matches[1]),
      );
    }
    return false;
  },
  calendarIcon: {
    type: "svg",
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 1000 1000",
    className: "icon icon--medium",
    children: [
      {
        type: "path",
        d: "M800 175H700v-37.5a37.5 37.5 0 0 0-75 0V175H350v-37.5a37.5 37.5 0 0 0-75 0V175H100v625a75 75 0 0 0 75 75h700V250a75 75 0 0 0-75-75zM300 825H187.4a37.5 37.5 0 0 1-37.5-37.6V700H300v125zm0-150H150V550h150v125zm0-150H150V400h150v125zm-50-262.5a62.4 62.4 0 0 1 25-50v50a37.5 37.5 0 0 0 75 0v-50a62.5 62.5 0 1 1-100 50zm225 562.4H325V700h150v125zm0-149.9H325V550h150v125zm0-150H325V400h150v125zm175 300H500V700h150v125zm0-150H500V550h150v125zm0-150H500V400h150v125zm-50-262.5a62.4 62.4 0 0 1 25-50v50a37.5 37.5 0 0 0 75 0v-50a62.5 62.5 0 1 1-100 50zM825 675H675V550h150v125zm0-150H675V400h112.5a37.5 37.5 0 0 1 37.5 37.4V525z",
        "fill-rule": "evenodd",
      },
    ],
  },
};

export default class DatePickerStatic {
  element: HTMLElement;
  config: DayPickrConfig;
  instance: any;

  constructor(element: HTMLElement, config: DayPickrConfig) {
    this.element = element;
    this.config = { ...defaultConfig, ...config };
    this.init();
    (this.element as any).ODS_DatePicker = this;
    return this;
  }

  init() {
    const elementConfig = this.element.getAttribute("data-datepicker-config");
    const enabledDays = this.element.getAttribute("data-enabled-days");

    let parsedConfig: Partial<DayPickrConfig> = {};
    if (elementConfig) {
      try {
        parsedConfig = JSON.parse(elementConfig);
      } catch {
        parsedConfig = {};
      }
    }

    // dates from enabledDays override disabledDayFn passed in config
    this.config = {
      ...this.config,
      ...parsedConfig,
      ...(enabledDays && {
        disabledDayFn: (date: Date) => {
          return !enabledDays.split(",").includes(dateToYYYYMMDD(date));
        },
      }),
    };

    const id = this.element.getAttribute("data-datepicker-id") || undefined;
    const name = this.element.getAttribute("data-datepicker-name") || id;

    this.instance = dayPickr(this.element, {
      id,
      name,
      ...this.config,
    });
  }

  destroy() {
    if (this.instance) {
      this.instance.destroy();
    }
    this.instance = null;
    (this.element as any).ODS_DatePicker = null;
  }
}
