import { months, weekdays } from '../consts';
import { getPartsFromEpoch } from '../helpers';
import { newDate } from '../date-utils';

const isValidAttrArr = (arr, count) =>
  Array.isArray(arr) && arr.length === count && arr.filter(Boolean).length === count;

const generateYearList = (range) => {
  const [start, end] = range;
  const years = [];

  for (let year = start; year <= end; year++) {
    years.push(year);
  }

  return years;
};

const getMaxDaysInMonth = (year, month) => {
  return new Date(year, month, 0).getDate();
};

const comboBoxItemTpl = ({ label, dataId, dataName }) => `
	<div class="combo-box-item"
		data-id="${dataId}"
		data-name="${dataName}"
	>
			${label}
	</div>
`;

export const createMonthView = (year, month, shortWeekdays) => {
  const daysInMonth = getMaxDaysInMonth(year, month);

  // Get day of the week (0 = Sunday, 1 = Monday, etc.)
  const firstDayOfMonth = new Date(year, month - 1, 1).getDay();

  let monthView = '<table>';

  // Add the table headers (days of the week)
  monthView += `<thead><tr>${shortWeekdays.reduce(
    (acc, d) => `${acc}<th><span class="weekday">${d}</span></th>`,
    ''
  )}</tr></thead>`;

  monthView += '<tbody>';

  // Add empty cells for the days before the start of the month
  monthView += '<tr>';
  for (let i = 0; i < firstDayOfMonth; i++) {
    monthView += '<td></td>';
  }

  // Add days of the month
  let dayOfWeek = firstDayOfMonth;
  for (let i = 1; i <= daysInMonth; i++) {
    if (dayOfWeek === 7) {
      dayOfWeek = 0;
      monthView += '</tr><tr>';
    }

    monthView += `
      <td
        data-date-day="${i}"
        class="day-entry">
        <span class="day" data-date-day=${i}>
          ${i}
        </span>
      </td>
    `;
    dayOfWeek++;
  }

  // Add empty cells for the days after the end of the month
  while (dayOfWeek < 7) {
    monthView += '<td></td>';
    dayOfWeek++;
  }

  monthView += '</tr></tbody></table>';

  return monthView;
};

export const getYearOptions = (range) =>
  generateYearList(range)
    .map((item) => comboBoxItemTpl({ label: item, dataId: item, dataName: item }))
    .join('');

export const getMonthsOptions = (customMonths = months) =>
  customMonths
    .map((item, index) => comboBoxItemTpl({ label: item, dataId: index + 1, dataName: item }))
    .join('');

export const isViewVisible = (selectionEpoch, previewEpoch) => {
  const [previewYear, previewMonth] = getPartsFromEpoch(previewEpoch);
  const [selectedYear, selectedMonth] = getPartsFromEpoch(selectionEpoch);
  return selectedYear === previewYear && selectedMonth === previewMonth;
};

export const createInputs = () => {
  const ele = document.createElement('span');

  ele.innerHTML = `
    <descope-combo-box
      label-type="static"
      bordered="true"
      item-label-path="data-name"
      item-value-path="data-id"
      class="month-input"
    >
    ${getMonthsOptions()}
    </descope-combo-box>
    <descope-combo-box
      allow-custom-value="true"
      label-type="static"
      bordered="true"
      item-label-path="data-name"
      item-value-path="data-id"
      class="year-input"
      no-empty-value="true"
    >
    </descope-combo-box>
  `;

  return ele;
};

export const initComboBox = (input, onChange, onBlur) => {
  input.addEventListener('input', onChange);
  input.addEventListener('focusout', onBlur);
  return input;
};

export const ensureMonthNamesArr = (attrVal) => {
  const monthArr = attrVal?.split(',');
  return isValidAttrArr(monthArr, 12) ? monthArr : months;
};

export const ensureWeekdayNamesArr = (attrVal) => {
  const customWeekdayArr = attrVal?.split?.(',');
  const isCustomValid = isValidAttrArr(customWeekdayArr, 7);
  return isCustomValid ? customWeekdayArr : weekdays;
};

export const ensureShortWeekdayNamesArr = (attrVal) => {
  const customShortWeekdays = attrVal;

  if (!attrVal || !isValidAttrArr(customShortWeekdays, 7)) {
    return weekdays.map((d) => d.substring(0, 3));
  }

  return customShortWeekdays.map((d) => d.substring(0, 3));
};

export const truncateWeekdays = (arr) => arr.map((d) => d.substring(0, 3));

export const prevMonth = (epoch) => {
  const date = newDate(epoch);
  const month = date.getMonth();

  if (month === 0) {
    const year = date.getFullYear();
    date.setFullYear(year - 1);
    date.setMonth(11);
  } else {
    date.setMonth(month - 1);
  }

  return date;
};

export const nextMonth = (epoch) => {
  const date = newDate(epoch);
  const month = date.getMonth();

  if (month === 11) {
    const year = date.getFullYear();
    date.setFullYear(year + 1);
    date.setMonth(0);
  } else {
    date.setMonth(month + 1);
  }

  return date;
};
