<template>
  <div class="wl-date-time-picker" data-weiling-mobile-ui-wl-date-time-picker>
    <WlPicker
      v-model="visible"
      :title="title"
      :columns="pickerColumns"
      teleport=""
      contentHeight="300px"
      :pickerDefaultValue="pickerDefaultValue"
      @onConfirm="onConfirm"
      @onChange="onChange"
      @onClose="onClose"
    />
  </div>
</template>

<script lang="ts">
export default {
  name: "WlDateTimePicker",
};
</script>

<script lang="ts" setup>
import { ref, watch, watchEffect } from "vue";
import WlPicker from "@mobileUI/components/WlPicker/src/index.vue";
import {
  dataKeyArr,
  timeKeyArr,
  dateKey,
  timeKey,
  keyToMethods,
} from "./utils/variable";
import { onGetDayNumber, onGetTime } from "./utils/utils";
type TDateTimePickerType =
  | "year"
  | "month"
  | "date"
  | "time"
  | "date-time"
  | "year-month"
  | "year-month-day"
  | "year-month-day-hour"
  | "month-day"
  | "date-hour"
  | "date-hour-minute";
type Props = {
  minDate?: Date;
  maxDate?: Date;
  type?: TDateTimePickerType;
  show?: boolean;
  title?: string;
  descShow?: boolean;
  defalutTime?: Date;
};

type TPickerItem = {
  value: number;
  text: string;
  type: string;
};

const props = withDefaults(defineProps<Props>(), {
  minDate: () => new Date("2000/1/1"),
  maxDate: () => new Date("2050/12/31"),
  type: "date-time",
  show: false,
  title: "",
  descShow: true,
  defalutTime: () => new Date(),
});

const emit = defineEmits<{
  (
    e: "onConfirm",
    val: {
      data: TPickerItem[];
      time: Date;
    },
  );
  (
    e: "onChange",
    val: {
      data: TPickerItem[];
      time: Date;
    },
  );
  (e: "update:show", val: boolean);
  (e: "onClose");
}>();

const pickerColumns = ref([]);
const visible = ref(true);
const pickerDefaultValue = ref([]);
// 获取需要的列
const getNeedColumns = (type = "date") => {
  let needColumns = [];
  if (type === "date") {
    if (props.type.includes("date")) {
      return dataKeyArr;
    } else {
      dataKeyArr.forEach((ele) => {
        if (props.type.includes(ele as string)) {
          needColumns.push(ele);
        }
      });
    }
  }
  if (type === "time") {
    if (props.type.includes("time")) {
      return timeKeyArr;
    } else {
      timeKeyArr.forEach((ele) => {
        if (props.type.includes(ele as string)) {
          needColumns.push(ele);
        }
      });
    }
  }
  return needColumns;
};
/**
 * 获取范围内的数据
 * @param funcName 调用Date对象的方法名
 * @param type 放在数据中的type
 * @param addStep 获取数据后额外加的,比如获取月份需要额外+1
 * @param min 最小数据,当不取Date的方法时
 * @param max 最大数据,当不取Date的方法时
 */
const getNeedValue = (
  funcName,
  type,
  desc = "",
  addStep = 0,
  min = 0,
  max = 0,
): TPickerItem[] => {
  const minData = funcName ? props.minDate[funcName]() + addStep : min;
  const maxData = funcName ? props.maxDate[funcName]() + addStep : max;
  let data = [];
  for (let i = minData; i <= maxData; i++) {
    data.push({
      text: `${i < 10 ? "0" + i : i}${!props.descShow ? "" : desc}`,
      value: i,
      type: type,
    });
  }
  return data;
};

// const getDefaultIndex = (arr, value) => {
//   return arr.findIndex((ele) => ele.value === value);
// };
const onGetDayCols = (currentYear, currentMonth) => {
  // const currentYear = props.defalutTime?.getFullYear(), currentMonth = props.defalutTime?.getMonth() + 1;
  const minYear = props.minDate["getFullYear"]();
  const maxYear = props.maxDate["getFullYear"]();
  const minMon = props.minDate["getMonth"]() + 1;
  const maxMon = props.maxDate["getMonth"]() + 1;
  const minDay = props.minDate["getDate"]();
  const maxDay = props.maxDate["getDate"]();
  let minD = 1,
    maxD = 31;
  // 如果当前选中的年月是最小的，那么最小日为minDate
  if (currentYear === minYear && currentMonth === minMon && currentMonth) {
    minD = minDay;
    // 如果当前选中的年月是最大的，那么最大日为minDate
  } else if (
    currentYear === maxYear &&
    currentMonth === maxMon &&
    currentMonth
  ) {
    maxD = maxDay;
  } else if (currentMonth) {
    // 如果有选中的月，那么需要修改最大日
    // 如果是二月，有年的情况下，获取该年下的天数，如果没有年，那么默认是29天
    if (currentMonth === 2) {
      maxD = currentYear ? onGetDayNumber(currentYear, currentMonth) : 29;
    } else {
      // 其他情况，取每月的天数
      maxD = onGetDayNumber(
        currentMonth,
        currentYear || new Date().getFullYear(),
      );
    }
  }
  return getNeedValue("", dateKey.day, "日", 0, minD, maxD);
};
const onGetMonthCol = (currentYear) => {
  const minYear = props.minDate["getFullYear"]();
  const maxYear = props.maxDate["getFullYear"]();
  const minMon = props.minDate["getMonth"]() + 1;
  const maxMon = props.maxDate["getMonth"]() + 1;
  const minMonth = currentYear === minYear ? minMon : 1;
  const maxMonth = currentYear === maxYear ? maxMon : 12;
  const data = getNeedValue("", dateKey.month, "月", 1, minMonth, maxMonth);
  return data;
};
const getDateColumns = () => {
  const needColumns = getNeedColumns("date");
  let columns = [];
  if (needColumns.includes(dateKey.year)) {
    const data = getNeedValue("getFullYear", dateKey.year, "年");
    columns.push(data);
  }
  if (needColumns.includes(dateKey.month)) {
    const currentYear =
      props.defalutTime?.getFullYear() || new Date().getFullYear();
    columns.push(onGetMonthCol(currentYear));
  }
  if (needColumns.includes(dateKey.day)) {
    columns.push(
      onGetDayCols(
        props.defalutTime?.getFullYear() || new Date().getFullYear(),
        props.defalutTime?.getMonth() + 1 || new Date().getMonth() + 1,
      ),
    );
  }
  return columns;
};
const getTimeColumns = () => {
  const needColumns = getNeedColumns("time");
  let columns = [];
  if (needColumns.includes(timeKey.hour)) {
    const data = getNeedValue("", timeKey.hour, "时", 0, 0, 23);
    columns.push(data);
  }
  if (needColumns.includes(timeKey.minute)) {
    const data = getNeedValue("", timeKey.minute, "分", 0, 0, 59);
    columns.push(data);
  }
  if (needColumns.includes(timeKey.second)) {
    const data = getNeedValue("", timeKey.second, "秒", 0, 0, 59);
    columns.push(data);
  }
  return columns;
};

const onConfirm = (val, indexs, { selectedOptions: data }) => {
  console.log(1111111, val, indexs, data);
  emit("onConfirm", {
    data,
    time: onGetTime(data),
  });
};

let preChangeData: TPickerItem[] = [];
const onChange = (val, index, { selectedOptions: data }) => {
  const dayIndex = data.findIndex((ele) => ele.type === dateKey.day);
  const monthIndex = data.findIndex((ele) => ele.type === dateKey.month);
  if (dayIndex !== -1) {
    const columns = pickerColumns.value;
    // 需要重新加载日期列表的情况
    // 1. 年份变化
    // 2. 不管什么年份,月份变化
    // 其他情况不需要变化,不需要重新计算数据
    let preYear = { value: 0 },
      preMonth = { value: 0 };
    let curYear = { value: 0 },
      curMonth = { value: 0 };
    // 不是只显示 月-日的情况
    if (dayIndex !== 1) {
      preYear = preChangeData[0] || { value: 0 };
      preMonth = preChangeData[1] || { value: 0 };
      curYear = data[0];
      curMonth = data[1];
    } else {
      preMonth = preChangeData[0] || { value: 0 };
      curMonth = data[0];
    }
    if ((curYear as TPickerItem).value !== (preYear as TPickerItem).value) {
      columns[dayIndex] = onGetDayCols(curYear.value, curMonth.value);
      columns[monthIndex] = onGetMonthCol(curYear.value);
    } else if (
      (preMonth as TPickerItem).value !== (curMonth as TPickerItem).value
    ) {
      columns[dayIndex] = onGetDayCols(curYear.value, curMonth.value);
      preChangeData = data;
      pickerColumns.value = columns;
    }
  }
  emit("onChange", {
    data,
    time: onGetTime(data),
  });
};

const onClose = () => {
  emit("update:show", false);
  emit("onClose");
};

watch(
  () => [props.type, props.maxDate, props.minDate, props.defalutTime],
  () => {
    pickerColumns.value = [...getDateColumns(), ...getTimeColumns()];
  },
  { immediate: true },
);
watchEffect(() => {
  visible.value = props.show;
});
watch(
  () => [props.defalutTime, pickerColumns.value],
  () => {
    if (props.defalutTime && pickerColumns.value.length !== 0) {
      const needColumns = [
        ...getNeedColumns("date"),
        ...getNeedColumns("time"),
      ];
      const indexs = [];
      needColumns.forEach((key, i) => {
        let data = props.defalutTime[keyToMethods[key]]();
        if (key === dateKey.month) {
          data += 1;
        }
        indexs.push(data);
      });
      pickerDefaultValue.value = indexs;
    }
  },
  {
    immediate: true,
  },
);
</script>
