import './ui/css/variables/definition.scss';
import './ui/css/common.scss';
import { createElement } from "./functions";
import { createIcon, changeIcon, resolveIcon } from "./ui/icon";
import { createCheckbox, createRadiobox, resolveCheckbox } from "./ui/checkbox";
import { setTooltip, resolveTooltip } from "./ui/tooltip";
import { createTab } from "./ui/tab";
import { Dropdown } from "./ui/dropdown";
import { Grid } from "./ui/grid/grid";
import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn, GridTextColumn, GridDateColumn } from './ui/grid/column';
import { Popup, createPopup, resolvePopup, showAlert, showInput, showConfirm } from "./ui/popup";
import { createPicture, createAudio, createVideo, createFile, createVideoList } from './ui/media';
import { validation, convertCssStyle } from './ui/extension';
import { createDateInput, toDateValue, getFormatter, formatDate, setDateValue, getDateValue, DateSelector } from './ui/date';
import * as utility from './utility';

function requestAnimationFrame(callback) {
  if (typeof utility.global.requestAnimationFrame === 'function') {
    utility.global.requestAnimationFrame(callback);
  } else {
    setTimeout(callback, 0);
  }
}

function scrollLeft() {
  const n = document.documentElement;
  return (utility.global.scrollX || n.scrollLeft) - (n.clientLeft || 0);
}

function scrollTop() {
  const n = document.documentElement;
  return (utility.global.scrollY || n.scrollTop) - (n.clientTop || 0);
}

/**
 * @private
 * @param {HTMLElement} e 
 */
function offset(e) {
  const rect = e.getBoundingClientRect();
  return {
    top: rect.top + scrollTop(),
    left: rect.left + scrollLeft(),
    height: rect.height,
    width: rect.width
  };
}

class OptionBase {
  _option;

  r;

  constructor(opt) {
    this._option = opt;
    const getText = opt.getText;
    if (typeof getText === 'function') {
      this.r = getText;
    } else if (typeof GetTextByKey === 'function') {
      this.r = GetTextByKey;
    } else {
      this.r = utility.r;
    }
  }
}

/**
 * 通知选项
 * @typedef NotifyOption
 * @property {string | HTMLElement} message - 内容，支持自定义元素
 * @property {HTMLElement} [parent] - 目标父元素
 * @property {string} [title] - 标题
 * @property {"success" | "warning" | "error"} [type] - 提示类型
 * @property {boolean} [persistent] - 是否持续显示，默认为 `false`，3 秒后自动关闭
 * @property {number} [timeout] - 超时时间，默认 3 秒
 * @property {(auto: boolean) => void} [onDismissed] - 关闭时触发的函数
 */

/**
 * @private
 * @param {HTMLDivElement} wrapper 
 * @param {(auto: boolean) => void} [onDismissed] 
 * @param {boolean} [auto] 
 */
function closeNotify(wrapper, onDismissed, auto) {
  wrapper.classList.remove('active');
  setTimeout(() => {
    wrapper.remove();
    if (typeof onDismissed === 'function') {
      onDismissed(auto);
    }
  }, 120);
}

/**
 * 
 * @param {NotifyOption} opts 
 */
function notify(opts) {
  opts ||= {};
  let timer;
  const close = createIcon('fa-light', 'times');
  close.classList.add('ui-notify-close');
  close.addEventListener('click', () => {
    timer && clearTimeout(timer);
    closeNotify(wrapper, opts.onDismissed);
  });
  let type;
  let typeClass;
  opts.type ||= 'success';
  switch (opts.type) {
    case 'warning':
      type = 'exclamation-circle';
      typeClass = 'warning';
      break;
    case 'error':
      type = 'times-circle';
      typeClass = 'error';
      break;
    case 'success':
      type = 'check-circle';
      typeClass = 'success';
      break;
    default:
      type = opts.type;
      typeClass = 'success';
      break;
  }
  const icon = createIcon('fa-solid', type);
  icon.classList.add('ui-notify-type', typeClass);
  const wrapper = createElement('div', 'ui-notify',
    utility.nullOrEmpty(opts.title) ?
      createElement('div', 'ui-notify-single',
        icon,
        createElement('span', 'ui-notify-message', opts.message),
        close
      ) :
      createElement('div', 'ui-notify-content',
        createElement('div', 'ui-notify-header',
          icon,
          createElement('h2', 'ui-notify-title', opts.title),
          close
        ),
        createElement('span', 'ui-notify-message', opts.message)
      )
  );
  if (!opts.persistent) {
    timer = setTimeout(() => {
      closeNotify(wrapper, opts.onDismissed, true);
    }, opts.timeout || 3000);
  }
  (opts.parent ?? document.body).appendChild(wrapper);
  setTimeout(() => wrapper.classList.add('active'), 10);
  return wrapper;
}

export {
  createElement,
  // icon
  createIcon,
  changeIcon,
  resolveIcon,
  // checkbox
  createCheckbox,
  createRadiobox,
  resolveCheckbox,
  // tooltip
  setTooltip,
  resolveTooltip,
  // tab
  createTab,
  // dropdown
  Dropdown,
  // grid
  Grid,
  GridColumn,
  GridInputColumn,
  GridDropdownColumn,
  GridCheckboxColumn,
  GridIconColumn,
  GridTextColumn,
  GridDateColumn,
  // popup
  Popup,
  createPopup,
  resolvePopup,
  showAlert,
  showInput,
  showConfirm,
  // dateSelector
  createDateInput,
  toDateValue,
  getFormatter,
  formatDate,
  setDateValue,
  getDateValue,
  DateSelector,
  // media
  createPicture,
  createAudio,
  createVideo,
  createFile,
  createVideoList,
  // extension
  validation,
  convertCssStyle,
  // utility
  utility,
  // functions
  requestAnimationFrame,
  offset,
  // base classes
  OptionBase,
  // notify
  notify
}
