<script setup lang="ts">
/* eslint-disable complexity, no-nested-ternary, no-void, vue/no-deprecated-filter */
import { computed, reactive, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import dayjs from 'dayjs';
import {
  fetchApproveMonthlyReport,
  fetchApproveProjectReport,
  fetchApproveWeeklyReport,
  fetchCreateMonthlyReport,
  fetchCreateProjectReport,
  fetchCreateWeeklyReport,
  fetchGetMonthlyReportDetail,
  fetchGetProjectReportDetail,
  fetchGetWeeklyReportDetail,
  fetchInitMonthlyReport,
  fetchInitProjectReport,
  fetchInitWeeklyReport,
  fetchPerformanceMonthlyResult,
  fetchPreviewMonthlyReportDefaultDraft,
  fetchPreviewProjectReportDefaultDraft,
  fetchPreviewWeeklyReportDefaultDraft,
  fetchRefreshMonthlyReportDraft,
  fetchRefreshProjectReportDraft,
  fetchRefreshWeeklyReportDraft,
  fetchRejectMonthlyReport,
  fetchRejectProjectReport,
  fetchRejectWeeklyReport,
  fetchSubmitMonthlyReport,
  fetchSubmitProjectReport,
  fetchSubmitWeeklyReport,
  fetchUpdateMonthlyReport,
  fetchUpdateProjectReport,
  fetchUpdateWeeklyReport
} from '@/service/api';
import type { WorkReportRow, WorkReportType } from '../types';
import {
  createMonthlySaveParams,
  createProjectSaveParams,
  createWeeklySaveParams,
  formatPeriodLabel,
  getStructuredSections,
  normalizePlanItems,
  normalizeProjectItems,
  normalizeReviewItems
} from '../types';
import WeeklyReportPage from '../../weekly/modules/fill-page.vue';
import MonthlyReportPage from '../../monthly/modules/fill-page.vue';
import ProjectReportPage from '../../project/modules/fill-page.vue';
import MonthlyReportApprovalPage from '../../monthly/modules/approval-page.vue';
import WorkReportActionDialog from './action-dialog.vue';
import WorkReportPageDialog from './page-dialog.vue';

defineOptions({ name: 'WorkReportPrototypePageDialog' });

interface PeriodPayload {
  periodKey: string;
  periodLabel: string;
  periodStartDate: string;
  periodEndDate: string;
}

interface Props {
  reportType: WorkReportType;
  mode?: 'add' | 'edit' | 'detail';
  scene?: 'fill' | 'detail' | 'approval';
  rowData?: WorkReportRow | null;
  initialPeriod?: PeriodPayload | null;
  initialProjectId?: string;
  initialFlag?: number;
}

const props = withDefaults(defineProps<Props>(), {
  mode: 'detail',
  scene: 'detail',
  rowData: null,
  initialPeriod: null,
  initialProjectId: '',
  initialFlag: 1
});

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

const emit = defineEmits<{
  (e: 'submitted'): void;
}>();

const REPORT_TYPE_TEXT: Record<WorkReportType, string> = {
  weekly: '个人周报',
  monthly: '个人月报',
  project: '项目半月报'
};

const loading = ref(false);
const actionVisible = ref(false);
const actionSubmitting = ref(false);
const currentActionType = ref<'approve' | 'reject'>('approve');
const currentStage = ref<'form' | 'approval'>('form');
const currentReportId = ref('');
const baseInfo = ref<WorkReportRow | null>(null);
const monthlyApprovalDraft = reactive<Api.WorkReport.Monthly.MonthlyReportApproveParams>({
  reason: '',
  meetingDate: '',
  strengthDesc: '',
  strengthExample: '',
  weaknessDesc: '',
  weaknessExample: '',
  improvementSuggestion: '',
  performanceResult: '',
  employeeSignName: '',
  employeeSignedDate: '',
  supervisorSignName: '',
  supervisorSignedDate: ''
});
const monthlyPerformanceAutoFilled = ref(false);

const weeklyModel = reactive<Api.WorkReport.Weekly.WeeklyReportSaveParams>(createWeeklySaveParams());
const monthlyModel = reactive<Api.WorkReport.Monthly.MonthlyReportSaveParams>(createMonthlySaveParams());
const projectModel = reactive<Api.WorkReport.Project.ProjectReportSaveParams>(createProjectSaveParams());

const currentModel = computed(() => {
  if (props.reportType === 'monthly') return monthlyModel;
  if (props.reportType === 'project') return projectModel;
  return weeklyModel;
});

const currentScene = computed(() => {
  if (props.reportType === 'monthly' && currentStage.value === 'approval') {
    return 'approval';
  }

  return props.scene;
});

const dialogTitle = computed(() => {
  if (props.reportType === 'monthly' && currentStage.value === 'approval') {
    return `${REPORT_TYPE_TEXT.monthly}审批页`;
  }

  if (currentScene.value === 'approval') {
    return `${REPORT_TYPE_TEXT[props.reportType]}审批`;
  }

  if (props.mode === 'add') return `${REPORT_TYPE_TEXT[props.reportType]}填报页`;
  if (props.mode === 'edit') return `${REPORT_TYPE_TEXT[props.reportType]}编辑页`;
  return `${REPORT_TYPE_TEXT[props.reportType]}查看页`;
});

const periodText = computed(() => {
  const label = currentModel.value.periodLabel || props.rowData?.periodLabel || props.initialPeriod?.periodLabel;
  return formatPeriodLabel(label) || '当前周期';
});

function resetModels() {
  Object.assign(weeklyModel, createWeeklySaveParams());
  Object.assign(monthlyModel, createMonthlySaveParams());
  Object.assign(projectModel, createProjectSaveParams());
  Object.assign(monthlyApprovalDraft, {
    reason: '',
    meetingDate: '',
    strengthDesc: '',
    strengthExample: '',
    weaknessDesc: '',
    weaknessExample: '',
    improvementSuggestion: '',
    performanceResult: '',
    employeeSignName: '',
    employeeSignedDate: '',
    supervisorSignName: '',
    supervisorSignedDate: ''
  });
  monthlyPerformanceAutoFilled.value = false;
}

function patchMonthlyApprovalDefaults(report?: Partial<Api.WorkReport.Monthly.MonthlyReport> | null) {
  const today = dayjs().format('YYYY-MM-DD');

  Object.assign(monthlyApprovalDraft, {
    employeeSignName: monthlyApprovalDraft.employeeSignName || report?.reporterName || '',
    employeeSignedDate: monthlyApprovalDraft.employeeSignedDate || today,
    supervisorSignName: monthlyApprovalDraft.supervisorSignName || report?.supervisorName || '',
    supervisorSignedDate: monthlyApprovalDraft.supervisorSignedDate || today
  });
}

function patchPeriod(target: {
  periodKey: string;
  periodLabel: string;
  periodStartDate: string;
  periodEndDate: string;
}) {
  if (!props.initialPeriod) return;
  target.periodKey = props.initialPeriod.periodKey;
  target.periodLabel = props.initialPeriod.periodLabel;
  target.periodStartDate = props.initialPeriod.periodStartDate;
  target.periodEndDate = props.initialPeriod.periodEndDate;
}

function patchWeekly(report?: Partial<Api.WorkReport.Weekly.WeeklyReport>) {
  Object.assign(
    weeklyModel,
    createWeeklySaveParams({
      ...report,
      reviewItems: report?.reviewItems,
      planItems: report?.planItems,
      travelSegments: report?.travelSegments
    })
  );

  if (report && Array.isArray(report.reviewItems) && !report.reviewItems.length) weeklyModel.reviewItems = [];
  if (report && Array.isArray(report.planItems) && !report.planItems.length) weeklyModel.planItems = [];
  if (report && Array.isArray(report.travelSegments) && !report.travelSegments.length) weeklyModel.travelSegments = [];

  if (props.mode === 'add') patchPeriod(weeklyModel);
}

function patchMonthly(report?: Partial<Api.WorkReport.Monthly.MonthlyReport>) {
  Object.assign(
    monthlyModel,
    createMonthlySaveParams({
      ...report,
      reviewItems: report?.reviewItems,
      planItems: report?.planItems
    })
  );

  if (report && Array.isArray(report.reviewItems) && !report.reviewItems.length) monthlyModel.reviewItems = [];
  if (report && Array.isArray(report.planItems) && !report.planItems.length) monthlyModel.planItems = [];

  if (props.mode === 'add') patchPeriod(monthlyModel);
  patchMonthlyApprovalDefaults(report);
}

function patchProject(report?: Partial<Api.WorkReport.Project.ProjectReport>) {
  Object.assign(
    projectModel,
    createProjectSaveParams({
      ...report,
      projectId: report?.projectId || props.initialProjectId,
      flag: report?.flag ?? props.initialFlag,
      currentItems: report?.currentItems,
      nextItems: report?.nextItems
    })
  );

  if (report && Array.isArray(report.currentItems) && !report.currentItems.length) projectModel.currentItems = [];
  if (report && Array.isArray(report.nextItems) && !report.nextItems.length) projectModel.nextItems = [];

  if (props.mode === 'add') patchPeriod(projectModel);
}

function applyWeeklyEditableFields(draft: Api.WorkReport.Weekly.WeeklyReport) {
  weeklyModel.isBusinessTrip = draft.isBusinessTrip;
  weeklyModel.reviewItems = draft.reviewItems?.length ? normalizeReviewItems(draft.reviewItems) : [];
  weeklyModel.planItems = draft.planItems?.length ? normalizePlanItems(draft.planItems) : [];
  weeklyModel.travelSegments = draft.travelSegments || [];
}

function applyMonthlyEditableFields(draft: Api.WorkReport.Monthly.MonthlyReport) {
  monthlyModel.reviewItems = draft.reviewItems?.length ? normalizeReviewItems(draft.reviewItems) : [];
  monthlyModel.planItems = draft.planItems?.length ? normalizePlanItems(draft.planItems) : [];
}

function applyProjectEditableFields(draft: Api.WorkReport.Project.ProjectReport) {
  projectModel.projectStatusDesc = draft.projectStatusDesc || '';
  projectModel.projectProgressPlan = draft.projectProgressPlan || '';
  projectModel.projectKeyPoints = draft.projectKeyPoints || '';
  projectModel.projectProblems = draft.projectProblems || '';
  projectModel.currentItems = draft.currentItems?.length ? normalizeProjectItems(draft.currentItems) : [];
  projectModel.nextItems = draft.nextItems?.length ? normalizeProjectItems(draft.nextItems) : [];
}

function firstMeaningfulValue<T>(...values: Array<T | null | undefined | ''>) {
  return values.find(value => value !== null && value !== undefined && value !== '') as T | undefined;
}

function firstPositiveWorkHours(...values: Array<string | number | null | undefined>) {
  const matchedValue = values.find(value => {
    const numberValue = Number(value ?? 0);
    return Number.isFinite(numberValue) && numberValue > 0;
  });

  return matchedValue ?? firstMeaningfulValue(...values);
}

function mergePersonalDetailBaseInfo<
  T extends Api.WorkReport.Weekly.WeeklyReport | Api.WorkReport.Monthly.MonthlyReport
>(detail: T) {
  const rowData = props.rowData as Partial<T> | null;
  if (!rowData) return detail;

  return {
    ...rowData,
    ...detail,
    reporterDeptName: firstMeaningfulValue(detail.reporterDeptName, rowData.reporterDeptName) ?? null,
    reporterPostName: firstMeaningfulValue(detail.reporterPostName, rowData.reporterPostName) ?? null,
    submitTime: firstMeaningfulValue(detail.submitTime, rowData.submitTime) ?? null,
    totalWorkHours: firstPositiveWorkHours(detail.totalWorkHours, rowData.totalWorkHours)
  } as T;
}

function mergeProjectDetailBaseInfo(detail: Api.WorkReport.Project.ProjectReport) {
  const rowData = props.rowData as Partial<Api.WorkReport.Project.ProjectReport> | null;
  if (!rowData) return detail;

  return {
    ...rowData,
    ...detail,
    submitTime: firstMeaningfulValue(detail.submitTime, rowData.submitTime) ?? null,
    totalWorkHours: firstPositiveWorkHours(detail.totalWorkHours, rowData.totalWorkHours)
  };
}

async function loadDetail(id: string) {
  loading.value = true;
  let result;

  if (props.reportType === 'weekly') {
    result = await fetchGetWeeklyReportDetail(id);
  } else if (props.reportType === 'monthly') {
    result = await fetchGetMonthlyReportDetail(id);
  } else {
    result = await fetchGetProjectReportDetail(id);
  }
  loading.value = false;

  if (result.error || !result.data) return;

  const detail =
    props.reportType === 'weekly'
      ? mergePersonalDetailBaseInfo(result.data as Api.WorkReport.Weekly.WeeklyReport)
      : props.reportType === 'monthly'
        ? mergePersonalDetailBaseInfo(result.data as Api.WorkReport.Monthly.MonthlyReport)
        : mergeProjectDetailBaseInfo(result.data as Api.WorkReport.Project.ProjectReport);

  currentReportId.value = detail.id;
  baseInfo.value = detail;

  if (props.reportType === 'weekly') patchWeekly(detail as Api.WorkReport.Weekly.WeeklyReport);
  if (props.reportType === 'monthly') patchMonthly(detail as Api.WorkReport.Monthly.MonthlyReport);
  if (props.reportType === 'project') patchProject(detail as Api.WorkReport.Project.ProjectReport);
}

async function pullDefaultDraft(confirmOverwrite = false) {
  const period = {
    periodKey: currentModel.value.periodKey,
    periodLabel: currentModel.value.periodLabel,
    periodStartDate: currentModel.value.periodStartDate,
    periodEndDate: currentModel.value.periodEndDate
  };

  loading.value = true;
  let result;

  if (props.reportType === 'weekly') {
    result = await fetchPreviewWeeklyReportDefaultDraft(period);
  } else if (props.reportType === 'monthly') {
    result = await fetchPreviewMonthlyReportDefaultDraft(period);
  } else {
    result = await fetchPreviewProjectReportDefaultDraft(projectModel.projectId, {
      ...period,
      flag: projectModel.flag
    });
  }
  loading.value = false;

  if (result.error || !result.data) return;

  baseInfo.value = {
    ...(baseInfo.value || {}),
    ...result.data
  } as WorkReportRow;

  if (props.reportType === 'weekly') {
    const data = result.data as Api.WorkReport.Weekly.WeeklyReport;
    applyWeeklyEditableFields(data);
    if (confirmOverwrite) {
      weeklyModel.travelSegments = data.travelSegments || [];
    }
  }

  if (props.reportType === 'monthly') {
    applyMonthlyEditableFields(result.data as Api.WorkReport.Monthly.MonthlyReport);
  }

  if (props.reportType === 'project') {
    applyProjectEditableFields(result.data as Api.WorkReport.Project.ProjectReport);
  }
}

async function refreshDraft(showSuccess = true) {
  if (props.mode !== 'edit') {
    await pullDefaultDraft(true);
    return;
  }

  loading.value = true;
  let result;

  if (props.reportType === 'weekly') {
    result = await fetchRefreshWeeklyReportDraft(weeklyModel);
  } else if (props.reportType === 'monthly') {
    result = await fetchRefreshMonthlyReportDraft(monthlyModel);
  } else {
    result = await fetchRefreshProjectReportDraft(projectModel.projectId, {
      periodKey: projectModel.periodKey,
      periodLabel: projectModel.periodLabel,
      periodStartDate: projectModel.periodStartDate,
      periodEndDate: projectModel.periodEndDate,
      flag: projectModel.flag,
      projectStatusDesc: projectModel.projectStatusDesc,
      projectProgressPlan: projectModel.projectProgressPlan,
      projectKeyPoints: projectModel.projectKeyPoints,
      projectProblems: projectModel.projectProblems,
      currentItems: projectModel.currentItems,
      nextItems: projectModel.nextItems
    });
  }
  loading.value = false;

  if (result.error || !result.data) return;

  baseInfo.value = {
    ...(baseInfo.value || {}),
    ...result.data
  } as WorkReportRow;

  if (props.reportType === 'weekly') {
    applyWeeklyEditableFields(result.data as Api.WorkReport.Weekly.WeeklyReport);
  } else if (props.reportType === 'monthly') {
    applyMonthlyEditableFields(result.data as Api.WorkReport.Monthly.MonthlyReport);
  } else {
    applyProjectEditableFields(result.data as Api.WorkReport.Project.ProjectReport);
  }

  if (showSuccess) {
    window.$message?.success('最新数据已刷新');
  }
}

async function loadInitData() {
  loading.value = true;
  let result;

  if (props.reportType === 'weekly') {
    result = await fetchInitWeeklyReport();
  } else if (props.reportType === 'monthly') {
    result = await fetchInitMonthlyReport();
  } else {
    result = await fetchInitProjectReport(props.initialProjectId);
  }

  if (!result.error && result.data) {
    baseInfo.value = result.data;
    if (props.reportType === 'weekly') patchWeekly(result.data as Api.WorkReport.Weekly.WeeklyReport);
    if (props.reportType === 'monthly') patchMonthly(result.data as Api.WorkReport.Monthly.MonthlyReport);
    if (props.reportType === 'project') patchProject(result.data as Api.WorkReport.Project.ProjectReport);
  }

  loading.value = false;
  await pullDefaultDraft();
}

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

  currentStage.value = props.reportType === 'monthly' && props.scene === 'approval' ? 'approval' : 'form';
  currentReportId.value = props.rowData?.id || '';
  baseInfo.value = null;
  resetModels();

  if (props.mode === 'add') {
    if (props.reportType === 'project') {
      projectModel.projectId = props.initialProjectId;
      projectModel.flag = props.initialFlag;
    }
    patchPeriod(currentModel.value);
    await loadInitData();
    return;
  }

  if (props.rowData?.id) {
    await loadDetail(props.rowData.id);
    if (props.mode === 'edit') {
      await refreshDraft(false);
    }
    await fillMonthlyPerformanceResult();
  }
});

watch(
  () => currentStage.value,
  stage => {
    if (stage === 'approval') {
      fillMonthlyPerformanceResult();
    }
  }
);

function hasTextValue(value: unknown) {
  const text = String(value ?? '')
    .replace(/<[^>]*>/g, '')
    .replace(/&nbsp;/g, ' ')
    .trim();

  return text.length > 0;
}

function hasMeaningfulStructuredValue(value: unknown): boolean {
  if (value === null || value === undefined) return false;

  if (typeof value === 'string') {
    const text = value.trim();
    if (!text || text === '{}' || text === '[]') return false;

    try {
      return hasMeaningfulStructuredValue(JSON.parse(text));
    } catch {
      return hasTextValue(text);
    }
  }

  if (Array.isArray(value)) {
    return value.some(item => hasMeaningfulStructuredValue(item));
  }

  if (typeof value === 'object') {
    return Object.values(value as Record<string, unknown>).some(item => hasMeaningfulStructuredValue(item));
  }

  return false;
}

function hasReviewContent(item: Api.WorkReport.Common.PersonalReportReviewItem) {
  return hasTextValue(item.contentText) || hasMeaningfulStructuredValue(item.contentJson);
}

function hasPlanTarget(item: Api.WorkReport.Common.PersonalReportPlanItem) {
  return hasTextValue(item.targetText) || hasMeaningfulStructuredValue(item.targetJson);
}

function isCompleteWeeklyTravelSegment(segment: Api.WorkReport.Weekly.WeeklyReportTravelSegment) {
  const travelDays = Number(segment.travelDays);

  return Boolean(
    segment.startDate &&
      segment.endDate &&
      Number.isFinite(travelDays) &&
      travelDays >= 0.5 &&
      Number.isInteger(travelDays * 2)
  );
}

function hasCompleteWeeklyTravelSegment(items: Api.WorkReport.Weekly.WeeklyReportTravelSegment[]) {
  return items.some(isCompleteWeeklyTravelSegment);
}

/**
 * 周报"具体工作内容及成果描述"中已记录出差信息（"本周差旅"分类、或含"差旅"分类、
 * 或结构化任务里带 kind=travel）时，视为已经有完整出差分段，不再强制弹出
 * "请至少新增一条完整的出差分段"。避免出差点位等历史录入原因导致保存时反复提示。
 */
function hasTravelInfoInWeeklyReview(items: Api.WorkReport.Common.PersonalReportReviewItem[]) {
  return items.some(item => {
    if (item.itemTitle?.trim() === '本周差旅') return true;
    const sections = getStructuredSections(item.contentJson);
    if (sections.some(section => section.category?.trim() === '差旅')) return true;
    if (sections.some(section => section.tasks.some(task => task.kind === 'travel'))) return true;
    return false;
  });
}

function hasCompletePersonalReviewItem(items: Api.WorkReport.Common.PersonalReportReviewItem[]) {
  return items.some(item => hasTextValue(item.itemTitle) && hasReviewContent(item));
}

function hasCompletePersonalPlanItem(items: Api.WorkReport.Common.PersonalReportPlanItem[]) {
  return items.some(item => hasTextValue(item.itemTitle) && hasPlanTarget(item));
}

function getPersonalReviewValidationMessage(label: string, items: Api.WorkReport.Common.PersonalReportReviewItem[]) {
  if (!items.length) return `至少要有一项${label}`;
  if (!hasCompletePersonalReviewItem(items)) {
    return `请完善${label}，项目名或我的事项、具体工作内容及成果描述不能为空`;
  }

  const hasIncompleteItem = items.some(item => !hasTextValue(item.itemTitle) || !hasReviewContent(item));
  return hasIncompleteItem ? `请完善${label}，项目名或我的事项、具体工作内容及成果描述不能为空` : '';
}

function getPersonalPlanValidationMessage(label: string, items: Api.WorkReport.Common.PersonalReportPlanItem[]) {
  if (!items.length) return `至少要有一项${label}`;
  if (!hasCompletePersonalPlanItem(items)) {
    return `请完善${label}，项目名或我的事项、具体目标不能为空`;
  }

  const hasIncompleteItem = items.some(item => !hasTextValue(item.itemTitle) || !hasPlanTarget(item));
  return hasIncompleteItem ? `请完善${label}，项目名或我的事项、具体目标不能为空` : '';
}

function hasProjectItem(items: Api.WorkReport.Project.ProjectReportItem[]) {
  return items.some(item => hasTextValue(item.itemTitle));
}

function validateRequiredReportItems() {
  const messages: string[] = [];

  if (props.reportType === 'weekly') {
    // 出差信息既可能来自 travelSegments，也可能来自具体工作内容及成果描述里的"差旅"段，
    // 任何一方已有完整出差信息就不再提示"请至少新增一条完整的出差分段"。
    const hasTravelReview =
      weeklyModel.isBusinessTrip &&
      (hasCompleteWeeklyTravelSegment(weeklyModel.travelSegments) ||
        hasTravelInfoInWeeklyReview(weeklyModel.reviewItems));
    const reviewMessage = hasTravelReview
      ? weeklyModel.reviewItems.length
        ? getPersonalReviewValidationMessage('当期重点工作回顾', weeklyModel.reviewItems)
        : ''
      : getPersonalReviewValidationMessage('当期重点工作回顾', weeklyModel.reviewItems);
    const planMessage = getPersonalPlanValidationMessage('下周期重点工作计划', weeklyModel.planItems);
    if (weeklyModel.isBusinessTrip && !hasTravelReview) messages.push('请至少新增一条完整的出差分段');
    if (reviewMessage) messages.push(reviewMessage);
    if (planMessage) messages.push(planMessage);
  } else if (props.reportType === 'monthly') {
    const reviewMessage = getPersonalReviewValidationMessage('当期重点工作回顾', monthlyModel.reviewItems);
    const planMessage = getPersonalPlanValidationMessage('下周期重点工作计划', monthlyModel.planItems);
    if (reviewMessage) messages.push(reviewMessage);
    if (planMessage) messages.push(planMessage);
  } else {
    const missingLabels: string[] = [];

    if (!hasProjectItem(projectModel.currentItems)) {
      missingLabels.push('本期工作内容');
    }
    if (!hasProjectItem(projectModel.nextItems)) {
      missingLabels.push('下期计划工作内容');
    }

    if (missingLabels.length) messages.push(`至少要有一项${missingLabels.join('、')}`);
  }

  if (!messages.length) return true;

  window.$message?.warning(messages.join('；'));
  return false;
}

async function persistReport(submitAfterSave: boolean) {
  if (!validateRequiredReportItems()) return false;

  let result;

  if (props.reportType === 'weekly') {
    if (currentReportId.value) {
      result = await fetchUpdateWeeklyReport(currentReportId.value, weeklyModel);
    } else {
      result = await fetchCreateWeeklyReport(weeklyModel);
      if (!result.error && result.data) currentReportId.value = result.data;
    }
  } else if (props.reportType === 'monthly') {
    if (currentReportId.value) {
      result = await fetchUpdateMonthlyReport(currentReportId.value, monthlyModel);
    } else {
      result = await fetchCreateMonthlyReport(monthlyModel);
      if (!result.error && result.data) currentReportId.value = result.data;
    }
  } else if (currentReportId.value) {
    result = await fetchUpdateProjectReport(currentReportId.value, projectModel);
  } else {
    result = await fetchCreateProjectReport(projectModel);
    if (!result.error && result.data) currentReportId.value = result.data;
  }

  if (result.error) return false;

  if (submitAfterSave) {
    if (props.reportType === 'weekly') {
      const submitResult = await fetchSubmitWeeklyReport(currentReportId.value);
      if (submitResult.error) return false;
    } else if (props.reportType === 'monthly') {
      const submitResult = await fetchSubmitMonthlyReport(currentReportId.value);
      if (submitResult.error) return false;
    } else {
      const submitResult = await fetchSubmitProjectReport(currentReportId.value);
      if (submitResult.error) return false;
    }
  }

  return true;
}

async function handleSaveDraft() {
  loading.value = true;
  const success = await persistReport(false);
  loading.value = false;

  if (!success) return;

  window.$message?.success('工作报告已保存');
  visible.value = false;
  emit('submitted');
}

async function handleSubmitReport() {
  try {
    await ElMessageBox.confirm('确认提交当前工作报告吗？', '提交确认', {
      type: 'warning',
      confirmButtonText: '确认提交',
      cancelButtonText: '取消'
    });
  } catch {
    return;
  }

  loading.value = true;
  const success = await persistReport(true);
  loading.value = false;

  if (!success) return;

  window.$message?.success('工作报告已提交');
  visible.value = false;
  emit('submitted');
}

function handleBack() {
  visible.value = false;
}

function handleViewApproval() {
  currentStage.value = 'approval';
  fillMonthlyPerformanceResult();
}

function resolveMonthlyPeriodMonth() {
  const startDate = monthlyModel.periodStartDate || baseInfo.value?.periodStartDate;
  const fromStartDate = dayjs(startDate);
  if (fromStartDate.isValid()) {
    return fromStartDate.format('YYYY-MM');
  }

  const periodKey = monthlyModel.periodKey || baseInfo.value?.periodKey;
  const periodKeyMatch = String(periodKey || '').match(/(\d{4})[-/年]?(\d{1,2})/u);
  if (periodKeyMatch) {
    return `${periodKeyMatch[1]}-${periodKeyMatch[2].padStart(2, '0')}`;
  }

  const periodLabel = monthlyModel.periodLabel || baseInfo.value?.periodLabel;
  const periodLabelMatch = String(periodLabel || '').match(/(\d{4})[-/年]?(\d{1,2})/u);
  if (periodLabelMatch) {
    return `${periodLabelMatch[1]}-${periodLabelMatch[2].padStart(2, '0')}`;
  }

  return '';
}

async function fillMonthlyPerformanceResult() {
  if (props.reportType !== 'monthly' || monthlyPerformanceAutoFilled.value) return;
  if (monthlyApprovalDraft.performanceResult?.trim()) return;

  const employeeId = (baseInfo.value as Api.WorkReport.Monthly.MonthlyReport | null)?.reporterId;
  const periodMonth = resolveMonthlyPeriodMonth();
  if (!employeeId || !periodMonth) return;

  monthlyPerformanceAutoFilled.value = true;
  const { error, data } = await fetchPerformanceMonthlyResult(employeeId, periodMonth);
  if (error || !data?.actualScoreTotal) return;
  if (monthlyApprovalDraft.performanceResult?.trim()) return;

  monthlyApprovalDraft.performanceResult = String(data.actualScoreTotal);
}

function handleRequestApprove() {
  if (props.reportType === 'monthly') {
    handleActionSubmit({ ...monthlyApprovalDraft }, 'approve');
    return;
  }
  currentActionType.value = 'approve';
  actionVisible.value = true;
}

function handleRequestReject() {
  if (props.reportType === 'monthly') {
    handleActionSubmit({ reason: monthlyApprovalDraft.reason }, 'reject');
    return;
  }
  currentActionType.value = 'reject';
  actionVisible.value = true;
}

function handlePullDefaultDraft() {
  refreshDraft();
}

function handleMonthlyApprovalChange(payload: Api.WorkReport.Monthly.MonthlyReportApproveParams) {
  Object.assign(monthlyApprovalDraft, payload);
}

async function handleActionSubmit(
  payload: Api.WorkReport.Common.StatusActionParams | Api.WorkReport.Monthly.MonthlyReportApproveParams,
  actionTypeOverride?: 'approve' | 'reject'
) {
  if (!currentReportId.value) return;

  const actionType = actionTypeOverride || currentActionType.value;
  actionSubmitting.value = true;
  let result;

  if (props.reportType === 'weekly') {
    result =
      actionType === 'approve'
        ? await fetchApproveWeeklyReport(currentReportId.value, payload)
        : await fetchRejectWeeklyReport(currentReportId.value, payload);
  } else if (props.reportType === 'monthly') {
    result =
      actionType === 'approve'
        ? await fetchApproveMonthlyReport(
            currentReportId.value,
            payload as Api.WorkReport.Monthly.MonthlyReportApproveParams
          )
        : await fetchRejectMonthlyReport(currentReportId.value, payload);
  } else {
    result =
      actionType === 'approve'
        ? await fetchApproveProjectReport(currentReportId.value, payload)
        : await fetchRejectProjectReport(currentReportId.value, payload);
  }
  actionSubmitting.value = false;

  if (result.error) return;

  actionVisible.value = false;
  window.$message?.success(actionType === 'approve' ? '审批已通过' : '工作报告已退回');
  visible.value = false;
  emit('submitted');
}
</script>

<template>
  <WorkReportPageDialog
    v-model:visible="visible"
    :title="dialogTitle"
    :loading="loading"
    :approval-mode="currentScene === 'approval'"
    @close="currentStage = 'form'"
  >
    <WeeklyReportPage
      v-if="reportType === 'weekly'"
      :report-type="REPORT_TYPE_TEXT[reportType]"
      :period="periodText"
      :mode="mode"
      :scene="currentScene"
      :base-info="baseInfo as Api.WorkReport.Weekly.WeeklyReport | null"
      :model="weeklyModel"
      @back="handleBack"
      @save="handleSaveDraft"
      @submit="handleSubmitReport"
      @request-approve="handleRequestApprove"
      @request-reject="handleRequestReject"
      @pull-default-draft="handlePullDefaultDraft"
    />

    <MonthlyReportApprovalPage
      v-else-if="reportType === 'monthly' && currentStage === 'approval'"
      :report-type="REPORT_TYPE_TEXT[reportType]"
      :period="periodText"
      :mode="mode"
      scene="approval"
      :base-info="baseInfo as Api.WorkReport.Monthly.MonthlyReport | null"
      :model="monthlyModel"
      :approval-model="monthlyApprovalDraft"
      @back="handleBack"
      @change-approval="handleMonthlyApprovalChange"
      @request-approve="handleRequestApprove"
      @request-reject="handleRequestReject"
    />

    <MonthlyReportPage
      v-else-if="reportType === 'monthly'"
      :report-type="REPORT_TYPE_TEXT[reportType]"
      :period="periodText"
      :mode="mode"
      :scene="currentScene"
      :base-info="baseInfo as Api.WorkReport.Monthly.MonthlyReport | null"
      :model="monthlyModel"
      @back="handleBack"
      @save="handleSaveDraft"
      @submit="handleSubmitReport"
      @view-approval="handleViewApproval"
      @pull-default-draft="handlePullDefaultDraft"
    />

    <ProjectReportPage
      v-else
      :report-type="REPORT_TYPE_TEXT[reportType]"
      :period="periodText"
      :mode="mode"
      :scene="currentScene"
      :base-info="baseInfo as Api.WorkReport.Project.ProjectReport | null"
      :model="projectModel"
      @back="handleBack"
      @save="handleSaveDraft"
      @submit="handleSubmitReport"
      @request-approve="handleRequestApprove"
      @request-reject="handleRequestReject"
      @pull-default-draft="handlePullDefaultDraft"
    />
  </WorkReportPageDialog>

  <WorkReportActionDialog
    v-model:visible="actionVisible"
    :report-type="reportType"
    :action-type="currentActionType"
    :initial-monthly-approve-data="reportType === 'monthly' ? monthlyApprovalDraft : null"
    :loading="actionSubmitting"
    append-to-body
    @submit="handleActionSubmit"
  />
</template>
