<script setup lang="ts">
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';
import dayjs from 'dayjs';
import {
  downloadFile,
  fetchConfirmMonthlyReportSignOff,
  fetchGetMonthlyReportSignOffDetail,
  fetchGetMyUserSignature
} from '@/service/api';
import MonthlyReportApprovalPage from './approval-page.vue';

defineOptions({ name: 'MonthlySignOffPage' });

const props = defineProps<{
  reportId?: string;
  baseInfo?: Api.WorkReport.Monthly.MonthlyReport | null;
}>();

const emit = defineEmits<{
  back: [];
  submitted: [];
}>();

const loading = ref(false);
const submitting = ref(false);
const detail = ref<Api.WorkReport.Monthly.MonthlyReportSignOffDetail | null>(null);
const supervisorSignaturePreviewUrl = ref('');
const supervisorSignatureObjectUrl = ref<string | null>(null);
const employeeSignaturePreviewUrl = ref('');
const employeeSignatureObjectUrl = ref<string | null>(null);

const report = computed(() => detail.value?.report || props.baseInfo || null);
const monthlyModel = computed<Api.WorkReport.Monthly.MonthlyReportSaveParams>(() => ({
  periodKey: report.value?.periodKey || '',
  periodLabel: report.value?.periodLabel || '',
  periodStartDate: report.value?.periodStartDate || '',
  periodEndDate: report.value?.periodEndDate || '',
  reviewItems: report.value?.reviewItems || [],
  planItems: report.value?.planItems || []
}));

const approvalDraft = reactive<Api.WorkReport.Monthly.MonthlyReportApproveParams>({
  reason: '',
  meetingDate: dayjs().format('YYYY-MM-DD'),
  strengthDesc: '',
  strengthExample: '',
  weaknessDesc: '',
  weaknessExample: '',
  improvementSuggestion: '',
  performanceResult: '',
  employeeSignName: undefined,
  employeeSignedDate: dayjs().format('YYYY-MM-DD'),
  supervisorSignName: '',
  supervisorSignedDate: ''
});

function patchApprovalRecord(record: Api.WorkReport.Monthly.MonthlyReportApprovalRecord | null | undefined) {
  Object.assign(approvalDraft, {
    reason: '',
    meetingDate: dayjs().format('YYYY-MM-DD'),
    strengthDesc: record?.strengthDesc || '',
    strengthExample: record?.strengthExample || '',
    weaknessDesc: record?.weaknessDesc || '',
    weaknessExample: record?.weaknessExample || '',
    improvementSuggestion: record?.improvementSuggestion || '',
    performanceResult: record?.performanceResult || '',
    employeeSignName: record?.employeeSignName,
    employeeSignedDate: dayjs().format('YYYY-MM-DD'),
    supervisorSignName: record?.supervisorSignName || '',
    supervisorSignedDate: record?.supervisorSignedDate || ''
  });
}

function revokePreviewUrl(target: 'supervisor' | 'employee') {
  const refValue = target === 'supervisor' ? supervisorSignatureObjectUrl : employeeSignatureObjectUrl;
  const previewRef = target === 'supervisor' ? supervisorSignaturePreviewUrl : employeeSignaturePreviewUrl;

  if (refValue.value) {
    URL.revokeObjectURL(refValue.value);
    refValue.value = null;
  }

  previewRef.value = '';
}

async function loadSignaturePreview(fileId: string | null | undefined, target: 'supervisor' | 'employee') {
  revokePreviewUrl(target);

  if (!fileId) {
    return;
  }

  const { error, data } = await downloadFile(fileId);
  if (error || !data) {
    return;
  }

  const objectUrl = URL.createObjectURL(data);
  if (target === 'supervisor') {
    supervisorSignatureObjectUrl.value = objectUrl;
    supervisorSignaturePreviewUrl.value = objectUrl;
    return;
  }

  employeeSignatureObjectUrl.value = objectUrl;
  employeeSignaturePreviewUrl.value = objectUrl;
}

async function loadDetail() {
  if (!props.reportId) {
    detail.value = null;
    patchApprovalRecord(null);
    revokePreviewUrl('supervisor');
    revokePreviewUrl('employee');
    return;
  }

  loading.value = true;
  const [detailResult, mySignatureResult] = await Promise.all([
    fetchGetMonthlyReportSignOffDetail(props.reportId),
    fetchGetMyUserSignature()
  ]);
  loading.value = false;

  if (detailResult.error || !detailResult.data) {
    detail.value = null;
    patchApprovalRecord(null);
    revokePreviewUrl('supervisor');
    revokePreviewUrl('employee');
    return;
  }

  detail.value = detailResult.data;
  patchApprovalRecord(detailResult.data.latestApprovalRecord);

  await Promise.all([
    loadSignaturePreview(detailResult.data.latestApprovalRecord?.supervisorSignatureFileId, 'supervisor'),
    loadSignaturePreview(mySignatureResult.error ? null : mySignatureResult.data?.fileId, 'employee')
  ]);
}

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

async function handleConfirm() {
  if (!props.reportId) {
    return;
  }

  submitting.value = true;
  const result = await fetchConfirmMonthlyReportSignOff(props.reportId, {
    meetingDate: approvalDraft.meetingDate || dayjs().format('YYYY-MM-DD'),
    employeeSignedDate: approvalDraft.employeeSignedDate || undefined
  });
  submitting.value = false;

  if (result.error) {
    return;
  }

  window.$message?.success('月报下签确认成功');
  emit('submitted');
}

watch(
  () => props.reportId,
  () => {
    loadDetail();
  },
  { immediate: true }
);

onBeforeUnmount(() => {
  revokePreviewUrl('supervisor');
  revokePreviewUrl('employee');
});
</script>

<template>
  <div v-loading="loading">
    <MonthlyReportApprovalPage
      report-type="个人月报"
      :period="report?.periodLabel || ''"
      mode="detail"
      scene="sign-off"
      :base-info="report"
      :model="monthlyModel"
      :approval-model="approvalDraft"
      :supervisor-signature-preview-url="supervisorSignaturePreviewUrl"
      :employee-signature-preview-url="employeeSignaturePreviewUrl"
      :supervisor-signature-loading="false"
      @back="emit('back')"
      @change-approval="handleApprovalChange"
      @request-confirm-sign-off="handleConfirm"
    />
  </div>
</template>
