<template>
  <div class="sop-step">
    <t-collapse class="sop-step-header" defaultExpandAll>
      <t-collapse-panel header="SOP各协作项目角色说明">
        <p
          >1.大区经理：研究生项目前置流程、项目必要信息工作交接、项目内审、SOP产出物检查；</p
        >
        <p
          >2.区域协调人：根据与客户沟通确认的项目关键信息表，组织项目成员共同进行项目风险评估，对SOP产出物进行检查跟进；</p
        >
        <p>3.实施工程师：完成现场实施工作，执行SOP及产出物提交；</p>
        <t-alert class="sop-intro" theme="error">
          <div slot="title" class="sop-intro-title">
            <ErrorCircleFilledIcon /> 注意：</div
          >
          <div class="sop-intro-content">
            <p
              >1.若存在暂时无法确定的需求为必填项，大区经理可先按照经验填写，客户确定后，可对关键信息进行补充和修改，具体可参考项目计划变更报备流程。</p
            >
            <p>2.区域协调人可能会由大区经理兼任。</p>
          </div>
        </t-alert>
      </t-collapse-panel>
    </t-collapse>
    <t-collapse class="sop-step-mid" defaultExpandAll>
      <t-collapse-panel disabled>
        <template #expandIcon></template>
        <template #header>
          项目派单信息(SOP流水单号：{{ sopInfo.sopNo }})
        </template>
        <t-form colon label-width="72px">
          <t-row :gutter="[0, 4]">
            <t-col :span="3">
              <t-form-item label="项目单号">{{ sopInfo.crmNo }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="项目名称">{{ sopInfo.crmName }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="派单时间">{{
                timestampFilter(sopInfo.beginTime)
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="客户经理">{{
                sopInfo.customManagerName
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="客户类型">{{
                sopInfo.customManagerTypeStr
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="客户名称">{{
                sopInfo.customName
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="考试开始时间" label-width="100px">{{
                timestampFilter(sopInfo.examStartTime)
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="考试结束时间" label-width="100px">{{
                timestampFilter(sopInfo.examEndTime)
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="实施产品">{{
                sopInfo.productName
              }}</t-form-item>
            </t-col>
            <t-col :span="3">
              <t-form-item label="服务单元">{{
                sopInfo.serviceName
              }}</t-form-item>
            </t-col>
          </t-row>
        </t-form>
      </t-collapse-panel>
    </t-collapse>

    <div class="t-tabs sop-step-list">
      <div class="t-tabs__header step-list-header">
        <div
          v-for="item in allSteps"
          :key="item.taskKey"
          :class="[
            'step-tabs-label',
            { 'is-active': curStep === item.taskKey },
          ]"
          @click="switchStep(item)"
          >{{ item.taskName }}</div
        >
      </div>
      <div class="t-tabs__content">
        <div class="t-tab-panel">
          <t-form
            ref="form"
            colon
            class="sop-step-body"
            :rules="rules"
            :data="formData"
            labelAlign="top"
          >
            <t-row :gutter="[0, 20]">
              <t-col
                :span="
                  fullWidthCodes.includes(config.code)
                    ? 12
                    : config.span < 6
                    ? 6
                    : config.span || 6
                "
                v-for="config in curFormConfig"
                :key="config.id"
              >
                <dynamic-form-item
                  v-if="config.visable"
                  :config="config"
                  @change="itemValueChange"
                  :sop="sop"
                ></dynamic-form-item>
              </t-col>
            </t-row>
          </t-form>
          <t-space class="sop-step-footer">
            <template v-if="showAction">
              <t-button v-if="IS_EDIT_MODE" theme="primary" @click="saveHandle"
                >提交</t-button
              >
              <t-button
                v-if="!IS_EDIT_MODE"
                theme="primary"
                @click="submitHandle()"
                >提交</t-button
              >

              <t-button
                v-if="!IS_EDIT_MODE"
                theme="default"
                @click="submitHandle('DRAFT')"
                >保存草稿</t-button
              >
            </template>
          </t-space>
          <!-- setup history -->
          <div v-if="flowApproveHistoryList.length" class="sop-step-history">
            <div class="sop-step-history-label" @click="toViewHistory">
              <ChevronRightDoubleIcon v-if="stepHistoryShow" />
              <ChevronLeftDoubleIcon v-else />
              流程动态
            </div>
            <transition name="fade-slide" mode="out-in" appear>
              <div v-if="stepHistoryShow" class="sop-step-history-content">
                <div class="content-head">
                  <h2>
                    {{ sop.statusStr }}
                  </h2>
                  <p>{{ stepDuration }}</p>
                </div>
                <div class="content-body">
                  <t-collapse>
                    <t-collapse-panel
                      v-for="(item, findex) in flowApproveHistoryList"
                      :key="findex"
                      :header="item.taskName"
                    >
                      <template #headerRightContent>
                        <t-space size="small">
                          <span class="collapse-head-right">{{
                            timestampFilter(item.createTime)
                          }}</span>
                          <t-tag
                            :theme="
                              item.approveOperation === 'REJECT'
                                ? 'danger'
                                : 'success'
                            "
                            variant="light"
                          >
                            {{ item.approveRemark }}
                          </t-tag>
                        </t-space>
                      </template>
                      <div class="content-detail">
                        <div class="content-detail-head">
                          {{ item.approveUserName || '--' }}
                        </div>
                        <div class="content-detail-body">
                          <p
                            >开始处理：{{ timestampFilter(item.createTime) }}</p
                          >
                          <p>处理耗时：{{ item.duration }}</p>
                        </div>
                      </div>
                    </t-collapse-panel>
                  </t-collapse>
                </div>
              </div>
            </transition>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup name="SopStep">
import { ref, computed, watch } from 'vue';
import {
  ErrorCircleFilledIcon,
  ChevronLeftDoubleIcon,
  ChevronRightDoubleIcon,
} from 'tdesign-icons-vue-next';
import { MessagePlugin } from 'tdesign-vue-next';

import DynamicFormItem from '../../components/dynamic-form-item/index.vue';
// import { useRouter, useRoute } from 'vue-router';
import {
  sopFlowViewApi,
  sopEditApi,
  sopSaveApi,
  sopApproveApi,
  sopApplyApi,
  flowFormPropertiesApi,
} from '@/api/sop';
import { objCopy, timeNumberToText } from '@/utils/tool';
import { timestampFilter } from '@/utils/filter';
import bus from '@/utils/bus';

const props = defineProps({
  type: {
    type: String,
    default: 'fill',
  },
  sop: {
    type: Object,
    default() {
      return {};
    },
  },
});
const emit = defineEmits(['confirm']);

const IS_VIEW_MODE = computed(() => {
  return props.type === 'view';
});
const IS_NEW_MODE = computed(() => {
  return props.type === 'new';
});
const IS_FILL_MODE = computed(() => {
  return props.type === 'fill';
});
const IS_EDIT_MODE = computed(() => {
  return props.type === 'edit';
});

const sopInfo = ref({
  crmNo: '',
  crmName: '',
  beginTime: '',
  customManagerName: '',
  customManagerTypeStr: '',
  customName: '',
  examStartTime: '',
  examEndTime: '',
  productName: '',
  serviceName: '',
});
const needValueCodes = [
  'NUMBER', //新增
  'TEXT',
  'DATE',
  'SINGLE_SELECT',
  'MULTIPLE_SELECT',
  'CHECKBOX',
  'TEXTAREA',
  'TABLE',
  'RADIO',
  'RADIO_WITH_INPUT',
  'SIGN',
  'DEVICE_OUT_TABLE',
  'DEVICE_IN_TABLE',
  'FILE',
];
const rules = ref({
  // scan_net_radio_2: [{ required: true, type: 'error', message: '大大是的' }],
});
const formData = ref({});
const loading = ref(false);
const fullWidthCodes = ref([
  'TABLE',
  'FORM_GROUP_TITLE',
  'TEXTAREA',
  'ONLY_TITLE',
  'DEVICE_OUT_TABLE',
  'DEVICE_IN_TABLE',
]);
const form = ref(null);
const sopEditDetail = ref({});
const allFormData = ref({});
const allSteps = ref([]);
let curStep = ref('');
const curStepData = ref({});
const currFlowTaskResultSetup = ref(null);
const flowId = props.sop.flowId;
const crmInfo = ref({});
const approveRejectFormIds = {
  // taskkey:[formId]
  f_usertask_office_inside_approve_3: [
    'approve_radio_region_3',
    'approve_radio_engineer_3',
  ],
  f_usertask_cloudmark_inside_approve_3: [
    'approve_radio_region_3',
    'approve_radio_engineer_3',
  ],
};
const stepHistoryShow = ref(false);
const flowApproveHistoryList = ref([]);
const stepDuration = ref('');
const otherRules = ref({
  DEVICE_IN_TABLE: true,
});
bus.on('changeOtherRules', (obj) => {
  otherRules.value[obj.code] = obj.result;
});
const otherRulesPassed = computed(() => {
  let values = Object.values(otherRules.value);
  return !values.filter((item) => !item).length;
});

function getFlowApproveHistoryList(data) {
  if (!data) return [];

  let lastTime = 0;
  // return data.map((item, index) => {
  //   let nitem = { ...item };
  //   nitem.duration =
  //     index === 0 ? '-' : timeNumberToText(item.createTime - lastTime);
  //   lastTime = item.createTime;
  //   return nitem;
  // });
  for (let i = data.length - 1; i >= 0; i--) {
    let item = data[i];
    item.duration =
      i === data.length - 1
        ? '-'
        : timeNumberToText(item.createTime - lastTime);
    lastTime = item.createTime;
  }
  return data;
}

function updateSopInfo(crmInfo) {
  let data = { ...props.sop };
  data.beginTime = crmInfo.crmBeginTime;
  data.customManagerName = crmInfo.customManagerName;
  data.customManagerTypeStr =
    props.sop.customManagerTypeStr || props.sop.customTypeStr;
  data.customName = crmInfo.customName;
  data.examStartTime = crmInfo.examStartTime;
  data.examEndTime = crmInfo.examEndTime;
  data.productName = crmInfo.productName;
  data.serviceName = crmInfo.serviceUnitName;
  sopInfo.value = data;
}

const initNew = async () => {
  loading.value = true;
  const flowRes = await sopFlowViewApi({ flowId });
  crmInfo.value = flowRes.crmInfo;
  updateSopInfo(crmInfo.value);
  const res = await flowFormPropertiesApi({
    flowDeploymentId: props.sop.flowDeploymentId,
  });
  loading.value = false;

  allSteps.value = [res.formProperties];
  switchStep(allSteps.value[0]);
};
const initFill = async () => {
  loading.value = true;
  const res = await sopFlowViewApi({ flowId });
  loading.value = false;
  crmInfo.value = res.crmInfo;
  updateSopInfo(crmInfo.value);
  sopInfo.value.sopNo = res.sopNo;

  res.flowTaskHistoryList = res.flowTaskHistoryList || [];
  res.flowTaskHistoryList.forEach((item) => {
    item.formProperty.forEach((v) => {
      v.writable = false;
    });
  });
  if (res.currFlowTaskResult) {
    res.currFlowTaskResult.formProperty =
      res.currFlowTaskResult.formProperty.map((item) => {
        //设备出库时间和设备入库时间，赋予默认值为当前时间
        if (
          // ['device_out_time_4', 'device_in_time_10'].includes(item.formName) &&
          (item.formName.startsWith('device_out_time') ||
            item.formName.startsWith('device_in_time')) &&
          !item.value
        ) {
          let now = Date.now();
          item.value = JSON.stringify({ value: now });
        }
        return item;
      });
    currFlowTaskResultSetup.value = res.currFlowTaskResult.setup;
    allSteps.value = [...res.flowTaskHistoryList, res.currFlowTaskResult];

    curStep.value = res.currFlowTaskResult.taskKey;
    const stepData = allSteps.value.find(
      (item) => item.taskKey === curStep.value
    );

    curStepData.value = stepData;
  } else {
    allSteps.value = [...res.flowTaskHistoryList];
    curStepData.value = allSteps.value[0];
    curStep.value = curStepData.value.taskKey;
  }
  allSteps.value = allSteps.value.sort((a, b) => a.setup - b.setup);
  allSteps.value.forEach((item) => {
    item.formProperty.forEach((prop) => {
      prop.value = prop.value ? JSON.parse(prop.value).value : null;
    });
  });
  flowApproveHistoryList.value = getFlowApproveHistoryList(
    res.flowApproveHistoryList
  );
};
const initEdit = async () => {
  loading.value = true;
  const res = await sopEditApi(props.sop.id);
  loading.value = false;
  crmInfo.value = res.crmInfo || {};
  updateSopInfo(crmInfo.value);
  sopEditDetail.value = res;
  allSteps.value = Object.values(res.setupMap)
    .sort((a, b) => a.setup - b.setup)
    //2023-11-20新增需求，编辑时，第一步里，除了那3个选人的地方，其余全部改为可写状态
    .map((item) => {
      if (item.setup == 1) {
        item.formProperty = item.formProperty.map((v) => {
          if (
            ![
              'region_user_id_1',
              'engineer_user_id_1',
              'assistant_engineer_user_id_1',
            ].includes(v.formName)
          ) {
            v.writable = true;
          }
          if (v.formName === 'third_service_region_cb_1') {
            v.writable = false;
          }
          return v;
        });
      }
      return item;
    });
  flowApproveHistoryList.value = getFlowApproveHistoryList(
    res.flowApproveHistoryList
  );
  let allFormMap = {};
  allSteps.value.forEach((item) => {
    item.formProperty.forEach((prop) => {
      allFormMap[prop.formName] = prop.value
        ? JSON.parse(prop.value).value
        : null;
    });
  });
  allFormData.value = allFormMap;
  const stepData = allSteps.value.slice(-1)[0];
  curStep = stepData.taskKey;
  curStepData.value = stepData;
};
const init = () => {
  if (IS_FILL_MODE.value || IS_VIEW_MODE.value) {
    // 填报
    initFill();
  } else if (IS_EDIT_MODE.value) {
    // 编辑
    initEdit();
  } else {
    // 还有可能是点击“新增SOP”进来的
    initNew();
  }
};
init();

const maxStep = computed(() => {
  return Math.max(...allSteps.value.map((item) => item.setup));
});

const showAction = computed(() => {
  if (
    // (IS_EDIT_MODE.value && curStepData.value.setup !== 1) ||
    (IS_EDIT_MODE.value &&
      (curStepData.value.setup == 1 ||
        curStepData.value.setup == maxStep.value)) ||
    IS_NEW_MODE.value
  )
    return true;

  if (
    IS_FILL_MODE.value &&
    curStepData.value.setup === currFlowTaskResultSetup.value
  )
    return true;

  return false;
});

const curFormConfig = computed(() => {
  const formProperty = curStepData.value.formProperty || [];
  formProperty.forEach((item) => {
    if (IS_EDIT_MODE.value) {
      item.value = allFormData.value[item.formName];
    }

    if (IS_VIEW_MODE.value) {
      item.writable = false;
    }
  });

  // 填报时第一步的特殊处理
  if (curStepData.value.setup === 1) {
    // region_user_id_1 区域协调人
    // engineer_user_id_1 实施工程师
    // assistant_engineer_user_id_1 助理工程师
    formProperty.forEach((field) => {
      // 区域协调人
      if (field.formId.startsWith('region_user')) {
        field.value = crmInfo.value.regionCoordinatorId;
        field.options = [
          {
            label: crmInfo.value.regionCoordinatorName,
            value: crmInfo.value.regionCoordinatorId,
          },
        ];
      }
      // 实施工程师
      if (field.formId.startsWith('engineer_user')) {
        field.options = crmInfo.value.effectEngineerList.map((user) => {
          return {
            label: user.name,
            value: user.userId,
          };
        });
        if (field.options.length == 1) {
          field.value = field.options[0].value;
        }
      }
      // 助理工程师
      if (field.formId.startsWith('assistant_engineer_user')) {
        field.options = crmInfo.value.assistantEngineerList.map((user) => {
          return {
            label: user.name,
            value: user.userId,
          };
        });
        if (!field.options.length) {
          field.writable = false;
        }
      }
      if (field.formId.startsWith('week_people_day') && !field.value) {
        field.value = crmInfo.value.peoperDay;
      }
    });
  }
  return formProperty;
});
watch(curFormConfig, (val) => {
  formData.value = val.reduce((obj, item) => {
    if (needValueCodes.includes(item.code)) {
      obj[item.formName] = item.value || null;
    }
    return obj;
  }, {});
  rules.value = val.reduce((obj, item) => {
    let ruleItem =
      item.required && item.code === 'CHECKBOX'
        ? {
            validator: (val) => {
              let options = Array.isArray(item.options)
                ? item.options
                : JSON.parse(item.options);

              if (formData.value?.[item.formName]?.length != options.length) {
                return {
                  result: false,
                  message: `"${item.title}"中有未选中项`,
                  type: 'error',
                };
              }

              return {
                result: true,
                message: '',
                type: 'success',
              };
            },
          }
        : item.required && needValueCodes.includes(item.code)
        ? {
            required: true,
            message: `${item.title}不能为空`,
            type: 'error',
            trigger: 'change',
          }
        : null;
    if (ruleItem) {
      obj[item.formName] = [ruleItem];
    }
    return obj;
  }, {});
});

const toViewHistory = () => {
  stepHistoryShow.value = !stepHistoryShow.value;
};

const switchStep = async (stepData) => {
  if (IS_EDIT_MODE.value) {
    const valid = await form.value.validate();
    if (
      (valid !== true || !otherRulesPassed.value) &&
      curStepData.value.setup !== 3
    )
      return MessagePlugin.error('请完善必填项');

    allFormData.value = { ...allFormData.value, ...formData.value };
  }

  curStep = stepData.taskKey;
  curStepData.value = stepData;
};

const itemValueChange = ({ prop, value }) => {
  console.log(prop, ':', value);
  formData.value[prop] = value;
  allFormData.value[prop] = value;
};

const getFormData = () => {
  let data = {};

  if (IS_EDIT_MODE.value) {
    data = objCopy(sopEditDetail.value);
    for (const k in data.setupMap) {
      if (Object.hasOwnProperty.call(data.setupMap, k)) {
        const element = data.setupMap[k];
        element.formProperty.forEach((item) => {
          item.value = JSON.stringify({
            value: allFormData.value[item.formName] || null,
          });
        });
      }
    }
  } else {
    // 新增 or 填报
    data = { ...curStepData.value };
    data.formProperty = data.formProperty.map((item) => {
      return {
        ...item,
        value: JSON.stringify({ value: formData.value[item.formName] || null }),
      };
    });
  }
  return JSON.stringify(data);
};
// 填报-提交
const submitHandle = async (approve = 'START') => {
  if (approve !== 'DRAFT') {
    // 提交
    const valid = await form.value.validate();
    if (valid !== true || !otherRulesPassed.value)
      return MessagePlugin.error('请完善必填项');

    if (curStepData.value.setup !== 1) {
      const rejectFormIds = approveRejectFormIds[curStepData.value.taskKey];
      if (
        rejectFormIds &&
        rejectFormIds.some((fid) => formData.value[fid] === '0')
      ) {
        approve = 'REJECT';
      } else {
        approve = 'PASS';
      }
    }
  }
  // console.log(approve);
  // if (approve) return;

  if (IS_FILL_MODE.value) {
    let data = {
      taskId: props.sop.taskId,
      formProperties: getFormData(),
      approve,
    };
    if (approve === 'REJECT') {
      // 目前只打回给定的允许打回的第一个选项
      data.setup = curStepData.value.approveRejectList[0].setup;
    }
    const res = await sopApproveApi(data).catch(() => {});
    if (!res) return;
  } else if (IS_NEW_MODE.value) {
    const res = await sopApplyApi({
      crmNo: props.sop.crmNo,
      flowDeploymentId: props.sop.flowDeploymentId,
      formProperties: getFormData(),
      approve,
    }).catch(() => {});
    if (!res) return;
  }

  MessagePlugin.success('保存成功');
  emit('confirm');
};
// 编辑-保存
const saveHandle = async () => {
  const valid = await form.value.validate();
  if (valid !== true || !otherRulesPassed.value)
    return MessagePlugin.error('请完善必填项');

  const res = await sopSaveApi({
    id: props.sop.id,
    formProperties: getFormData(),
  }).catch(() => {});
  if (!res) return;

  MessagePlugin.success('保存成功');
  emit('confirm');
};
</script>
