<template>
  <a-spin :spinning="loading">
    <section class="improvement-proposal-bpm-form">
      <div class="section-header">
        <span>基本信息</span>
      </div>
      <a-descriptions bordered size="small" :column="2">
        <a-descriptions-item label="提案编号">{{ proposal.proposalNo || '-' }}</a-descriptions-item>
        <a-descriptions-item label="提案名称">{{ proposal.proposalName || '-' }}</a-descriptions-item>
        <a-descriptions-item label="提出日期">{{ formatDate(proposal.proposalDate) }}</a-descriptions-item>
        <a-descriptions-item label="提案类别">{{ proposal.proposalCategory || '-' }}</a-descriptions-item>
        <a-descriptions-item label="提案部门">{{ proposal.proposalDeptName || '-' }}</a-descriptions-item>
        <a-descriptions-item label="申请人">{{ proposal.applicantName || '-' }}</a-descriptions-item>
        <a-descriptions-item label="团队名称" :span="2">{{ proposal.teamName || '-' }}</a-descriptions-item>
        <a-descriptions-item label="问题描述" :span="2">{{ proposal.problemDesc || '-' }}</a-descriptions-item>
        <a-descriptions-item label="改善方法及措施" :span="2">{{ proposal.improvementMethod || '-' }}</a-descriptions-item>
        <a-descriptions-item label="改善前情况" :span="2">{{ proposal.beforeDesc || '-' }}</a-descriptions-item>
        <a-descriptions-item label="改善后情况" :span="2">{{ proposal.afterDesc || '-' }}</a-descriptions-item>
        <a-descriptions-item label="改善效果" :span="2">{{ proposal.improvementEffect || '-' }}</a-descriptions-item>
        <a-descriptions-item label="附件" :span="2">
          <div v-if="proposal.id" class="attachment-grid">
            <div>
              <div class="attachment-label">改善前附件</div>
              <SUploadFile :bussiness-id="`${proposal.id}:before`" :disabled="true" :multiple="true" />
            </div>
            <div>
              <div class="attachment-label">改善后附件</div>
              <SUploadFile :bussiness-id="`${proposal.id}:after`" :disabled="true" :multiple="true" />
            </div>
          </div>
          <span v-else>-</span>
        </a-descriptions-item>
      </a-descriptions>

      <template v-if="showProcessHandle">
        <a-divider />
        <div class="section-header">
          <span>流程办理</span>
        </div>

        <a-form class="process-form" :label-col="labelCol" :wrapper-col="wrapperCol">
          <a-form-item v-if="isTask('Task_improve001')" label="初步评定奖项" required>
            <JDictSelectTag v-model:value="initialAward" dictCode="proposal_prize" type="radio" />
            <div class="form-help">金奖、银奖进入部门评议小组打分；铜奖、参与奖直接进入部门负责人审核。</div>
          </a-form-item>

          <template v-if="isTask('Task_improve002')">
            <a-form-item label="我的评分">
              <a-descriptions bordered size="small" :column="1">
                <a-descriptions-item label="评分状态">{{ scoreStatusLabel }}</a-descriptions-item>
                <a-descriptions-item label="加权总分">{{ currentScore?.totalScore ?? '-' }}</a-descriptions-item>
                <a-descriptions-item label="评分时间" :span="2">{{ formatDateTime(currentScore?.scoreTime) }}</a-descriptions-item>
              </a-descriptions>
            </a-form-item>
            <a-form-item label="评分操作">
              <a-button type="primary" :disabled="scoreLocked" @click="openScoreModal">{{ scoreLocked ? '评分已锁定' : '打分' }}</a-button>
            </a-form-item>
          </template>

          <template v-if="isTask('Task_improve003')">
            <a-form-item label="初步评定奖项">{{ awardLabel(proposal.initialAward) }}</a-form-item>
            <a-form-item v-if="proposal.needDeptScore === '1'" label="部门评议小组打分结果">
              平均分：{{ proposal.deptAvgScore ?? '-' }}；建议奖项：{{ awardLabel(proposal.suggestedAward) }}
            </a-form-item>
            <a-form-item label="负责人确认奖项" required>
              <a-radio-group v-if="leaderAwardBase" v-model:value="leaderFinalAward">
                <a-radio v-for="item in leaderAwardOptions" :key="item.value" :value="item.value">{{ item.label }}</a-radio>
              </a-radio-group>
              <div v-if="leaderAwardBase" class="form-help">评定基准：{{ awardLabel(leaderAwardBase) }}，仅可选择当前档位或降档奖项。</div>
              <div v-else class="form-help">部门评议建议奖项尚未生成，暂不能确认负责人奖项。</div>
            </a-form-item>
          </template>

          <template v-if="isTask('Task_improve004')">
            <a-form-item label="负责人确认奖项">{{ awardLabel(proposal.leaderFinalAward) }}</a-form-item>
            <a-form-item label="所级评议人员" required>
              <a-checkbox-group v-model:value="selectedInstituteVoterIds" class="vote-member-grid">
                <a-checkbox v-for="member in instituteVoteCandidates" :key="member.id" :value="member.id" class="vote-member-option">
                  <span class="vote-member-name">{{ member.realname || member.username }}</span>
                  <span class="vote-member-username">{{ member.username }}</span>
                </a-checkbox>
              </a-checkbox-group>
              <div v-if="!instituteVoteCandidates.length" class="form-help">未查询到所级评议小组人员。</div>
              <div v-else class="form-help">请选择本次所级评议投票人员，提交办理后将生成对应投票待办。</div>
            </a-form-item>
          </template>

          <template v-if="isTask('Task_improve005')">
            <a-form-item label="我的投票">
              <a-space v-if="currentVote">
                <a-button :type="currentVote.voteResult === 'agree' ? 'primary' : 'default'" :loading="savingVote" @click="confirmInstituteVote('agree')">投票通过</a-button>
                <a-button danger :type="currentVote.voteResult === 'disagree' ? 'primary' : 'default'" :loading="savingVote" @click="confirmInstituteVote('disagree')">投票反对</a-button>
                <span>{{ voteResultLabel(currentVote) }}</span>
              </a-space>
              <span v-else class="form-help">当前用户不在所级评议投票名单中。</span>
            </a-form-item>
          </template>

          <template v-if="isTask('Task_improve006')">
            <a-form-item label="负责人确认奖项">{{ awardLabel(proposal.leaderFinalAward) }}</a-form-item>
            <a-form-item v-if="proposal.isneedvote === '1'" label="所级评议结果">
              同意票：{{ proposal.instituteAgreeCount ?? '-' }}；不同意票：{{ proposal.instituteDisagreeCount ?? '-' }}；结果：{{ proposal.instituteVoteResult || '-' }}
            </a-form-item>
            <a-form-item label="最终奖项" required>
              <a-radio-group v-model:value="finalAward">
                <a-radio v-for="item in awardOptions" :key="item.value" :value="item.value">{{ item.label }}</a-radio>
              </a-radio-group>
            </a-form-item>
          </template>
        </a-form>

        <!-- 所级投票以“投票即办理”完成，避免通用“同意/退回”与投票结果产生歧义。 -->
        <TaskHandleInnerContent
          v-if="!isTask('Task_improve005')"
          :form-data="formData"
          :claim="claim"
          :before-handle="saveNodeAction"
          @success="handleSuccess"
          @claimSuccess="handleClaimSuccess"
        />
      </template>

      <a-modal v-model:open="scoreModalVisible" title="部门评议打分" :footer="null" :mask-closable="false" :body-style="{ padding: '24px 28px 20px' }">
        <a-form layout="vertical">
          <a-alert class="score-range-alert" type="info" show-icon message="所有评分项均须填写 0-100 分，最多可保留两位小数。" />
          <a-row :gutter="12">
            <a-col :span="24">
              <a-form-item label="改善效果（权重 50%）" required>
                <a-row :gutter="12">
                  <a-col :xs="24" :sm="12" :lg="6">
                    <a-form-item label="安全" required><a-input-number v-model:value="scoreForm.safetyScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" /></a-form-item>
                  </a-col>
                  <a-col :xs="24" :sm="12" :lg="6">
                    <a-form-item label="质量" required><a-input-number v-model:value="scoreForm.qualityScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" /></a-form-item>
                  </a-col>
                  <a-col :xs="24" :sm="12" :lg="6">
                    <a-form-item label="效率" required><a-input-number v-model:value="scoreForm.efficiencyScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" /></a-form-item>
                  </a-col>
                  <a-col :xs="24" :sm="12" :lg="6">
                    <a-form-item label="成本" required><a-input-number v-model:value="scoreForm.costScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" /></a-form-item>
                  </a-col>
                </a-row>
                <div class="form-help">改善效果得分按安全、质量、效率、成本四项的平均分自动计算：{{ effectAveragePreview }}</div>
              </a-form-item>
            </a-col>
            <a-col :xs="24" :sm="12">
              <a-form-item label="可推广度（权重 20%）" required>
                <a-input-number v-model:value="scoreForm.promotionScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" />
              </a-form-item>
            </a-col>
            <a-col :xs="24" :sm="12">
              <a-form-item label="独创性（权重 20%）" required>
                <a-input-number v-model:value="scoreForm.originalityScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" />
              </a-form-item>
            </a-col>
            <a-col :xs="24" :sm="12">
              <a-form-item label="努力度（权重 10%）" required>
                <a-input-number v-model:value="scoreForm.effortScore" :min="0" :max="100" :precision="2" :disabled="scoreLocked" style="width: 100%" />
              </a-form-item>
            </a-col>
          </a-row>
          <a-form-item label="评分意见">
            <a-textarea v-model:value="scoreForm.scoreOpinion" :rows="3" :disabled="scoreLocked" />
          </a-form-item>
          <a-space>
            <a-button v-if="!scoreLocked" type="primary" :loading="savingScore" @click="saveScoreDraft">保存评分</a-button>
            <span v-else>评分已锁定，请重新提交流程办理</span>
          </a-space>
        </a-form>
      </a-modal>
    </section>
  </a-spin>
</template>

<script lang="ts" setup>
  import { computed, ref, watch } from 'vue';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useUserStore } from '/@/store/modules/user';
  import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
  import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
  import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
  import {
    queryDataById,
    queryInstituteVoteCandidates,
    queryImprovementInstituteVoteListByMainId,
    queryMyDeptScore,
    saveArchiveAward,
    saveDeptScore,
    saveInitialReview,
    saveInstituteVoteMembers,
    saveLeaderAward,
    submitInstituteVote,
    submitDeptScore,
  } from '../ImprovementProposal.api';

  const props = defineProps({
    formData: { type: Object, default: () => ({}) },
    formBpm: { type: Boolean, default: true },
    claim: { type: Boolean, default: false },
  });
  const emit = defineEmits(['success', 'claimSuccess']);
  const { createMessage, createConfirm } = useMessage();
  const userStore = useUserStore();
  const loading = ref(false);
  const savingScore = ref(false);
  const savingVote = ref(false);
  const scoreModalVisible = ref(false);
  const proposal = ref<Recordable>({});
  const currentScore = ref<Recordable | null>(null);
  const voteRows = ref<Recordable[]>([]);
  const instituteVoteCandidates = ref<Recordable[]>([]);
  const selectedInstituteVoterIds = ref<string[]>([]);
  const initialAward = ref('');
  const leaderFinalAward = ref('');
  const finalAward = ref('');
  const scoreForm = ref<Recordable>(createEmptyScoreForm());
  const labelCol = { xs: { span: 24 }, sm: { span: 5 } };
  const wrapperCol = { xs: { span: 24 }, sm: { span: 19 } };

  const awardOptions = [
    { value: '0', label: '金奖' },
    { value: '1', label: '银奖' },
    { value: '2', label: '铜奖' },
    { value: '3', label: '参与奖' },
  ];
  // 流程引擎在运行待办中提供 taskDefKey，节点功能只依赖该稳定标识而非表单 URL 参数。
  const processInfo = computed(() => ({
    mainId: props.formData?.processDataId || props.formData?.dataId,
    taskId: props.formData?.taskId,
    taskDefKey: props.formData?.taskDefKey,
    processInstanceId:
      props.formData?.procInsId ||
      props.formData?.procInstId ||
      props.formData?.processInstanceId ||
      props.formData?.vars?.BPM_INST_ID ||
      props.formData?.vars?.JG_LOCAL_PROCESS_ID ||
      props.formData?.vars?.processInstanceId,
  }));
  const showProcessHandle = computed(() => props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!processInfo.value.taskId);
  const currentUserId = computed(() => String(userStore.getUserInfo?.id || ''));
  const scoreLocked = computed(() => currentScore.value?.scoreStatus === 'completed');
  const scoreStatusLabel = computed(() => {
    if (!currentScore.value) return '未保存';
    return scoreLocked.value ? '评分已锁定' : '已保存，待流程提交';
  });
  const effectAveragePreview = computed(() => {
    const values = ['safetyScore', 'qualityScore', 'efficiencyScore', 'costScore'].map((key) => scoreForm.value[key]);
    if (values.some((value) => value === undefined || value === null)) return '-';
    return (values.reduce((sum, value) => sum + Number(value), 0) / values.length).toFixed(2);
  });
  // 部门评分完成后必须以系统建议奖项为基准，不能回退到初审奖项。
  const leaderAwardBase = computed(() => {
    const award = proposal.value.needDeptScore === '1' ? proposal.value.suggestedAward : proposal.value.initialAward;
    return awardOptions.some((item) => item.value === String(award)) ? String(award) : '';
  });
  const leaderAwardOptions = computed(() => {
    if (!leaderAwardBase.value) return [];
    return awardOptions.filter((item) => Number(item.value) >= Number(leaderAwardBase.value));
  });
  const currentVote = computed(() => voteRows.value.find((item) => String(item.voterId) === currentUserId.value));

  watch(
    () => [processInfo.value.mainId, processInfo.value.processInstanceId, processInfo.value.taskId, processInfo.value.taskDefKey],
    () => loadProposal(),
    { immediate: true }
  );

  async function loadProposal() {
    const mainId = processInfo.value.mainId;
    if (!mainId) {
      proposal.value = {};
      currentScore.value = null;
      voteRows.value = [];
      instituteVoteCandidates.value = [];
      selectedInstituteVoterIds.value = [];
      return;
    }
    loading.value = true;
    try {
      const [main, votes, myScore] = await Promise.all([
        queryDataById(mainId),
        queryImprovementInstituteVoteListByMainId(mainId),
        isTask('Task_improve002') && processInfo.value.processInstanceId && processInfo.value.taskId
          ? queryMyDeptScore(processInfo.value)
          : Promise.resolve(null),
      ]);
      proposal.value = main || {};
      currentScore.value = myScore || null;
      voteRows.value = votes || [];
      initialAward.value = proposal.value.initialAward || '';
      leaderFinalAward.value = proposal.value.leaderFinalAward || '';
      finalAward.value = proposal.value.finalAward || '';
      if (isTask('Task_improve004') && processInfo.value.processInstanceId && processInfo.value.taskId) {
        instituteVoteCandidates.value = await queryInstituteVoteCandidates(processInfo.value);
        const candidateIds = new Set(instituteVoteCandidates.value.map((item) => String(item.id)));
        // 流程提交失败后重新打开 Task4 时，回显本次尚未流转的有效名单。
        selectedInstituteVoterIds.value = voteRows.value
          .map((item) => String(item.voterId))
          .filter((voterId) => candidateIds.has(voterId));
      } else {
        instituteVoteCandidates.value = [];
        selectedInstituteVoterIds.value = [];
      }
    } catch (error) {
      createMessage.warning('提案数据加载失败');
    } finally {
      loading.value = false;
    }
  }

  function isTask(taskDefKey: string) {
    return processInfo.value.taskDefKey === taskDefKey;
  }

  function actionPayload(extra: Recordable = {}) {
    return { ...processInfo.value, ...extra };
  }

  async function saveNodeAction() {
    try {
      if (isTask('Task_improve001')) {
        if (!initialAward.value) {
          createMessage.warning('请选择初步评定奖项');
          return false;
        }
        await saveInitialReview(actionPayload({ initialAward: initialAward.value }));
      }
      if (isTask('Task_improve002')) {
        // 弹窗仅保存草稿；通用流程办理前才锁定评分，确保评委在此之前仍可修改。
        await submitDeptScore(actionPayload());
      }
      if (isTask('Task_improve003')) {
        if (!leaderAwardBase.value) {
          createMessage.warning('部门评议建议奖项尚未生成，不能确认负责人奖项');
          return false;
        }
        if (!leaderFinalAward.value) {
          createMessage.warning('请选择负责人确认奖项');
          return false;
        }
        if (!leaderAwardOptions.value.some((item) => item.value === leaderFinalAward.value)) {
          createMessage.warning('负责人确认奖项只能选择当前档位或降档奖项');
          return false;
        }
        await saveLeaderAward(actionPayload({ leaderFinalAward: leaderFinalAward.value }));
      }
      if (isTask('Task_improve004')) {
        if (!selectedInstituteVoterIds.value.length) {
          createMessage.warning('请至少选择一名所级评议人员');
          return false;
        }
        await saveInstituteVoteMembers(actionPayload({ voterIds: selectedInstituteVoterIds.value }));
      }
      if (isTask('Task_improve006')) {
        if (!finalAward.value) {
          createMessage.warning('请选择最终奖项');
          return false;
        }
        await saveArchiveAward(actionPayload({ finalAward: finalAward.value }));
      }
      return true;
    } catch (error: any) {
      createMessage.warning(error?.message || '流程办理数据保存失败');
      return false;
    }
  }

  function confirmInstituteVote(voteResult: 'agree' | 'disagree') {
    const voteLabel = voteResult === 'agree' ? '通过' : '反对';
    createConfirm({
      iconType: 'warning',
      title: '确认投票',
      content: `确认提交投票${voteLabel}吗？`,
      okText: '确认提交',
      cancelText: '取消',
      onOk: () => submitInstituteVoteAndComplete(voteResult),
    });
  }

  async function submitInstituteVoteAndComplete(voteResult: 'agree' | 'disagree') {
    savingVote.value = true;
    try {
      // 后端在锁定投票后复用通用流程办理服务完成当前 Task5 任务。
      await submitInstituteVote(actionPayload({ voteResult }));
      createMessage.success('投票提交成功');
      emit('success');
    } catch (error: any) {
      createMessage.warning(error?.message || '投票提交失败');
    } finally {
      savingVote.value = false;
    }
  }

  function openScoreModal() {
    const score = currentScore.value;
    scoreForm.value = {
      safetyScore: score?.safetyScore ?? undefined,
      qualityScore: score?.qualityScore ?? undefined,
      efficiencyScore: score?.efficiencyScore ?? undefined,
      costScore: score?.costScore ?? undefined,
      promotionScore: score?.promotionScore ?? undefined,
      originalityScore: score?.originalityScore ?? undefined,
      effortScore: score?.effortScore ?? undefined,
      scoreOpinion: score?.scoreOpinion || '',
    };
    scoreModalVisible.value = true;
  }

  async function saveScoreDraft() {
    if (!hasValidScoreValues()) {
      createMessage.warning('请完整填写 0 到 100 分之间的七项评分');
      return;
    }
    savingScore.value = true;
    try {
      await saveDeptScore(actionPayload(scoreForm.value));
      createMessage.success('评分保存成功，可在流程提交前继续修改');
      scoreModalVisible.value = false;
      await loadProposal();
    } catch (error: any) {
      createMessage.warning(error?.message || '评分保存失败');
    } finally {
      savingScore.value = false;
    }
  }

  function createEmptyScoreForm() {
    return {
      safetyScore: undefined,
      qualityScore: undefined,
      efficiencyScore: undefined,
      costScore: undefined,
      promotionScore: undefined,
      originalityScore: undefined,
      effortScore: undefined,
      scoreOpinion: '',
    };
  }

  function hasValidScoreValues() {
    return ['safetyScore', 'qualityScore', 'efficiencyScore', 'costScore', 'promotionScore', 'originalityScore', 'effortScore'].every((key) => {
      const value = scoreForm.value[key];
      return value !== undefined && value !== null && Number(value) >= 0 && Number(value) <= 100;
    });
  }

  function awardLabel(value: string) {
    return awardOptions.find((item) => item.value === String(value))?.label || '-';
  }

  function voteResultLabel(vote: Recordable) {
    if (vote.voteStatus !== 'voted') {
      return '待投票';
    }
    return vote.voteResult === 'agree' ? '已投同意票' : '已投不同意票';
  }

  function formatDate(value: string) {
    return value ? String(value).slice(0, 10) : '-';
  }

  function formatDateTime(value?: string) {
    return value ? String(value) : '-';
  }

  function handleSuccess() {
    emit('success');
  }

  function handleClaimSuccess() {
    emit('claimSuccess');
  }
</script>

<style lang="less" scoped>
  .improvement-proposal-bpm-form {
    padding: 8px 12px 16px;

    :deep(.ant-descriptions-item-content) {
      white-space: pre-wrap;
    }
  }

  .section-header {
    margin-bottom: 10px;
    padding: 7px 10px;
    border-left: 3px solid #1677ff;
    background: #f6fbff;
    color: #1f2937;
    font-weight: 600;
  }

  .attachment-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
  }

  .attachment-label {
    margin-bottom: 6px;
    color: #475569;
    font-weight: 500;
  }

  .process-form {
    margin-bottom: 12px;
  }

  .form-help {
    margin-top: 6px;
    color: #64748b;
    font-size: 12px;
  }

  .score-range-alert {
    margin-bottom: 16px;
  }

  .vote-member-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 10px 12px;
    width: 100%;
  }

  .vote-member-option {
    display: flex;
    align-items: center;
    min-height: 42px;
    margin-inline-start: 0;
    padding: 8px 10px;
    border: 1px solid #d9e2ec;
    border-radius: 4px;
    background: #fff;
  }

  .vote-member-name {
    margin-left: 6px;
    color: #1f2937;
    font-weight: 500;
  }

  .vote-member-username {
    margin-left: 6px;
    color: #64748b;
    font-size: 12px;
  }

  @media (max-width: 768px) {
    .attachment-grid {
      grid-template-columns: 1fr;
    }
  }
</style>
