<!-- 如果是 一维数组 则选中一个值；如果是二维数组，则返回每一列选中值组成的数组 -->
<template>
  <view class="w-picker">
    <view class="w-picker-wrapper" @click.passive="onShowPicker">
      <slot name="trigger" :label="state.name" :value="state.value">
        <up-input
          readonly
          :border="border"
          v-model="state.name"
          :inputAlign="align"
          :placeholder="placeholder"
          :placeholder-style="`color: ${placeholderColor}`"
          :suffixIcon="align == 'right' ? 'arrow-right' : ''"
          :suffixIconStyle="{
            color: state.name ? color : placeholderColor,
          }"
          :fontSize="size"
          :color="color"
        >
          <template #suffix v-if="state.name && clearable">
            <view style="width: 12px" @click.stop="onClear">
              <view style="position: absolute; top: 0; bottom: 0; z-index: 100">
                <view class="clear" :style="iconStyle">
                  <u-icon name="close" size="8" color="#fff"></u-icon>
                </view>
              </view>
            </view>
          </template> </up-input
      ></slot>
      <div class="input-cover"></div>
    </view>
    <u-datetime-picker
      :show="show"
      :mode="mode"
      :title="title"
      v-model="state.value"
      :closeOnClickOverlay="closeOnClickOverlay"
      :minDate="state.minDate"
      :maxDate="state.maxDate"
      :format="format"
      @close="close"
      @cancel="cancel"
      @confirm="confirm"
      @change="change"
    ></u-datetime-picker>
  </view>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watchEffect } from "vue";
import dayjs from "dayjs";
type Mode = "date" | "datetime" | "year-month" | "time";
interface Props {
  modelValue: any;
  mode?: Mode; // date为日期选择，time为时间选择，year-month为年月选择
  maxDate?: number | string; // 最大时间戳
  minDate?: number | string; // 最小时间戳
  minHour?: number; // 最小小时
  maxHour?: number; // 最大小时
  minMinute?: number; // 最小分钟
  maxMinute?: number; // 最大分钟
  format?: string; // 日期格式化模板
  formatter?: (type: string, value: string) => string; // 日期格式化函数

  align?: "left" | "center" | "right" | undefined; //对齐方式 left\center\right
  border?: "none" | "bottom" | "surround" | undefined; // surround四周有边框,bottom底部有边框,none没有边框
  shape?: "circle" | "square" | undefined; //输入框形状 circle-圆形，square-方形 （ 默认 'square' ）

  title?: string; // 弹窗顶部标题
  size?: string; //文本大小
  color?: string; //选中的颜色
  placeholder?: string; //未选择时,提示文字
  placeholderColor?: string; //占位颜色
  closeOnClickOverlay?: boolean; //是否允许点击遮罩关闭选择器  ( 默认 false )
  clearable?: boolean; //是否允许清空已选择内容 ( 默认 true )
}

const props = withDefaults(defineProps<Props>(), {
  border: "none",
  shape: "square",
  mode: "date",
  align: "right",
  value: null, // 最终选择的值
  placeholder: "请选择",
  placeholderColor: "#c0c4cc",
  color: "#303133",
  size: "15",
  clearable: true,
});

const iconStyle = computed(() => {
  if (props.border == "none") {
    return { transform: "translateY(5px)" };
  } else if (props.border == "surround") {
    return { transform: "translateY(11px)" };
  } else {
    return { transform: "translateY(11px)" };
  }
});
// 集中到这里处理
const state = reactive<any>({
  name: null, // 最终选择的值
  value: -1, // 最终选择的值
  //maxDate: null as string | number | unknown, // 最大日期
  //minDate: null as string | number | unknown, // 最小日期
  defaultIndex: [], // //默认选中索引[]
});

//默认不弹出
const show = ref(false);

//事件抛出
const emit = defineEmits([
  "close",
  "cancel",
  "confirm",
  "change",
  "update:modelValue",
]);

const onShowPicker = () => {
  show.value = true;
};

//确认
const confirm = (d: any) => {
  show.value = false;
  const { value, mode } = d;
  let _v = formatDatetime(mode, value);
  emit("update:modelValue", _v);
  emit("confirm", d);
};
//取消
const cancel = () => {
  show.value = false;
  emit("cancel");
};
//关闭
const close = () => {
  show.value = false;
  emit("close");
};
//改变
const change = (d: any) => {
  emit("change", d);
};
const onClear = () => {
  state.name = null;
  state.value = -1;
  emit("update:modelValue", null);
};

watchEffect(() => {
  if (props.modelValue) {
    state.name = props.modelValue;
    if (props.mode == "time") {
      state.value = props.modelValue;
    } else {
      state.value = tran2millisecond(props.modelValue);
    }
  } else {
    if (props.mode == "time") {
      state.value = "00:00";
    }
  }

  if (props.maxDate) {
    if (typeof props.maxDate == "string") {
      try {
        state.maxDate = tran2millisecond(props.maxDate);
      } catch (error) {
        console.error("maxDate日期格式错误");
        state.maxDate = "";
      }
    } else {
      state.maxDate = props.maxDate;
    }
  }
  if (props.minDate) {
    if (typeof props.minDate == "string") {
      try {
        state.minDate = tran2millisecond(props.minDate);
      } catch (error) {
        console.error("minDate日期格式错误");
        state.minDate = "";
      }
    } else {
      state.minDate = props.minDate;
    }
  }
});

// 获取时间戳（毫秒）
function tran2millisecond(date: any) {
  return dayjs(date).valueOf();
}

function formatDatetime(type: Mode, value: any) {
  let _v = value;
  let _format = props.format;
  switch (type) {
    case "date":
      _format = props.format ?? "YYYY-MM-DD";
      break;
    case "datetime":
      _format = props.format ?? "YYYY-MM-DD HH:mm:ss";
      break;
    case "year-month":
      _format = props.format ?? "YYYY-MM";
      break;
    case "time":
      _format = props.format ?? "HH:mm:ss";
      return value;
    default:
      break;
  }
  _v = dayjs(_v).format(_format);
  return _v;
}
</script>
<style scoped lang="scss">
@mixin flex($direction: row) {
  display: flex;
  flex-direction: $direction;
}

.w-picker {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  .w-picker-wrapper {
    position: relative;
    width: 100%;
    cursor: pointer;
  }
  .clear {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #c1c1c1;
    width: 15px;
    height: 15px;
    line-height: 15px;
    border-radius: 50%;
    .u-icon {
      margin-top: 1px;
    }
  }
}
.u-input {
  @include flex(row);
  align-items: center;
  flex: 1;

  &--radius,
  &--square {
    border-radius: 4px;
  }

  &--no-radius {
    border-radius: 0;
  }

  &--circle {
    border-radius: 100px;
  }
}
.input-cover {
  opacity: 0;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
}
</style>
