<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import dayjs from 'dayjs';
import { Calendar } from '@element-plus/icons-vue';
import isoWeek from 'dayjs/plugin/isoWeek';
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
import {
  type WorkReportPeriodOption,
  buildMonthlyPeriodFromMonth,
  buildProjectPeriodFromMonth,
  buildWeeklyPeriodFromDate,
  formatPeriodDisplayLabel,
  getReportTypePeriodOptions
} from '../utils';
import { WORK_REPORT_TYPE_LABEL, type WorkReportType } from '../types';

dayjs.extend(isoWeek);

defineOptions({ name: 'WorkReportCreateDialog' });

interface Props {
  defaultReportType?: WorkReportType;
  projectVisible?: boolean;
  projectOptions?: Api.WorkReport.Project.ProjectReportOwnerProjectOption[];
}

const props = withDefaults(defineProps<Props>(), {
  defaultReportType: 'weekly',
  projectVisible: false,
  projectOptions: () => []
});

const visible = defineModel<boolean>('visible', { default: false });

const emit = defineEmits<{
  (
    e: 'confirm',
    payload:
      | { reportType: 'weekly' | 'monthly'; period: WorkReportPeriodOption['period'] }
      | {
          reportType: 'project';
          projectId: string;
          flag: number;
          period: WorkReportPeriodOption['period'];
        }
  ): void;
}>();

const selectedPeriodKey = ref('');
const selectedProjectId = ref('');
const rawCustomWeekDate = ref('');
const customMonth = ref('');
const customProjectMonth = ref('');
const customProjectFlag = ref(1);

// 自定义周报周期：无论用户点哪一天，都归一到该 ISO 周的周一，
// 这样 ElDatePicker 使用内置 dayjs 的 ww（locale week）也能正确显示 ISO 周数。
const customWeekDate = computed<string>({
  get: () => rawCustomWeekDate.value,
  set: val => {
    if (!val) {
      rawCustomWeekDate.value = val;
      return;
    }
    rawCustomWeekDate.value = dayjs(val).startOf('isoWeek').format('YYYY-MM-DD');
  }
});

const selectedReportType = computed<WorkReportType>(() => {
  if (props.defaultReportType === 'project' && !props.projectVisible) return 'weekly';
  return props.defaultReportType;
});

const periodOptionMap = computed(() => getReportTypePeriodOptions());
const activePeriodOptions = computed(() => periodOptionMap.value[selectedReportType.value]);
const dialogTitle = computed(() => `新增${WORK_REPORT_TYPE_LABEL[selectedReportType.value]}`);
const projectHalfOptions = [
  { label: '上半月', value: 1 },
  { label: '下半月', value: 2 }
];

const defaultCustomMonth = computed(() => {
  const period = activePeriodOptions.value[0]?.period;
  return period?.periodStartDate.slice(0, 7) || '';
});

const customPeriod = computed<WorkReportPeriodOption['period'] | null>(() => {
  if (selectedPeriodKey.value !== 'custom') return null;

  if (selectedReportType.value === 'weekly') {
    if (!customWeekDate.value) return null;
    return buildWeeklyPeriodFromDate(customWeekDate.value);
  }

  if (selectedReportType.value === 'monthly') {
    if (!customMonth.value) return null;
    return buildMonthlyPeriodFromMonth(customMonth.value);
  }

  if (!customProjectMonth.value) return null;
  return buildProjectPeriodFromMonth(customProjectMonth.value, customProjectFlag.value);
});

const selectedPeriod = computed(
  () => activePeriodOptions.value.find(item => item.key === selectedPeriodKey.value) ?? activePeriodOptions.value[0]
);

const selectedPeriodValue = computed(() =>
  selectedPeriodKey.value === 'custom' ? customPeriod.value : selectedPeriod.value?.period
);
const customPeriodPreviewLabel = computed(() =>
  customPeriod.value ? formatPeriodDisplayLabel(customPeriod.value.periodLabel) : ''
);

const confirmDisabled = computed(() => {
  if (!selectedPeriodValue.value) return true;
  if (selectedReportType.value === 'project' && !selectedProjectId.value) return true;
  return false;
});

watch(
  selectedReportType,
  type => {
    selectedPeriodKey.value = periodOptionMap.value[type][0]?.key || '';

    if (type === 'project' && !selectedProjectId.value) {
      selectedProjectId.value = props.projectOptions[0]?.id || '';
    }
  },
  { immediate: true }
);

watch(visible, isVisible => {
  if (!isVisible) return;

  selectedProjectId.value = props.projectOptions[0]?.id || '';
  selectedPeriodKey.value = periodOptionMap.value[selectedReportType.value][0]?.key || '';
  customWeekDate.value = activePeriodOptions.value[0]?.period.periodStartDate || '';
  customMonth.value = defaultCustomMonth.value;
  customProjectMonth.value = defaultCustomMonth.value;
  customProjectFlag.value = activePeriodOptions.value[0]?.flag || 1;
});

function handleConfirm() {
  const period = selectedPeriodValue.value;
  if (!period) return;

  if (selectedReportType.value === 'project') {
    emit('confirm', {
      reportType: 'project',
      projectId: selectedProjectId.value,
      flag: selectedPeriodKey.value === 'custom' ? customProjectFlag.value : selectedPeriod.value.flag || 1,
      period
    });
  } else {
    emit('confirm', {
      reportType: selectedReportType.value,
      period
    });
  }

  visible.value = false;
}
</script>

<template>
  <BusinessFormDialog
    v-model="visible"
    :title="dialogTitle"
    class="work-report-create-dialog"
    preset="md"
    confirm-text="确认新增"
    append-to-body
    :close-on-click-modal="false"
    @confirm="handleConfirm"
  >
    <!-- 必须用单根节点包裹：ElScrollbar 默认 slot 接收多根 Fragment 时，destroy-on-close 后 patch 会触发 null __vnode 错误 -->
    <div class="work-report-create-dialog__body">
      <div v-if="selectedReportType === 'project'" class="work-report-create-dialog__project-select">
        <label class="work-report-create-dialog__label">项目</label>
        <ElSelect
          v-model="selectedProjectId"
          class="work-report-create-dialog__project-select-control w-full"
          placeholder="请选择项目"
          filterable
        >
          <ElOption
            v-for="item in props.projectOptions"
            :key="item.id"
            :label="item.projectCode ? `${item.projectName}（${item.projectCode}）` : item.projectName"
            :value="item.id"
          />
        </ElSelect>
      </div>

      <div class="work-report-create-dialog__section">
        <div class="work-report-create-dialog__grid is-period">
          <button
            v-for="item in activePeriodOptions"
            :key="item.key"
            type="button"
            class="work-report-create-dialog__choice"
            :class="{ 'is-active': selectedPeriodKey === item.key }"
            @click="selectedPeriodKey = item.key"
          >
            <div class="work-report-create-dialog__choice-title">{{ item.label }}</div>
            <div class="work-report-create-dialog__choice-desc">{{ item.description }}</div>
          </button>
          <button
            type="button"
            class="work-report-create-dialog__choice"
            :class="{ 'is-active': selectedPeriodKey === 'custom' }"
            @click="selectedPeriodKey = 'custom'"
          >
            <div class="work-report-create-dialog__choice-title">自定义周期</div>
            <div class="work-report-create-dialog__choice-desc">
              {{
                selectedReportType === 'weekly'
                  ? '选择某一周作为周报周期。'
                  : selectedReportType === 'monthly'
                    ? '选择某一月作为月报周期。'
                    : '选择某个月的上半月或下半月。'
              }}
            </div>
          </button>
        </div>

        <div v-if="selectedPeriodKey === 'custom'" class="work-report-create-dialog__custom-period">
          <div v-if="selectedReportType === 'weekly'" class="work-report-create-dialog__custom-row">
            <div class="work-report-create-dialog__field work-report-create-dialog__field--inline">
              <label class="work-report-create-dialog__label">周报周期</label>
              <ElDatePicker
                v-model="customWeekDate"
                type="date"
                format="YYYY[年第]ww[周]"
                value-format="YYYY-MM-DD"
                popper-class="work-report-create-date-popper"
                placeholder="请选择周报周期"
              />
              <div v-if="customPeriodPreviewLabel" class="work-report-create-dialog__period-preview">
                {{ customPeriodPreviewLabel }}
              </div>
            </div>
          </div>

          <div v-else-if="selectedReportType === 'monthly'" class="work-report-create-dialog__custom-row">
            <div class="work-report-create-dialog__field work-report-create-dialog__field--inline">
              <label class="work-report-create-dialog__label">月报周期</label>
              <ElDatePicker
                v-model="customMonth"
                type="month"
                value-format="YYYY-MM"
                popper-class="work-report-create-date-popper"
                placeholder="请选择月份"
              />
              <div v-if="customPeriodPreviewLabel" class="work-report-create-dialog__period-preview">
                {{ customPeriodPreviewLabel }}
              </div>
            </div>
          </div>

          <div v-else class="work-report-create-dialog__custom-project">
            <div class="work-report-create-dialog__custom-project-grid">
              <div class="work-report-create-dialog__custom-project-item">
                <div class="work-report-create-dialog__custom-project-item-label">选择月份</div>
                <ElDatePicker
                  v-model="customProjectMonth"
                  class="w-full"
                  type="month"
                  value-format="YYYY-MM"
                  popper-class="work-report-create-date-popper"
                  placeholder="请选择月份"
                />
              </div>
              <div class="work-report-create-dialog__custom-project-item">
                <div class="work-report-create-dialog__custom-project-item-label">选择半月</div>
                <ElSegmented
                  v-model="customProjectFlag"
                  :options="projectHalfOptions"
                  class="work-report-create-dialog__half-segmented"
                />
              </div>
            </div>
            <div v-if="customPeriodPreviewLabel" class="work-report-create-dialog__period-preview">
              <ElIcon class="work-report-create-dialog__period-preview-icon"><Calendar /></ElIcon>
              <span class="work-report-create-dialog__period-preview-text">已选周期：</span>
              <span class="work-report-create-dialog__period-preview-value">{{ customPeriodPreviewLabel }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer="{ close }">
      <div class="work-report-create-dialog__footer">
        <ElButton @click="close">取消</ElButton>
        <ElButton type="primary" :disabled="confirmDisabled" @click="handleConfirm">确认新增</ElButton>
      </div>
    </template>
  </BusinessFormDialog>
</template>

<style scoped>
.work-report-create-dialog__header {
  padding: 0 0 14px;
}

.work-report-create-dialog__title {
  margin: 0;
  font-size: 18px;
  font-weight: 900;
}

.work-report-create-dialog__subtitle {
  margin-top: 5px;
  color: #667085;
  font-size: 12px;
}

.work-report-create-dialog__section + .work-report-create-dialog__section {
  margin-top: 18px;
}

.work-report-create-dialog__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.work-report-create-dialog__grid.is-period {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.work-report-create-dialog__choice {
  padding: 16px;
  border: 2px solid #e5edf1;
  border-radius: 16px;
  background: #fbfdfe;
  text-align: left;
  cursor: pointer;
  transition:
    border-color 0.16s ease,
    background 0.16s ease,
    box-shadow 0.16s ease;
}

.work-report-create-dialog__choice:hover {
  border-color: var(--el-color-primary-light-3);
  box-shadow: 0 8px 20px rgba(15, 23, 42, 0.06);
}

.work-report-create-dialog__choice.is-active {
  border-color: var(--el-color-primary);
  background: var(--el-color-primary-light-9);
}

.work-report-create-dialog__choice-title {
  font-weight: 900;
  color: #14213d;
}

.work-report-create-dialog__choice-desc {
  margin-top: 7px;
  color: #667085;
  font-size: 12px;
  line-height: 1.5;
}

.work-report-create-dialog__project-select {
  margin: 4px 0 18px;
  display: grid;
  gap: 6px;
}

.work-report-create-dialog__project-select-control :deep(.el-select__wrapper) {
  min-height: 46px;
  border-radius: 12px;
  padding-inline: 14px;
}

.work-report-create-dialog__project-select-control :deep(.el-select__selected-item) {
  line-height: 1.4;
}

.work-report-create-dialog__field {
  display: grid;
  gap: 6px;
}

/** 行内字段：label 和控件在同一行，绿色 label 紧贴日期选择器右边 */
.work-report-create-dialog__field--inline {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.work-report-create-dialog__field--inline .work-report-create-dialog__label {
  flex-shrink: 0;
  white-space: nowrap;
}

.work-report-create-dialog__field--inline :deep(.el-date-editor) {
  width: auto;
  min-width: 160px;
  max-width: 240px;
}

.work-report-create-dialog__label {
  color: #667085;
  font-size: 12px;
  font-weight: 800;
}

.work-report-create-dialog__custom-period {
  margin-top: 14px;
  padding: 16px;
  border: 1px solid var(--el-color-primary-light-7);
  border-radius: 14px;
  background: linear-gradient(180deg, var(--el-color-primary-light-9) 0%, #ffffff 100%);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
}

.work-report-create-dialog__custom-row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
}

.work-report-create-dialog__custom-row > .work-report-create-dialog__field--inline {
  flex: 1;
  min-width: 0;
}

.work-report-create-dialog__custom-project {
  display: grid;
  gap: 14px;
}

.work-report-create-dialog__custom-project-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 14px;
  align-items: stretch;
}

.work-report-create-dialog__custom-project-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid #e5edf1;
  border-radius: 10px;
  background: #fff;
  transition: border-color 0.18s ease;
}

.work-report-create-dialog__custom-project-item:hover {
  border-color: var(--el-color-primary-light-5);
}

.work-report-create-dialog__custom-project-item-label {
  color: #475467;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

.work-report-create-dialog__custom-project-item :deep(.el-date-editor) {
  width: 100%;
}

.work-report-create-dialog__half-segmented {
  width: 100%;
  display: flex;
}

.work-report-create-dialog__half-segmented :deep(.el-segmented__group) {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: 100%;
  gap: 0;
}

.work-report-create-dialog__half-segmented :deep(.el-segmented__item) {
  flex: 1;
  min-width: 0;
  justify-content: center;
}

.work-report-create-dialog__period-preview {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 14px;
  border: 1px solid var(--el-color-primary-light-7);
  border-radius: 999px;
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  width: fit-content;
}

.work-report-create-dialog__period-preview-icon {
  font-size: 14px;
  color: var(--el-color-primary);
}

.work-report-create-dialog__period-preview-text {
  color: #475467;
  font-weight: 600;
}

.work-report-create-dialog__period-preview-value {
  color: var(--el-color-primary);
  font-weight: 800;
}

.work-report-create-dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

@media (width <= 900px) {
  .work-report-create-dialog__grid,
  .work-report-create-dialog__grid.is-period {
    grid-template-columns: 1fr;
  }

  .work-report-create-dialog__custom-row,
  .work-report-create-dialog__custom-project-grid {
    flex-direction: column;
    grid-template-columns: 1fr;
  }

  .work-report-create-dialog__field--inline {
    flex-wrap: wrap;
  }

  .work-report-create-dialog__field--inline :deep(.el-date-editor) {
    max-width: 100%;
    flex: 1;
  }

  .work-report-create-dialog__period-preview {
    justify-content: center;
    width: 100%;
  }
}

:global(.work-report-create-date-popper) {
  border-radius: 12px;
  overflow: hidden;
}

:global(.work-report-create-date-popper .el-picker-panel__body-wrapper) {
  background: #fff;
}

:global(.work-report-create-date-popper .el-date-table td.current:not(.disabled) .el-date-table-cell__text),
:global(.work-report-create-date-popper .el-month-table td.current:not(.disabled) .cell) {
  background-color: var(--el-color-primary);
}
</style>
