<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import dayjs from 'dayjs';

import { t } from '@/i18n';

import type { PickerMode } from 'ant-design-vue/es/vc-picker/interface';
import type { Dayjs, OpUnitType } from 'dayjs';
import type { OptionItem, RangeValue } from '@/types';

type DateType = 'year' | 'month' | 'date' | 'custom';
type LastType = '1d' | '7d' | '30d' | 'custom';

interface Props {
  isLast?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  isLast: false,
});

const emit = defineEmits<{
  change: [range: RangeValue];
}>();

const selectedType = ref<DateType | LastType>(props.isLast ? '1d' : 'month');
const singleDate = ref<Dayjs>();
const rangeDate = ref<RangeValue>();

const isCustomType = computed(() => {
  return selectedType.value === 'custom';
});

const typeOptions = computed<OptionItem<DateType | LastType>[]>(() => {
  if (props.isLast) {
    return [
      { value: '1d', label: t('common.recent1Day') },
      { value: '7d', label: t('common.recent7Day') },
      { value: '30d', label: t('common.recent30Day') },
      { value: 'custom', label: t('common.custom') },
    ];
  }

  return [
    { value: 'year', label: t('common.year') },
    { value: 'month', label: t('common.month') },
    { value: 'date', label: t('common.date') },
    { value: 'custom', label: t('common.custom') },
  ];
});

onMounted(() => {
  handleTypeChange();
});

const disabledDate = (current: Dayjs) => {
  return current > dayjs().endOf('day');
};

const handleTypeChange = () => {
  if (props.isLast) {
    handleLastTypeChange();
  } else {
    handleNormalTypeChange();
  }
};

const handleNormalTypeChange = () => {
  const now = dayjs();

  if (isCustomType.value) {
    if (!rangeDate.value) {
      rangeDate.value = [now.startOf('month'), now.endOf('day')];
    }

    handleRangeChange();
  } else {
    if (!singleDate.value) {
      singleDate.value = now;
    }

    handleDateChange();
  }
};

const handleLastTypeChange = () => {
  if (!isCustomType.value) {
    const days = parseInt(selectedType.value);
    const end = dayjs();
    const start = end.subtract(days, 'day');
    rangeDate.value = [start, end];
    emitChange(start, end);
  }
};

const handleDateChange = () => {
  if (!singleDate.value) {
    return;
  }

  const type = selectedType.value as OpUnitType;
  emitChange(singleDate.value.startOf(type), singleDate.value.endOf(type));
};

const handleRangeChange = () => {
  if (!rangeDate.value) {
    return;
  }

  selectedType.value = 'custom';
  emitChange(rangeDate.value[0].startOf('day'), rangeDate.value[1].endOf('day'));
};

const emitChange = (start: Dayjs, end: Dayjs) => {
  emit('change', [start, end]);
};
</script>

<template>
  <div class="time-select-container">
    <span class="time-select-label">{{ $t('common.selectTime') }}</span>
    <ASelect class="time-select-type" v-model:value="selectedType" @change="handleTypeChange">
      <ASelectOption v-for="item in typeOptions" :key="item.value" :value="item.value">
        {{ item.label }}
      </ASelectOption>
    </ASelect>
    <ADatePicker
      v-show="!isLast && !isCustomType"
      v-model:value="singleDate"
      :picker="<PickerMode>selectedType"
      :allow-clear="false"
      :disabled-date="disabledDate"
      @change="handleDateChange"
    >
      <template #suffixIcon>
        <SvgIcon name="calendar" color="#333" />
      </template>
    </ADatePicker>
    <ARangePicker
      class="time-select-range-picker"
      v-show="isLast || isCustomType"
      v-model:value="rangeDate"
      :allow-clear="false"
      :separator="$t('common.to')"
      :disabled-date="disabledDate"
      @change="handleRangeChange"
    >
      <template #suffixIcon>
        <SvgIcon name="calendar" color="#333" />
      </template>
    </ARangePicker>
  </div>
</template>

<style lang="scss" scoped>
.time-select-container {
  display: inline-flex;
  align-items: center;
}

.time-select-label {
  margin-right: 16px;
  font-size: 14px;
  line-height: 22px;
  color: #000;
}

.time-select-type {
  width: 110px;
  margin-right: 12px;
}

.time-select-range-picker {
  width: 256px;

  :deep(.ant-picker-range-separator) {
    padding-right: 16px;
  }
}
</style>
