<template>
  <BasicLayout>
    <!-- 统一的滚动容器，包含编辑组件和流程组件 -->
    <scroll-view scroll-y class="unified-scroll" :class="{ 'full-height': hideBottomBtn }">
      <!-- 引入编辑组件（不包含滚动） -->
      <JfEdit v-if="isLoginReady" ref="jfEditRef" :jf-id="jfId" @saved="handleDataSaved" @loaded="handleJfEditLoaded" @popup-change="handlePickerPopupChange" />

      <!-- 审批流程展示 -->
      <view class="flow-section" v-if="jfId">
        <LcglSp :yw-id="jfId" yw-type="JF" :key="jfId" />
      </view>
    </scroll-view>

    <template #bottom>
      <view :class="{ 'hide-bottom': hideBottomBtn }">
        <YwConfirm
          v-if="showButton"
          :spApi="wrappedJfSpApi"
          :stopApi="wrappedJfStopApi"
          :transferApi="wrappedJfTransferApi"
          :params="spParams"
          :autoToMessage="false"
          :showXt="false"
          :showReject="!isYiban"
          :showTransfer="false"
          :showApprove="!isYiban"
          :showReturn="false"
          :showStop="true"
          :showXtDk="false"
          approveText="通过"
          @submit="handleSubmit"
          @reject="handleReject"
          @transfer="handleTransfer"
          @stop="handleStop"
        />
      </view>
    </template>

    <!-- 遮罩层 -->
    <view v-if="loading" class="loading-mask">
      <view class="loading-content">
        <view class="loading-spinner"></view>
        <text class="loading-text">{{ loadingText }}</text>
      </view>
    </view>
  </BasicLayout>
</template>

<script setup lang="ts">
import { onLoad, onBackPress } from "@dcloudio/uni-app";
import { ref, computed } from "vue";
import dayjs from "dayjs";
import BasicLayout from "@/components/BasicLayout/Layout.vue";
import LcglSp from "@/components/LcglSp/index.vue";
import YwConfirm from "@/pages/components/YwConfirm/index.vue";
import JfEdit from "./JfEdit.vue";
import { jfFlowByIdApi, jfSpApi, jfTransferApi, jfStopApi, jfSaveApi } from "@/api/base/jfApi";
import { xxtsFindByIdApi } from "@/api/base/xxtsApi";
import { useUserStore } from "@/store/modules/user";

const { loginByOpenId, getJs } = useUserStore();

const jfId = ref<string>("");
const jfInfo = ref<any>({});
const showButton = ref<boolean>(false);
const isLoginReady = ref<boolean>(false); // 登录是否准备就绪
// 编辑组件的引用，用于获取表单数据
const jfEditRef = ref<any>(null);
// 控制底部按钮区域显示/隐藏
const hideBottomBtn = ref(false);
// 遮罩层状态
const loading = ref<boolean>(false);
const loadingText = ref<string>("处理中...");
// 数据加载状态
const jfInfoLoaded = ref<boolean>(false); // 流程数据是否已加载
const jfEditLoaded = ref<boolean>(false); // 编辑组件数据是否已加载
// 是否已办（dbZt === "B" 表示已办）
const dbZtFromUrl = ref<string>("");
// 直接用一个 ref 保存 xxtsId
const xxtsId = ref<string>("");
const isYiban = computed(() => {
  return dbZtFromUrl.value === "B";
});

// 审批参数（只包含审批相关字段，业务字段通过 save 接口保存）
const spParams = computed(() => {
  return {
    xxtsId: xxtsId.value,
    ywId: jfId.value,
    // 业务字段已通过 save 接口保存，这里不再传递
  };
});

// 读取流程详情（用于审批时获取最新数据）
const getJfInfo = async () => {
  try {
    const res: any = await jfFlowByIdApi({ id: jfId.value });
    if (res && res.resultCode === 1 && res.result) {
      jfInfo.value = res.result.jfInfo || {};
      const spResult = jfInfo.value?.spResult;
      const spJd = jfInfo.value?.spJd;

      // 已完结或驳回：隐藏审批按钮
      if (spResult === "C" || (spJd === "Z" && spResult === "B")) {
        showButton.value = false;
      } else if (spResult && spResult !== "A" && dbZtFromUrl.value === "A") {
        // 历史逻辑：当流程已完成且待办状态关闭时，不显示审批按钮
        showButton.value = false;
      } else {
        showButton.value = true;
      }
    } else {
      showButton.value = false;
    }
    jfInfoLoaded.value = true;
    checkAllDataLoaded();
  } catch (error) {
    console.error("获取积分流程失败:", error);
    showButton.value = false;
    jfInfoLoaded.value = true;
    checkAllDataLoaded();
  }
};

// 获取编辑组件的表单数据
const getJfEditFormData = () => {
  if (!jfEditRef.value) {
    console.warn('JfEdit 组件引用不存在');
    return null;
  }
  // 通过 ref 访问子组件的 formData
  const formData = jfEditRef.value.formData;
  if (!formData) {
    console.warn('无法从 JfEdit 组件获取 formData');
    return null;
  }
  console.log('获取到表单数据:', formData);
  return formData;
};

// 保存编辑组件数据（审批前调用）
const saveJfDataBeforeApprove = async () => {
  console.log('开始保存编辑组件数据...');
  console.log('jfEditRef.value:', jfEditRef.value);
  
  // 显示遮罩层
  loading.value = true;
  loadingText.value = '正在保存数据...';
  
  try {
    // 等待一下，确保组件已挂载
    await new Promise(resolve => setTimeout(resolve, 100));
    
    const formData = getJfEditFormData();
    if (!formData) {
      console.error('无法获取表单数据');
      loading.value = false;
      return { success: false, message: '无法获取表单数据，请确保编辑组件已加载' };
    }
    
    // 验证必要字段
    if (!formData.jfTypeId) {
      console.warn('表单数据缺少 jfTypeId');
      loading.value = false;
      return { success: false, message: '请先选择业绩类别' };
    }
    const jfTypeId = typeof formData.jfTypeId === 'object' && formData.jfTypeId !== null 
      ? formData.jfTypeId.value 
      : formData.jfTypeId;
    
    let hjtime = formData.hjtime;
    if (hjtime && hjtime.length === 7 && hjtime.match(/^\d{4}-\d{2}$/)) {
      hjtime = hjtime + '-01';
    }
    
    let fileUrl = '';
    let fileName = '';
    let fileFormat = '';
    if (formData.attachments && formData.attachments.length > 0) {
      const urls: string[] = [];
      const names: string[] = [];
      const exts: string[] = [];
      formData.attachments.forEach((att: any) => {
        if (att.url) urls.push(att.url);
        if (att.name) names.push(att.name);
        const ext = (att.name || '').split('.').pop()?.toLowerCase() || '';
        if (ext) exts.push(ext);
      });
      fileUrl = urls.join(',');
      fileName = names.join(',');
      fileFormat = exts.join(',');
    }
    
    // 获取当前用户信息，设置考核人
    const js = getJs;
    let khJsId = '';
    let khjsxm = '';
    if (js) {
      khJsId = js.id || '';
      khjsxm = js.jsxm || js.xm || '';
    }
    // 设置考核时间为今天
    const today = new Date();
    const khTime = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
    
    const submitData: any = {
      ...formData,
      id: jfId.value, // 确保有ID
      jfTypeId: jfTypeId,
      hjtime: hjtime,
      fileUrl: fileUrl,
      fileName: fileName,
      fileFormat: fileFormat,
      khJsId: khJsId,
      khjsxm: khjsxm,
      khTime: khTime,
    };
    
    delete submitData.attachments;
    
    // 处理学生获奖名单：转换为 studentList 格式（只保存有效状态的学生）
    // 注意：需要判断是否需要保存学生名单（根据 showStudentAward 或 formData 中的标识）
    if (formData.hjmdList && Array.isArray(formData.hjmdList) && formData.hjmdList.length > 0) {
      const validStudents = formData.hjmdList.filter((s: any) => s.status !== 'D');
      submitData.studentList = validStudents.map((student: any) => {
        // 如果没有 bc，根据 njbc、njmc、bjmc 组合生成
        let bc = student.bc;
        if (!bc && (student.njmc || student.njbc || student.bjmc)) {
          const parts: string[] = [];
          if (student.njmc) parts.push(student.njmc);
          if (student.njbc) parts.push(`(${student.njbc})`);
          if (student.bjmc) parts.push(student.bjmc);
          bc = parts.join('');
        }
        
        return {
          id: student.id,  // 编辑时保留ID
          xsId: student.xsId,
          xsxm: student.xsxm,
          njId: student.njId,
          njmcId: student.njmcId,
          bjId: student.bjId,
          njbc: student.njbc,
          njmc: student.njmc,
          bjmc: student.bjmc,
          bc: bc || '',
          status: student.status || 'A',
          remark: student.remark || ''
        };
      });
    } else {
      // 如果没有学生，传递空数组（用于删除所有学生）
      submitData.studentList = [];
    }
    
    console.log('准备调用保存接口，数据:', submitData);
    const res: any = await jfSaveApi(submitData);
    console.log('保存接口返回:', res);
    
    if (res && res.resultCode === 1) {
      console.log('数据保存成功（包含学生获奖名单）');
      
      // 保存成功后，更新 jfInfo 用于审批参数
      await getJfInfo();
      loading.value = false;
      return { success: true };
    } else {
      console.error('数据保存失败:', res?.resultMsg);
      loading.value = false;
      return { success: false, message: res?.resultMsg || '保存失败' };
    }
  } catch (error) {
    console.error('保存数据失败:', error);
    loading.value = false;
    return { success: false, message: '保存数据失败' };
  }
};

// 包装审批接口，先保存数据再审批
const wrappedJfSpApi = async (params: any) => {
  console.log('审批接口被调用，参数:', params);
  
  try {
    // 先保存编辑组件的数据
    console.log('步骤1: 保存编辑组件数据');
    const saveResult = await saveJfDataBeforeApprove();
    
    if (!saveResult.success) {
      console.error('保存数据失败:', saveResult.message);
      loading.value = false;
      uni.showToast({
        title: saveResult.message || '保存数据失败',
        icon: 'none',
        duration: 2000
      });
      throw new Error(saveResult.message || '保存数据失败');
    }
    
    console.log('步骤2: 数据保存成功，开始审批');
    loadingText.value = '正在审批...';
    
    // 保存成功后，再调用审批接口（只传递审批相关参数，不传递业务字段）
    const spParams = {
      xxtsId: params.xxtsId,
      ywId: params.ywId,
      spStatus: params.spStatus,
      spRemark: params.spRemark
    };
    
    console.log('步骤3: 调用审批接口，参数:', spParams);
    const result = await jfSpApi(spParams);
    console.log('审批接口返回:', result);
    loading.value = false;
    return result;
  } catch (error: any) {
    console.error('审批流程出错:', error);
    loading.value = false;
    throw error;
  }
};

// 包装转办接口，先保存数据再转办
const wrappedJfTransferApi = async (params: any) => {
  console.log('转办接口被调用，参数:', params);
  
  try {
    // 先保存编辑组件的数据
    console.log('步骤1: 保存编辑组件数据');
    const saveResult = await saveJfDataBeforeApprove();
    
    if (!saveResult.success) {
      console.error('保存数据失败:', saveResult.message);
      loading.value = false;
      uni.showToast({
        title: saveResult.message || '保存数据失败',
        icon: 'none',
        duration: 2000
      });
      throw new Error(saveResult.message || '保存数据失败');
    }
    
    console.log('步骤2: 数据保存成功，开始转办');
    loadingText.value = '正在转办...';
    
    // 保存成功后，再调用转办接口
    const transferParams = {
      xxtsId: params.xxtsId,
      ywId: params.ywId,
      zbrIds: params.zbrIds,
      csrIds: params.csrIds,
      spRemark: params.spRemark,
    };
    
    console.log('步骤3: 调用转办接口，参数:', transferParams);
    const result = await jfTransferApi(transferParams);
    console.log('转办接口返回:', result);
    loading.value = false;
    return result;
  } catch (error: any) {
    console.error('转办流程出错:', error);
    loading.value = false;
    throw error;
  }
};

// 包装终止接口，先保存数据再终止
const wrappedJfStopApi = async (params: any) => {
  console.log('终止接口被调用，参数:', params);
  
  try {
    // 先保存编辑组件的数据
    console.log('步骤1: 保存编辑组件数据');
    const saveResult = await saveJfDataBeforeApprove();
    
    if (!saveResult.success) {
      console.error('保存数据失败:', saveResult.message);
      loading.value = false;
      uni.showToast({
        title: saveResult.message || '保存数据失败',
        icon: 'none',
        duration: 2000
      });
      throw new Error(saveResult.message || '保存数据失败');
    }
    
    console.log('步骤2: 数据保存成功，开始终止');
    loadingText.value = '正在终止...';
    
    // 保存成功后，再调用终止接口
    const stopParams = {
      xxtsId: params.xxtsId,
      ywId: params.ywId,
      spRemark: params.spRemark,
    };
    
    console.log('步骤3: 调用终止接口，参数:', stopParams);
    const result = await jfStopApi(stopParams);
    console.log('终止接口返回:', result);
    loading.value = false;
    return result;
  } catch (error: any) {
    console.error('终止流程出错:', error);
    loading.value = false;
    throw error;
  }
};

// 处理选择器弹窗状态变化
const handlePickerPopupChange = (show: boolean) => {
  hideBottomBtn.value = show;
};

// 处理编辑组件数据加载完成
const handleJfEditLoaded = () => {
  jfEditLoaded.value = true;
  checkAllDataLoaded();
};

// 检查所有数据是否已加载完成
const checkAllDataLoaded = () => {
  if (jfInfoLoaded.value && jfEditLoaded.value) {
    // 延迟一点时间，确保界面渲染完成
    setTimeout(() => {
      loading.value = false;
    }, 300);
  }
};

// 处理数据保存后的回调
const handleDataSaved = async () => {
  // 数据保存后，重新获取最新数据用于审批
  await getJfInfo();
};

// 处理审批操作完成后的跳转
const handleSubmit = () => {
  navigateToIndex();
};

const handleReject = () => {
  navigateToIndex();
};

const handleTransfer = () => {
  navigateToIndex();
};

const handleStop = () => {
  navigateToIndex();
};

// 跳转回审批列表页面
const navigateToIndex = () => {
  setTimeout(() => {
    uni.redirectTo({
      url: '/pages/view/routine/JiFenPingJia/jfsp/index'
    });
  }, 500);
};

// 返回按钮监听（仅 App 端生效，H5 端已在 ImagePreviewWithRotate 组件内部处理）
onBackPress(() => {
  // 检查 JfEdit 子组件是否正在预览图片
  if (jfEditRef.value && jfEditRef.value.certificateUploadRef) {
    const certUpload = jfEditRef.value.certificateUploadRef;
    const isPreviewing = certUpload.isPreviewing;
    if (isPreviewing) {
      // 如果正在预览图片，关闭预览并阻止返回
      certUpload.closePreview();
      return true; // 阻止默认返回行为
    }
  }
  // 没有预览图片，允许正常返回
  return false;
});

onLoad(async (options: any) => {
  if (!options || !options.id) {
    uni.showToast({ title: "缺少积分ID", icon: "none" });
    setTimeout(() => uni.navigateBack(), 1500);
    return;
  }

  // 如果有 openId，先进行认证（防止 token 过期）
  if (options.openId) {
    try {
      const loginSuccess = await loginByOpenId(options.openId);
      if (!loginSuccess) {
        // 登录失败，停止后续流程
        return;
      }
      // 等待一下，确保 token 已保存到 store 中
      await new Promise(resolve => setTimeout(resolve, 100));
    } catch (e) {
      console.error("openId认证失败:", e);
      // 认证失败，停止后续流程
      return;
    }
  }
  
  // 标记登录准备就绪，允许组件开始加载数据（无论是否有 openId）
  isLoginReady.value = true;

  // 显示遮罩层
  loading.value = true;
  loadingText.value = '正在加载数据...';
  // 重置加载状态
  jfInfoLoaded.value = false;
  jfEditLoaded.value = false;

  let actualJfId = options.id; // 默认使用传入的 ID

  // 如果是从待办进入的（from=db），需要先获取 xxts 信息，然后获取业务 ID
  if (options.from === 'db') {
    try {
      // 从后端根据 url 中的 id（xxts ID）查询待办信息
      const xxtsRes = await xxtsFindByIdApi({ id: options.id });
      
      if (xxtsRes && xxtsRes.result) {
        const xxts = xxtsRes.result;
        
        // 直接保存 xxtsId
        if (xxts.id) {
          xxtsId.value = xxts.id;
        }
        
        // 从 xxts 中获取业务 ID（xxzbId）
        if (xxts.xxzbId) {
          actualJfId = xxts.xxzbId;
        }
        
        // 从 xxts 获取 dbZt
        if (xxts.dbZt) {
          dbZtFromUrl.value = xxts.dbZt;
        }
      }
    } catch (error) {
      console.error('获取待办信息失败:', error);
      // 如果获取失败，继续使用原始 ID
    }
  } else {
    // 如果不是从待办进入，检查 URL 参数中是否有 xxtsId
    if (options.xxtsId) {
      xxtsId.value = options.xxtsId;
    }
    
    // 从 URL 参数获取 dbZt（如果传递了的话）
    if (options.dbZt) {
      dbZtFromUrl.value = options.dbZt;
    }
  }

  // 使用实际的业务 ID
  jfId.value = actualJfId;
  
  getJfInfo();
});
</script>

<style scoped lang="scss">
.unified-scroll {
  flex: 1;
  height: calc(100vh - 120rpx);
  overflow-y: auto;
  
  &.full-height {
    height: 100vh;
  }
}

.flow-section {
  padding: 0;
  background-color: #f5f5f5;
  margin-top: 30rpx;
  
  // 确保流程组件与编辑组件有间距
  :deep(.lcgl-info) {
    padding-top: 0;
    margin-top: 0;
    padding-left: 0;
    padding-right: 0;
  }
  
  // 流程组件的 section 也要移除左右边距
  :deep(.info-section) {
    border-radius: 0;
    margin-left: 0;
    margin-right: 0;
  }
}

// 统一滚动容器的样式
.unified-scroll {
  background-color: #f5f5f5;
}

// 遮罩层样式
.loading-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  
  .loading-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #ffffff;
    border-radius: 16rpx;
    padding: 60rpx 80rpx;
    min-width: 300rpx;
    
    .loading-spinner {
      width: 60rpx;
      height: 60rpx;
      border: 6rpx solid #f3f3f3;
      border-top: 6rpx solid #007aff;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      margin-bottom: 30rpx;
    }
    
    .loading-text {
      font-size: 28rpx;
      color: #333333;
      text-align: center;
    }
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

// 隐藏底部按钮区域
.hide-bottom {
  display: none !important;
  height: 0 !important;
  padding: 0 !important;
}
</style>

