<template>
  <div class="p-2" v-loading="pageLoading">
    <approvalButton
      class="mb-3"
      @submitForm="submitForm"
      @approvalVerifyOpen="approvalVerifyOpen"
      @handleApprovalRecord="handleApprovalRecord"
      :buttonLoading="buttonLoading"
      :id="form.tempTaskId as any"
      :status="form.flowStatus as any"
      :pageType="pageType"
      :mode="false"
    >
      <el-button v-if="canSubmitFinish" type="success" icon="CircleCheck" @click="handleSubmitFinish" v-hasPermi="['oa/erp:tempTask:submitFinish']">
        提交完成
      </el-button>
      <el-button v-if="canScoreClose" type="warning" icon="Star" @click="openScoreDialog" v-hasPermi="['oa/erp:tempTask:list']">
        评分关闭
      </el-button>
    </approvalButton>

    <el-card shadow="never" class="mb-3">
      <el-form ref="tempTaskFormRef" :model="form" :rules="rules" label-width="120px" :disabled="isFormReadOnly">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="任务编号" prop="tempTaskCode">
              <el-input v-model="form.tempTaskCode" placeholder="后端自动生成" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="业务状态" prop="taskStatus">
              <el-select v-model="form.taskStatus" disabled>
                <el-option v-for="dict in temp_task_status" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="累计工时" prop="totalHours">
              <el-input-number v-model="form.totalHours" :min="0" :precision="2" disabled controls-position="right" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="任务类型" prop="taskType">
              <el-select v-model="form.taskType" placeholder="请选择任务类型" clearable>
                <el-option v-for="dict in temp_task_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="16">
            <el-form-item label="任务标题" prop="taskTitle">
              <el-input v-model="form.taskTitle" placeholder="请输入任务标题" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="任务描述" prop="taskDesc">
              <el-input v-model="form.taskDesc" type="textarea" :rows="4" placeholder="请输入临时任务描述" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="计划开始" prop="planStartTime">
              <el-date-picker v-model="form.planStartTime" type="date" value-format="YYYY-MM-DD" clearable placeholder="请选择计划开始" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="计划完成" prop="planEndTime">
              <el-date-picker v-model="form.planEndTime" type="date" value-format="YYYY-MM-DD" clearable placeholder="请选择计划完成" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="预计工时" prop="estimateWorkload">
              <el-input-number v-model="form.estimateWorkload" :min="0" :step="0.5" :precision="1" controls-position="right" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.taskType === '3'">
            <el-form-item label="主报工项目" prop="projectCode">
              <el-input v-model="form.projectCode" placeholder="请选择项目" readonly>
                <template #suffix>
                  <el-icon class="cursor-pointer" @click="openProjectSelect"><Search /></el-icon>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.taskType === '3'">
            <el-form-item label="项目名称" prop="projectName">
              <el-input v-model="form.projectName" disabled placeholder="选择项目后自动填充" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.taskType === '1'">
            <el-form-item label="归集部门" prop="deptId">
              <el-select v-model="form.deptId" placeholder="请选择归集部门" clearable filterable @change="handleTaskDeptChange">
                <el-option v-for="dept in deptList" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="form.taskType === '1'">
            <el-form-item label="归集部门名称" prop="deptName">
              <el-input v-model="form.deptName" disabled placeholder="选择部门后自动填充" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="发起人" prop="requesterName">
              <el-input v-model="form.requesterName" disabled placeholder="后端按当前用户回填" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="实际需求人" prop="realRequesterName">
              <el-input v-model="form.realRequesterName" readonly placeholder="默认可为空，代发起时选择">
                <template #suffix>
                  <el-icon class="cursor-pointer" @click="openUserSelect('realRequester')"><Search /></el-icon>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="实际需求部门" prop="realRequestDeptId">
              <el-select v-model="form.realRequestDeptId" placeholder="请选择实际需求部门" clearable filterable @change="handleRealDeptChange">
                <el-option v-for="dept in deptList" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="软件部领导" prop="softwareLeaderName">
              <el-input v-model="form.softwareLeaderName" readonly placeholder="请选择软件部领导">
                <template #suffix>
                  <el-icon class="cursor-pointer" @click="openUserSelect('leader')"><Search /></el-icon>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="主执行人" prop="assigneeName">
              <el-input v-model="form.assigneeName" readonly placeholder="请选择主执行人">
                <template #suffix>
                  <el-icon class="cursor-pointer" @click="openUserSelect('assignee')"><Search /></el-icon>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <!-- Why actualStartTime 始终 disabled：由后端流程引擎在 leader_review 通过后自动落库，前端不可手动编辑 -->
          <el-col :span="8">
            <el-form-item label="实际开始" prop="actualStartTime">
              <el-date-picker v-model="form.actualStartTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" disabled placeholder="流程自动记录" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="备注" prop="remark">
              <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </el-card>

    <el-row v-if="form.tempTaskId" :gutter="12">
      <el-col :span="8">
        <el-card shadow="never" class="mb-3">
          <template #header>
            <div class="flex justify-between items-center">
              <span>参与人</span>
              <el-button
                v-if="canManageMembers"
                type="primary"
                plain
                icon="Plus"
                size="small"
                @click="openMemberDialog"
                v-hasPermi="['oa/erp:tempTask:list']"
              >
                协作人
              </el-button>
            </div>
          </template>
          <el-table :data="memberList" border>
            <el-table-column label="类型" prop="memberType" width="100" align="center">
              <template #default="scope">
                <dict-tag :options="temp_task_member_type" :value="scope.row.memberType" />
              </template>
            </el-table-column>
            <el-table-column label="姓名" prop="userName" min-width="100" align="center" />
            <el-table-column label="协作说明" prop="joinRemark" min-width="150" show-overflow-tooltip align="center" />
            <el-table-column v-if="canManageMembers" label="操作" width="80" align="center">
              <template #default="scope">
                <el-button v-if="scope.row.memberType === '2'" link type="danger" @click="handleRemoveMember(scope.row.memberId)">移除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>

      <el-col :span="16">
        <el-card shadow="never" class="mb-3">
          <template #header>
            <div class="flex justify-between items-center">
              <span>工时明细</span>
              <el-button
                v-if="canEditWorklog"
                type="primary"
                plain
                icon="Plus"
                size="small"
                @click="openWorklogDialog()"
                v-hasPermi="['oa/erp:tempTask:list']"
              >
                填报工时
              </el-button>
            </div>
          </template>
          <el-table :data="worklogList" border>
            <el-table-column label="填报人" prop="userName" width="100" align="center" />
            <el-table-column label="工作日期" prop="workDate" width="120" align="center">
              <template #default="scope">{{ parseDate(scope.row.workDate) }}</template>
            </el-table-column>
            <el-table-column label="自然周" min-width="190" align="center">
              <template #default="scope">{{ parseDate(scope.row.weekStart) }} ~ {{ parseDate(scope.row.weekEnd) }}</template>
            </el-table-column>
            <el-table-column label="工时" prop="hours" width="80" align="center" />
            <el-table-column label="事项描述" prop="workContent" min-width="180" show-overflow-tooltip align="center" />
            <el-table-column label="附件" min-width="160" align="center">
              <template #default="scope">
                <OssFilePreview v-if="scope.row.ossId" :oss-ids="scope.row.ossId" thumb-size="40px" />
                <span v-else>暂无附件</span>
              </template>
            </el-table-column>
            <el-table-column label="状态" prop="lockFlag" width="90" align="center">
              <template #default="scope">
                <el-tag :type="scope.row.lockFlag === '1' ? 'info' : 'success'">{{ scope.row.lockFlag === '1' ? '已锁定' : '可编辑' }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column v-if="canEditWorklog" label="操作" width="110" align="center">
              <template #default="scope">
                <el-button v-if="scope.row.lockFlag !== '1'" link type="primary" @click="openWorklogDialog(scope.row)">编辑</el-button>
                <el-button v-if="scope.row.lockFlag !== '1'" link type="danger" @click="handleDeleteWorklog(scope.row.worklogId)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <el-card v-if="form.tempTaskId" shadow="never">
      <template #header>
        <div class="flex justify-between items-center">
          <span>评分结果</span>
          <el-button
            v-if="canScoreClose"
            type="warning"
            plain
            icon="Star"
            size="small"
            @click="openScoreDialog"
            v-hasPermi="['oa/erp:tempTask:list']"
          >
            评分关闭
          </el-button>
        </div>
      </template>
      <el-table :data="scoreList" border>
        <el-table-column label="被评分人" prop="userName" width="120" align="center" />
        <el-table-column label="评分等级" prop="scoreGrade" width="140" align="center">
          <template #default="scope">
            <dict-tag :options="temp_task_score" :value="scope.row.scoreGrade" />
          </template>
        </el-table-column>
        <el-table-column label="评分说明" prop="scoreRemark" min-width="220" show-overflow-tooltip align="center" />
        <el-table-column label="评分时间" prop="scoreTime" width="160" align="center">
          <template #default="scope">{{ parseDateTime(scope.row.scoreTime) }}</template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-dialog v-model="memberDialog.visible" title="新增协作人" width="620px" append-to-body>
      <el-form ref="memberFormRef" :model="memberForm" :rules="memberRules" label-width="120px">
        <el-form-item label="协作人" prop="userName">
          <el-input v-model="memberForm.userName" readonly placeholder="请选择协作人">
            <template #suffix>
              <el-icon class="cursor-pointer" @click="openUserSelect('member')"><Search /></el-icon>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="协作说明" prop="joinRemark">
          <el-input v-model="memberForm.joinRemark" type="textarea" :rows="3" placeholder="请输入协作事项说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="memberDialog.visible = false">取消</el-button>
        <el-button type="primary" :loading="buttonLoading" @click="handleAddMember">确定</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="worklogDialog.visible" title="工时明细" width="720px" append-to-body>
      <el-form ref="worklogFormRef" :model="worklogForm" :rules="worklogRules" label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="工作日期" prop="workDate">
              <el-date-picker v-model="worklogForm.workDate" type="date" value-format="YYYY-MM-DD" clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="工时" prop="hours">
              <el-input-number v-model="worklogForm.hours" :min="0.5" :step="0.5" :precision="1" controls-position="right" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="事项描述" prop="workContent">
              <el-input v-model="worklogForm.workContent" type="textarea" :rows="4" placeholder="请输入本次工作内容" />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="附件" prop="ossId">
              <FileUpload
                v-model="worklogOssIdString"
                :limit="5"
                :file-size="20"
                :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'pdf', 'xls', 'xlsx', 'txt']"
                :is-show-tip="true"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="worklogDialog.visible = false">取消</el-button>
        <el-button type="primary" :loading="buttonLoading" @click="handleSaveWorklog">保存</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="scoreDialog.visible" title="领导评分关闭" width="820px" append-to-body>
      <el-form ref="scoreFormRef" :model="scoreForm" label-width="120px">
        <el-table :data="scoreForm.scoreList" border>
          <el-table-column label="人员" min-width="140" align="center">
            <template #default="scope">
              {{ memberNameMap[scope.row.memberId] || scope.row.userId }}
            </template>
          </el-table-column>
          <el-table-column label="评分等级" width="180" align="center">
            <template #default="scope">
              <el-select v-model="scope.row.scoreGrade" placeholder="请选择评分">
                <el-option v-for="dict in temp_task_score" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="评分说明" min-width="240" align="center">
            <template #default="scope">
              <el-input v-model="scope.row.scoreRemark" placeholder="请输入评分说明" />
            </template>
          </el-table-column>
        </el-table>
        <el-form-item class="mt-3" label="最终审核意见">
          <el-input v-model="scoreForm.leaderFinalOpinion" type="textarea" :rows="3" placeholder="请输入最终审核意见" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="scoreDialog.visible = false">取消</el-button>
        <el-button type="primary" :loading="buttonLoading" @click="handleScoreAndClose">评分关闭</el-button>
      </template>
    </el-dialog>

    <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
    <approvalRecord ref="approvalRecordRef" />
    <ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="handleProjectSelect" />
    <UserSelect ref="userSelectRef" :multiple="userSelectMode === 'cc'" @confirm-call-back="handleUserSelect" />
  </div>
</template>

<script setup name="TempTaskEdit" lang="ts">
import {
  addTempTask,
  addTempTaskMember,
  assigneeReviewTempTask,
  delTempTaskMember,
  delTempTaskWorklog,
  getTempTask,
  leaderReviewAndCompleteTempTask,
  listTempTaskMember,
  listTempTaskScore,
  listTempTaskWorklog,
  saveTempTaskWorklog,
  scoreAndCloseTempTask,
  submitFinishTempTask,
  tempTaskSubmitAndFlowStart,
  updateTempTask,
  syncTaskState
} from '@/api/oa/erp/tempTask';
import type {
  TempTaskForm,
  TempTaskMemberForm,
  TempTaskMemberVO,
  TempTaskScoreSubmitForm,
  TempTaskScoreVO,
  TempTaskWorklogForm,
  TempTaskWorklogVO
} from '@/api/oa/erp/tempTask/types';
import type { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
import type { DeptVO } from '@/api/system/dept/types';
import { allListDept } from '@/api/system/dept';
import { getTask } from '@/api/workflow/task';
import { FlowCodeEnum } from '@/enums/OAEnum';
import ApprovalButton from '@/components/Process/approvalButton.vue';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ProjectSelect from '@/components/ProjectSelect/index.vue';
import UserSelect from '@/components/UserSelect/index.vue';
import FileUpload from '@/components/FileUpload/index.vue';
import OssFilePreview from '@/components/OssFilePreview/index.vue';

type UserSelectMode = 'leader' | 'assignee' | 'realRequester' | 'member' | 'cc';

const { proxy } = getCurrentInstance() as any;
const route = useRoute();
const router = useRouter();

const { temp_task_type, temp_task_status, temp_task_member_type, temp_task_score } = toRefs<any>(
  proxy?.useDict('temp_task_type', 'temp_task_status', 'temp_task_member_type', 'temp_task_score')
);

const pageLoading = ref(false);
const buttonLoading = ref(false);
const pageType = ref<string>((route.query.type as string) || 'add');
const tempTaskFormRef = ref<ElFormInstance>();
const memberFormRef = ref<ElFormInstance>();
const worklogFormRef = ref<ElFormInstance>();
const scoreFormRef = ref<ElFormInstance>();
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
const userSelectRef = ref<InstanceType<typeof UserSelect>>();

const userSelectMode = ref<UserSelectMode>('leader');
const taskVariables = ref<Record<string, unknown>>({});
const currentNodeCode = ref<string>('');
const deptList = ref<DeptVO[]>([]);
const memberList = ref<TempTaskMemberVO[]>([]);
const worklogList = ref<TempTaskWorklogVO[]>([]);
const scoreList = ref<TempTaskScoreVO[]>([]);

const initFormData: TempTaskForm = {
  tempTaskId: undefined,
  taskId: undefined,
  tempTaskCode: undefined,
  taskTitle: undefined,
  taskDesc: undefined,
  taskType: '1',
  planStartTime: undefined,
  planEndTime: undefined,
  actualStartTime: undefined,
  actualFinishTime: undefined,
  projectId: undefined,
  projectCode: undefined,
  projectName: undefined,
  deptId: undefined,
  deptName: undefined,
  requesterId: undefined,
  requesterName: undefined,
  realRequesterId: undefined,
  realRequesterName: undefined,
  realRequestDeptId: undefined,
  realRequestDeptName: undefined,
  softwareLeaderId: undefined,
  softwareLeaderName: undefined,
  assigneeId: undefined,
  assigneeName: undefined,
  estimateWorkload: undefined,
  totalHours: undefined,
  taskStatus: '1',
  flowStatus: 'draft',
  ccUserIds: undefined,
  remark: undefined,
  flowCode: FlowCodeEnum.TEMP_TASK_CODE,
  variables: {},
  bizExt: {}
};

const form = ref<TempTaskForm>({ ...initFormData });

const rules: ElFormRules = {
  taskDesc: [{ required: true, message: '任务描述不能为空', trigger: 'blur' }],
  taskType: [{ required: true, message: '任务类型不能为空', trigger: 'change' }],
  softwareLeaderName: [{ required: true, message: '软件部领导不能为空', trigger: 'change' }],
  projectCode: [
    {
      validator: (_rule, value, callback) => {
        if (form.value.taskType === '3' && !value) {
          callback(new Error('项目任务必须选择项目'));
        } else {
          callback();
        }
      },
      trigger: 'change'
    }
  ],
  deptId: [
    {
      validator: (_rule, value, callback) => {
        if (form.value.taskType === '1' && !value) {
          callback(new Error('部门任务必须选择归集部门'));
        } else {
          callback();
        }
      },
      trigger: 'change'
    }
  ]
};

const memberDialog = reactive({ visible: false });
const memberForm = ref<TempTaskMemberForm>({});
const memberRules: ElFormRules = {
  userName: [{ required: true, message: '协作人不能为空', trigger: 'change' }]
};

const worklogDialog = reactive({ visible: false });
const worklogForm = ref<TempTaskWorklogForm>({});
const worklogRules: ElFormRules = {
  workDate: [{ required: true, message: '工作日期不能为空', trigger: 'change' }],
  hours: [{ required: true, message: '工时不能为空', trigger: 'blur' }],
  workContent: [{ required: true, message: '事项描述不能为空', trigger: 'blur' }]
};

const scoreDialog = reactive({ visible: false });
const scoreForm = ref<TempTaskScoreSubmitForm>({
  tempTaskId: '',
  taskId: '',
  leaderFinalOpinion: undefined,
  scoreList: []
});

/**
 * 表单是否只读。
 *
 * 规则：
 * - 查看模式(pageType=view)  -> 全部只读
 * - 审批模式(pageType=approval) + 当前节点不是 leader_review/assignee_review -> 只读
 * - 审批模式 + 当前节点是 leader_review  -> 可编辑（领导审批时可修改主执行人、软件部领导等字段）
 * - 审批模式 + 当前节点是 assignee_review -> 可编辑（主执行人审阅时可修改标题/描述/计划周期/预估工时）
 *
 * 为什么 leader_review 和 assignee_review 在审批模式也可编辑：
 * 这两个节点的业务语义是"审批者可以修正业务数据"，而非纯粹的"只读审批"。
 * 审批即修改，所以表单在这些节点保持可编辑状态。
 */
// Why：type=execute 模式主表只读，参与人/工时明细单独控制；
//       leader_review/assignee_review 节点审批人可修正业务数据；
//       execute 工作流节点同样保持可编辑。
const isFormReadOnly = computed(
  () => pageType.value === 'view'
    || pageType.value === 'execute'
    || (pageType.value === 'approval' && !['leader_review', 'assignee_review', 'execute'].includes(currentNodeCode.value))
);
/**
 * 是否允许管理协作人（新增/移除）。
 * type=execute 模式 + 执行中(taskStatus=3) 时可操作。
 */
const canManageMembers = computed(() => !!form.value.tempTaskId && pageType.value !== 'view' && form.value.taskStatus === '3');
/**
 * 是否允许编辑工时明细（填报/修改/删除）。
 * 规则同上。
 */
const canEditWorklog = computed(() => !!form.value.tempTaskId && pageType.value !== 'view' && form.value.taskStatus === '3');
/**
 * 是否允许"提交完成"按钮显示。
 *
 * 需要同时满足五个条件：
 * 1. tempTaskId 存在（任务已保存，非新增草稿）
 * 2. route.query.taskId 存在（从工作流待办进入，非直接编辑进入）
 *    -- 这是为了保证 taskId 存在，提交完成后端需要它来 completeTask
 * 3. 非查看模式
 * 4. taskStatus === '3'（执行中）
 * 5. currentNodeCode === 'execute'（当前流程节点是执行节点）
 *    -- 只有主执行人在 execute 节点时才能提交完成，防止其他角色误操作
 */
const canSubmitFinish = computed(
  () =>
    !!form.value.tempTaskId &&
    !!route.query.taskId &&
    pageType.value !== 'view' &&
    form.value.taskStatus === '3' &&
    currentNodeCode.value === 'execute'
);
/**
 * 是否允许"评分关闭"按钮显示。
 *
 * 需要同时满足五个条件：
 * 1. tempTaskId 存在（任务已保存）
 * 2. route.query.taskId 存在（从工作流待办进入）
 * 3. 非查看模式
 * 4. taskStatus === '4'（待领导审核 -- 主执行人已提交完成，等待领导评分）
 * 5. currentNodeCode === 'leader_final'（当前流程节点是领导终审节点）
 *    -- 只有领导在 leader_final 节点时才能评分关闭，评分即关闭，不可逆
 */
const canScoreClose = computed(
  () =>
    !!form.value.tempTaskId &&
    !!route.query.taskId &&
    pageType.value !== 'view' &&
    // Why：执行人可能绕过 submitFinish 直接用工作流审批按钮推进到 leader_final，
    //      此时 taskStatus 仍为 3，但评分人已到 leader_final 节点，仍需允许评分关闭。
    (form.value.taskStatus === '3' || form.value.taskStatus === '4') &&
    currentNodeCode.value === 'leader_final'
);

const memberNameMap = computed<Record<string, string>>(() => {
  const map: Record<string, string> = {};
  memberList.value.forEach((member) => {
    map[String(member.memberId)] = member.userName || '';
  });
  return map;
});

const worklogOssIdString = computed({
  get() {
    return worklogForm.value.ossId ? String(worklogForm.value.ossId) : '';
  },
  set(val: string) {
    worklogForm.value.ossId = val || undefined;
  }
});

const parseDate = (value?: string) => {
  return value ? String(value).slice(0, 10) : '';
};

const parseDateTime = (value?: string) => {
  return value ? String(value).replace('T', ' ').slice(0, 16) : '';
};

const getDeptList = async () => {
  const res = await allListDept({ status: 0 } as any);
  deptList.value = res.data || [];
};

const findDept = (deptId?: string | number) => {
  return deptList.value.find((dept) => dept.deptId === deptId);
};

const handleTaskDeptChange = (deptId?: string | number) => {
  form.value.deptName = findDept(deptId)?.deptName;
};

const handleRealDeptChange = (deptId?: string | number) => {
  form.value.realRequestDeptName = findDept(deptId)?.deptName;
};

/**
 * 监听 taskType 切换，联动清除不适用的表单字段。
 * - 切换到非项目类型(taskType !== '3')：清除项目相关字段，避免脏数据带入提交
 * - 切换到非部门类型(taskType !== '1')：清除部门相关字段
 * 此逻辑确保表单提交时不会携带与当前任务类型无关的字段值。
 */
watch(
  () => form.value.taskType,
  (taskType) => {
    if (taskType !== '3') {
      form.value.projectId = undefined;
      form.value.projectCode = undefined;
      form.value.projectName = undefined;
    }
    if (taskType !== '1') {
      form.value.deptId = undefined;
      form.value.deptName = undefined;
    }
  }
);

const openProjectSelect = () => {
  if (isFormReadOnly.value) {
    return;
  }
  projectSelectRef.value?.open();
};

const handleProjectSelect = (data: ProjectInfoVO[]) => {
  const project = data?.[0];
  if (!project) {
    return;
  }
  form.value.projectId = project.projectId;
  form.value.projectCode = project.projectCode;
  form.value.projectName = project.projectName;
};

const openUserSelect = (mode: UserSelectMode) => {
  if (isFormReadOnly.value && mode !== 'member') {
    return;
  }
  userSelectMode.value = mode;
  userSelectRef.value?.open();
};

const handleUserSelect = (users: Array<Record<string, any>>) => {
  const selected = users?.[0];
  if (!selected) {
    return;
  }
  const userId = selected.userId;
  const name = selected.nickName || selected.userName;
  if (userSelectMode.value === 'leader') {
    form.value.softwareLeaderId = userId;
    form.value.softwareLeaderName = name;
  } else if (userSelectMode.value === 'assignee') {
    form.value.assigneeId = userId;
    form.value.assigneeName = name;
  } else if (userSelectMode.value === 'realRequester') {
    form.value.realRequesterId = userId;
    form.value.realRequesterName = name;
    if (selected.deptId) {
      form.value.realRequestDeptId = selected.deptId;
      form.value.realRequestDeptName = selected.deptName;
    }
  } else if (userSelectMode.value === 'member') {
    memberForm.value.userId = userId;
    memberForm.value.userName = name;
    memberForm.value.memberDeptId = selected.deptId;
  } else {
    form.value.ccUserIds = users.map((item) => item.userId).join(',');
  }
};

/**
 * 从专用子表端点加载参与人/工时/评分列表（AD-13/AD-16）。
 *
 * 这些子表通过独立 API 端点查询，而非依赖主表 queryById 的嵌套返回。
 * 为什么不用 loadDetail 中的嵌套数据而要再调一次：
 * 主表 queryById 可能出于性能考虑不返回完整子表数据（不包含 members/worklogs/scores），
 * 或者列表页查询不携带子表，只有编辑页才加载。loadSubLists 保证子表数据是最新状态。
 */
const loadSubLists = async () => {
  if (!form.value.tempTaskId) {
    memberList.value = [];
    worklogList.value = [];
    scoreList.value = [];
    return;
  }
  const tempTaskId = form.value.tempTaskId;
  const [memberRes, worklogRes, scoreRes] = await Promise.all([
    listTempTaskMember(tempTaskId),
    listTempTaskWorklog(tempTaskId),
    listTempTaskScore(tempTaskId)
  ]);
  memberList.value = memberRes.data || [];
  worklogList.value = worklogRes.data || [];
  scoreList.value = scoreRes.data || [];
};

/**
 * 加载任务详情。
 *
 * 数据来源：
 * - 主表字段（form）：来自 getTempTask(queryById)，包含业务字段快照
 * - 子表字段（members/worklogs/scores）：先用 queryById 返回的嵌套数据做快速渲染，
 *   然后调用 loadSubLists() 从专用端点拉取最新数据覆盖
 *
 * 为什么需要两步加载：
 * queryById 可能返回子表的旧版本数据（如列表页用的同一个 VO），
 * loadSubLists 从独立端点获取确保数据是最新的。
 */
const loadDetail = async (id: string | number) => {
  const res = await getTempTask(id);
  form.value = {
    ...initFormData,
    ...res.data,
    flowCode: FlowCodeEnum.TEMP_TASK_CODE
  };
  // 先用嵌套数据快速渲染，避免空白闪烁
  memberList.value = res.data?.members || [];
  worklogList.value = res.data?.worklogs || [];
  scoreList.value = res.data?.scores || [];
  // 再从专用端点拉取最新子表数据覆盖
  await loadSubLists();
};

const loadCurrentWorkflowTask = async () => {
  const taskId = route.query.taskId as string | undefined;
  if (!taskId) {
    currentNodeCode.value = '';
    return;
  }
  const res = await getTask(taskId);
  currentNodeCode.value = res.data?.nodeCode || '';
};

/**
 * 组装工作流 variables 和 bizExt 载荷。
 *
 * variables 的来源：
 * - has_assignee: 控制流程网关分支 -- 有主执行人时跳过 assignee_confirm 节点，直接进入执行
 * - reassigned: 保留后端可能写入的换人标记，用于下一次提交时维持流程变量
 * - 其余字段：从 form 中提取业务关键字段，用于 Warm-Flow 条件表达式(SpEL)计算路由/办理人
 *
 * null/undefined/空字符串清理：
 * Warm-Flow 的 SpEL 表达式对 null 和空字符串处理不同，为保持一致性，
 * 前端在提交前删除所有空值变量，让后端按默认逻辑处理缺失字段。
 *
 * bizExt 用于审批中心/待办列表渲染，截断到 80 字符防止展示溢出。
 */
const buildVariables = () => {
  taskVariables.value = {
    has_assignee: form.value.assigneeId ? '1' : '0',
    // 保留后端可能写入的 reassigned 标记，避免下拉框变更后丢失换人状态
    reassigned: (form.value.variables as Record<string, unknown>)?.reassigned || '0',
    requesterId: form.value.requesterId,
    realRequesterId: form.value.realRequesterId,
    realRequestDeptId: form.value.realRequestDeptId,
    softwareLeaderId: form.value.softwareLeaderId,
    assigneeId: form.value.assigneeId,
    ccUserIds: form.value.ccUserIds,
    taskTitle: form.value.taskTitle,
    taskDesc: form.value.taskDesc,
    taskType: form.value.taskType,
    projectId: form.value.projectId,
    deptId: form.value.deptId,
    planStartTime: form.value.planStartTime,
    planEndTime: form.value.planEndTime,
    estimateWorkload: form.value.estimateWorkload,
    actualStartTime: form.value.actualStartTime,
    assigneeOpinion: form.value.assigneeOpinion,
    leaderOpinion: form.value.leaderOpinion,
    leaderFinalOpinion: scoreForm.value.leaderFinalOpinion
  };
  // 清理空值：Warm-Flow 的 SpEL 表达式对 null/空串/undefined 处理行为不一致，
  // 删除全部空值变量让后端按缺失字段的默认逻辑处理，避免条件分支误判
  Object.keys(taskVariables.value).forEach((key) => {
    if (taskVariables.value[key] === undefined || taskVariables.value[key] === null || taskVariables.value[key] === '') {
      delete taskVariables.value[key];
    }
  });
  form.value.variables = { ...taskVariables.value };
  // 组装 bizExt：用于审批中心/待办列表展示业务信息
  const businessTitle = `${form.value.tempTaskCode || '临时任务'}-${form.value.taskDesc || form.value.taskTitle || ''}`;
  form.value.bizExt = {
    businessId: form.value.tempTaskId,
    businessCode: form.value.tempTaskCode,
    businessTitle: businessTitle.slice(0, 80) // 截断防止审批中心展示溢出
  };
};

const validateMainForm = async () => {
  if (!tempTaskFormRef.value) {
    return true;
  }
  return await tempTaskFormRef.value.validate().catch(() => false);
};

const submitForm = async (status: string) => {
  const valid = await validateMainForm();
  if (!valid) {
    return;
  }
  buttonLoading.value = true;
  try {
    buildVariables();
    if (status !== 'draft') {
      const res = await tempTaskSubmitAndFlowStart(form.value);
      form.value = { ...initFormData, ...res.data, flowCode: FlowCodeEnum.TEMP_TASK_CODE };
      proxy?.$modal.msgSuccess('操作成功');
    } else {
      form.value.taskStatus = '1';
      form.value.flowStatus = 'draft';
      if (form.value.tempTaskId) {
        await updateTempTask(form.value);
      } else {
        await addTempTask(form.value);
      }
      proxy?.$modal.msgSuccess('暂存成功');
    }
    proxy?.$tab.closePage(route);
    router.go(-1);
  } finally {
    buttonLoading.value = false;
  }
};

const openMemberDialog = () => {
  memberForm.value = {
    tempTaskId: form.value.tempTaskId,
    memberType: '2'
  };
  memberDialog.visible = true;
};

const handleAddMember = async () => {
  const valid = await memberFormRef.value?.validate().catch(() => false);
  if (!valid) {
    return;
  }
  buttonLoading.value = true;
  try {
    await addTempTaskMember(memberForm.value);
    proxy?.$modal.msgSuccess('协作人已添加');
    memberDialog.visible = false;
    await loadSubLists();
  } finally {
    buttonLoading.value = false;
  }
};

const handleRemoveMember = async (memberId: string | number) => {
  await proxy?.$modal.confirm('确认移除该协作人？');
  await delTempTaskMember(memberId);
  proxy?.$modal.msgSuccess('移除成功');
  await loadSubLists();
};

const openWorklogDialog = (row?: TempTaskWorklogVO) => {
  worklogForm.value = row
    ? { ...row }
    : {
        tempTaskId: form.value.tempTaskId,
        workDate: undefined,
        hours: 0.5,
        workContent: undefined,
        ossId: undefined
      };
  worklogDialog.visible = true;
};

const handleSaveWorklog = async () => {
  const valid = await worklogFormRef.value?.validate().catch(() => false);
  if (!valid) {
    return;
  }
  buttonLoading.value = true;
  try {
    await saveTempTaskWorklog(worklogForm.value);
    proxy?.$modal.msgSuccess('工时明细已保存');
    worklogDialog.visible = false;
    await loadSubLists();
  } finally {
    buttonLoading.value = false;
  }
};

const handleDeleteWorklog = async (worklogId: string | number) => {
  await proxy?.$modal.confirm('确认删除该工时明细？');
  await delTempTaskWorklog(worklogId);
  proxy?.$modal.msgSuccess('删除成功');
  await loadSubLists();
};

/**
 * 主执行人提交完成。
 *
 * 前置校验：
 * 1. tempTaskId 和 taskId 必须存在（从工作流待办进入才有 taskId）
 * 2. 当前流程节点必须是 execute（防止在非执行节点误操作）
 *
 * 提交后行为：
 * - 后端锁定全部工时明细(lockFlag=1)
 * - 累计汇总 totalHours
 * - 业务状态从 3(执行中) 扭转为 4(待领导审核)
 * - 流程从 execute 流转到 leader_final
 * - 关闭当前页返回列表
 */
const handleSubmitFinish = async () => {
  const taskId = route.query.taskId as string | undefined;
  if (!form.value.tempTaskId || !taskId) {
    proxy?.$modal.msgWarning('请从执行待办进入后提交完成');
    return;
  }
  // 双保险：再次获取最新节点状态，防止 stale closure
  if (!currentNodeCode.value) {
    await loadCurrentWorkflowTask();
  }
  if (currentNodeCode.value !== 'execute') {
    proxy?.$modal.msgWarning('当前流程节点不是执行节点，不能提交完成');
    return;
  }
  await proxy?.$modal.confirm('确认提交完成并锁定全部工时明细？');
  buttonLoading.value = true;
  try {
    await submitFinishTempTask({
      tempTaskId: form.value.tempTaskId,
      taskId
    });
    proxy?.$modal.msgSuccess('提交完成成功');
    proxy?.$tab.closePage(route);
    router.go(-1);
  } finally {
    buttonLoading.value = false;
  }
};

/**
 * 打开评分关闭对话框。
 *
 * 预填充逻辑（复用已有评分）：
 * - 遍历所有参与人(memberList)，为每个参与人创建一条评分表单
 * - 如果后端已有评分数据（例如领导之前打开过评分弹窗但未提交），
 *   则用已有评分预填充 scoreGrade 和 scoreRemark，
 *   方便领导再次打开时不丢失之前填写的评分内容
 * - 为什么需要这个预填充：评分关闭是一次性操作，但领导可能多次打开弹窗查看/调整，
 *   已有的评分数据不应在重新打开时丢失
 */
const openScoreDialog = () => {
  const taskId = route.query.taskId as string | undefined;
  if (!form.value.tempTaskId || !taskId) {
    return;
  }
  scoreForm.value = {
    tempTaskId: form.value.tempTaskId,
    taskId,
    leaderFinalOpinion: undefined,
    scoreList: memberList.value.map((member) => {
      const oldScore = scoreList.value.find((score) => String(score.memberId) === String(member.memberId));
      return {
        memberId: member.memberId,
        userId: member.userId,
        // 复用已有评分作为预填充值，防止重新打开弹窗时评分数据丢失
        scoreGrade: oldScore?.scoreGrade || '',
        scoreRemark: oldScore?.scoreRemark
      };
    })
  };
  scoreDialog.visible = true;
};

/**
 * 领导评分关闭提交。
 *
 * 校验：所有参与人的评分等级必须填写，不能有遗漏。
 * 提交后行为：
 * - 后端逐人写评分 + 落库 actualFinishTime + 关闭任务(taskStatus=5)
 * - 完成 leader_final 工作流节点
 * - 关闭页面返回列表
 */
const handleScoreAndClose = async () => {
  // 确保所有参与人的评分等级都已选择，防止部分人员漏评
  if (scoreForm.value.scoreList.some((item) => !item.scoreGrade)) {
    proxy?.$modal.msgWarning('请为全部参与人选择评分等级');
    return;
  }
  buttonLoading.value = true;
  try {
    await scoreAndCloseTempTask(scoreForm.value);
    proxy?.$modal.msgSuccess('评分关闭成功');
    scoreDialog.visible = false;
    proxy?.$tab.closePage(route);
    router.go(-1);
  } finally {
    buttonLoading.value = false;
  }
};

/**
 * 审批按钮回调，根据当前工作流节点做三路分发。
 *
 * 分支逻辑：
 * 1. leader_review（领导审批节点）：
 *    - 先校验主表单
 *    - 调用 leaderReviewAndCompleteTempTask 原子完成落库+流转
 *    - 直接关闭页面返回列表（无需弹出 submitVerify，因为后端已完成 completeTask）
 *
 * 2. assignee_review（主执行人审阅节点）：
 *    - 调用 assigneeReviewTempTask 回写审阅可改字段
 *    - 重新 buildVariables() 装配最新的流程变量
 *    - 弹出 submitVerify 对话框，由用户确认后调用 workflow completeTask 流转
 *
 * 3. 其他节点（新增/修改提交、驳回重提等）：
 *    - 直接 buildVariables() 装配流程变量
 *    - 弹出 submitVerify 对话框，走标准提交流程
 *
 * 为什么 leader_review 不弹出 submitVerify：
 * leaderReviewAndCompleteTempTask 已经在后端原子完成了 completeTask，
 * 如果前端再调 completeTask 会导致重复流转。
 */
const approvalVerifyOpen = async () => {
  const taskId = route.query.taskId as string;
  if (!taskId) {
    return;
  }
  if (!currentNodeCode.value) {
    await loadCurrentWorkflowTask();
  }
  if (currentNodeCode.value === 'leader_review') {
    const valid = await validateMainForm();
    if (!valid) {
      return;
    }
    // 领导审批：后端原子完成审核落库+流转，前端不再调 completeTask
    await leaderReviewAndCompleteTempTask({ ...form.value, taskId });
    proxy?.$modal.msgSuccess('领导审批成功');
    await proxy?.$tab.closePage(route);
    router.go(-1);
    return;
  } else if (currentNodeCode.value === 'assignee_review') {
    // 主执行人审阅：先回写可改字段，再重新装配变量后弹出审阅确认
    await assigneeReviewTempTask(form.value);
    buildVariables();
  } else {
    // 标准路径：装配变量后弹出提交流程确认
    buildVariables();
  }
  await submitVerifyRef.value?.openDialog(taskId);
};

const handleApprovalRecord = () => {
  if (form.value.tempTaskId) {
    approvalRecordRef.value?.init(form.value.tempTaskId);
  }
};

const submitCallback = async () => {
  await proxy?.$tab.closePage(route);
  router.go(-1);
};

/**
 * 兜底修复：流程已到 leader_final 但 taskStatus 仍为 3 时，
 * 调用后端补齐 totalHours 汇总 + lockFlag 锁定 + taskStatus→4。
 */
const syncTaskStateToPendingFinal = async (tempTaskId: string | number) => {
  try {
    await syncTaskState(tempTaskId);
  } catch {
    // 静默失败——canScoreClose/scoreAndClose 已有兜底逻辑
  }
};

onMounted(async () => {
  pageLoading.value = true;
  try {
    pageType.value = (route.query.type as string) || 'add';
    await getDeptList();
    await loadCurrentWorkflowTask();
    const id = route.query.id as string | number | undefined;
    if (id) {
      await loadDetail(id);
      // Why：执行人可能绕过 submitFinish 通过工作流通用审批将流程推到 leader_final，
      //      此时 taskStatus 仍为 3(执行中) 而非 4(待领导审核)。前端加载时主动修复此不一致。
      if (form.value.taskStatus === '3' && currentNodeCode.value === 'leader_final') {
        await syncTaskStateToPendingFinal(id);
        form.value.taskStatus = '4';
      }
    }
  } finally {
    pageLoading.value = false;
  }
});
</script>
