<template>
  <div class="container">
    <el-card :shadow="device === 'desktop' ? 'always' : 'never'"
             class="card"
             :style="{
               border: device === 'desktop' ? '' : 'none',
               background: device === 'desktop' ? '' : '#f7f8fa',
               'min-height': device === 'desktop' ? '' : '100vh',
             }">
      <template #header>
        <p>{{ config.customModel ? config.customModel.name : "办理" }}</p>
      </template>

      <template>
        <div class="steps" v-if="!/\/detail/.test($route.path)">
          <el-steps :space="120" finish-status="success" align-center>
            <el-step
              :title="node.name"
              status="finish"
              icon="el-icon-edit"
            ></el-step>
            <el-step
              v-for="nextNode in node.nextNodes"
              :key="nextNode.id"
              :title="nextNode.name"
              icon="el-icon-right"
              status="wait"
            ></el-step>
          </el-steps>

          <el-divider></el-divider>

        </div>

        <div class="form-container">
          <template v-if="device === 'desktop'">
            <DesktopForm
              :device="device"
              ref="desktopForm"
              :sub-form="subConfig"
              :fields="fields"
              :original-form="form"
              :readable="readableFields"
              :file-list="fileList"
              :script-content="scriptContent"
              :writeable="writeableFields"
              :rules="rules"
            ></DesktopForm>
          </template>
          <template v-else>
            <MobileForm
              :device="device"
              ref="mobileForm"
              :sub-form="subConfig"
              :fields="fields"
              :original-form="form"
              :readable="readableFields"
              :file-list="fileList"
              :script-content="scriptContent"
              :writeable="writeableFields"
            ></MobileForm>
          </template>
        </div>
      </template>

<!--      审批日志-->
      <div v-if="/\/detail/.test($route.path)" style="margin-top: 10px">
        <div>流转记录</div>
        <vxe-table
          show-footer
          ref="table"
          stripe
          class="log-table-scroll"
          keep-source
          show-overflow
          :column-config="{ resizable: true }"
          :print-config="{}"
          :export-config="{}"
          :custom-config="{ mode: 'popup' }"
          :footer-data="footerData"
          :data="config.logs || []"
        >
          <vxe-column type="seq" width="62" align="center" field="seq" title="编号"/>
          <vxe-column width="140" title="节点名称" align="center" field="node.name" :formatter="({ cellValue }) => (cellValue || '节点已调整')"></vxe-column>
          <vxe-column width="80" align="center" title="办理状态" field="status" :formatter="({ cellValue }) => (myStatus.get(cellValue))">
            <template #default="{ row }">
              <el-tag
                size="mini"
                :type="statusColor.get(row.status)"
                effect="dark"
              >{{ myStatus.get(row.status) }}</el-tag
              >
            </template>
          </vxe-column>
          <vxe-column align="center" width="80" title="承办人员" field="user.name"></vxe-column>
          <vxe-column align="center" width="200" title="流转时间" field="created_at" :formatter="({ cellValue }) => $moment(cellValue).format('YYYY年MM月DD日 HH:mm:ss')"></vxe-column>
          <vxe-column min-width="200" header-align="center" title="退回原因" field="reason"></vxe-column>
          <vxe-column align="center" width="200" title="办理时间" field="updated_at">
            <template #default="{ row }">
              <span :style="{ 'color': (row.deadline && row.updated_at && $moment(row.updated_at).isAfter($moment(row.deadline).endOf('day')) ? 'red' : '') }">{{ $moment(row.updated_at).format('YYYY年MM月DD日 HH:mm:ss') }}</span>
            </template>
          </vxe-column>
          <vxe-column align="center" title="耗时" field="use_time" width="120">
            <template #default="{ row }">
              <span>{{ diffTime(row.updated_at, row.created_at) }}</span>
            </template>
          </vxe-column>
        </vxe-table>
      </div>

      <div class="btns" ref="btns">
        <template v-if="!/\/detail/.test($route.path)">
          <el-button
            v-if="$route.query.flow_id"
            icon="el-icon-arrow-left"
            type="danger"
            size="small"
            @click="isShowRollback = true"
          >退回</el-button
          >
          <el-button
            v-if="$route.query.flow_id"
            icon="el-icon-caret-right"
            type="primary"
            plain
            size="small"
            @click="isShowForward = true"
          >部门内转办</el-button
          >
          <el-button
            v-if="$route.query.flow_id"
            icon="el-icon-document-add"
            type="info"
            size="small"
            @click="submit('only-submit')"
          >暂存不流转</el-button
          >
          <el-button type="primary" size="small" @click="submit('assign')"
          >保存并流转 <i class="el-icon-right"></i
          ></el-button>
          <el-button
            v-if="!$route.query.flow_id"
            type="info"
            size="small"
            @click="$router.go(-1)"
          >返回</el-button
          >
        </template>
        <template v-else>
          <el-button
            plain
            size="small"
            @click="$router.go(-1)"
          >返回</el-button
          >
          <el-button
            plain
            size="small"
          >打印</el-button
          >
          <el-button
            plain
            size="small"
          >打印(带审批记录)</el-button
          >
          <el-button
            plain
            size="small"
          >下载附件</el-button
          >
        </template>
      </div>
    </el-card>

    <assign
      ref="assign"
      :visible.sync="isShowAssign"
      :config="config"
      :result="result"
    ></assign>

    <forward
      ref="forward"
      :is-show.sync="isShowForward"
      :flow="config.flow"></forward>

    <rollback ref="rollback"
              :is-show.sync="isShowRollback"
              :flow="config.flow"></rollback>

    <el-backtop></el-backtop>
  </div>
</template>

<script>
import DesktopForm from "./DesktopForm.vue";
import MobileForm from "./MobileForm.vue";
import assign from "./components/assign.vue";
import forward from "./components/forward.vue";
import rollback from "./components/rollback.vue";
import { create, deal, fieldConfig, preConfig, preDeal, view } from "@/api/flow";
import { deepCopy } from "@/utils";
import { validation, validationName } from "@/utils/validate";

export default {
  components: {
    DesktopForm,
    MobileForm,
    assign,
    forward,
    rollback,
  },
  data() {
    return {
      isShowRollback: false,
      isShowForward: false,
      isShowAssign: false,
      info: [],
      config: {},
      subConfig: new Map(),
      myStatus: new Map([
        [-2,'会签退回'],
        [-1,'退回'],
        [0, "办理中"],
        [1, "已完成"],
      ]),
      statusColor: new Map([
        [-2, "warning"],
        [-1, "warning"],
        [0, ""],
        [1, "success"],
      ]),

      form: {},
      result: {},
      fileList: {},
      rules: {}
    };
  },
  methods: {
    generateForm(object, fields) {
      this.rules = {}
      fields.forEach((field) => {
        if(field.rules && field.rules.length > 0) {
          this.rules[field.name] = field.rules.map(rule => {
            switch (rule) {
              case 'required':
                return { required: true, message: `请填写${field.label}`, trigger: 'blur' }
              default:
                return {
                  validator: (myRule, value, callback) => {
                    if(validation.get(rule).test(value)) {
                      callback()
                    } else {
                      callback(new Error(`${field.label}必须为${validationName.get(rule)}`))
                    }
                  },
                  trigger: 'blur'
                }
            }
          })
        }
        if (field.type === "file") {
          this.fileList[field.name] = [];
        }
        if (field.type === "relation") {
          object[field.name] = [{}];

          this.generateForm(
            object[field.name][0],
            this.subConfig.get(field.sub_custom_model_id)?.customModel?.fields
          );
        } else {
          object[field.name] = "";
        }
      });
    },
    formatTime(time) {
      const days = parseInt(time / (1000 * 60 * 60 * 24));
      const hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      const minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = (time % (1000 * 60)) / 1000;
      return `${days > 0 ? (days) + '天' : ''}${hours > 0 ? (hours) + '时' : ''}${minutes}分${seconds}秒`;
    },

    async getConfig() {
      const loading = this.$loading({
        lock: true,
        text: "拼命加载中",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.8)",
      });
      //路由为detail为详情
      if(/\/detail/.test(this.$route.path) && this.$route.query.flow_id) {
        try {
          const res = await view(this.$route.query.flow_id);
          console.log('view',res)
          const { fields } = res?.customModel;
          let subFormRequest = [];
          const getSubForm = (id) => {
            subFormRequest.push(fieldConfig(id));
          };
          fields.forEach((field) => {
            if (field.sub_custom_model_id) {
              getSubForm(field.sub_custom_model_id);
            }
          });
          const subConfigs = await Promise.all(subFormRequest);
          subConfigs.forEach((sub) => {
            if (sub.customModel?.id) {
              this.subConfig.set(sub.customModel?.id, sub);
            }
          });
          this.config = res;
          this.generateForm(this.form, fields);
          this.form = Object.assign({}, this.form);
          const { data } = res?.flow;
          for (let key in data) {
            try {
              let jsonObj = JSON.parse(data[key]);
              if (this.form.hasOwnProperty(key)) {
                this.form[key] = jsonObj;
              }
              if (this.fileList.hasOwnProperty(key)) {
                this.fileList[key] = jsonObj.map((i) => ({
                  name: i.name,
                  url: i.url,
                  response: i,
                }));
              }
            } catch (err) {
              if (this.form.hasOwnProperty(key)) {
                this.form[key] = data[key];
              }
            }
          }
          this.fileList = Object.assign({}, this.fileList);
          loading.close();
        } catch (err) {
          console.error(err);
          this.$message.error("配置失败");
          loading.close();
        }
      } else if (!this.$route.query.flow_id) {
        try {
          const res = await preConfig(this.$route.query.module_id);
          const { fields } = res?.customModel;
          let subFormRequest = [];
          const getSubForm = (id) => {
            subFormRequest.push(fieldConfig(id));
          };
          fields.forEach((field) => {
            if (field.sub_custom_model_id) {
              getSubForm(field.sub_custom_model_id);
            }
          });
          const subConfigs = await Promise.all(subFormRequest);
          subConfigs.forEach((sub) => {
            if (sub.customModel?.id) {
              this.subConfig.set(sub.customModel?.id, sub);
            }
          });
          this.config = res;
          this.generateForm(this.form, fields);
          this.form = Object.assign({}, this.form);
          loading.close();
        } catch (err) {
          console.error(err);
          this.$message.error("配置失败");
          loading.close();
        }
      } else {
        try {
          const res = await preDeal(this.$route.query.flow_id);
          const { fields } = res?.customModel;
          let subFormRequest = [];
          const getSubForm = (id) => {
            subFormRequest.push(fieldConfig(id));
          };
          fields.forEach((field) => {
            if (field.sub_custom_model_id) {
              getSubForm(field.sub_custom_model_id);
            }
          });
          const subConfigs = await Promise.all(subFormRequest);
          subConfigs.forEach((sub) => {
            if (sub.customModel?.id) {
              this.subConfig.set(sub.customModel?.id, sub);
            }
          });
          this.config = res;
          this.generateForm(this.form, fields);
          this.form = Object.assign({}, this.form);
          const { data } = res?.flow;
          for (let key in data) {
            try {
              let jsonObj = JSON.parse(data[key]);
              if (this.form.hasOwnProperty(key)) {
                this.form[key] = jsonObj;
              }
              if (this.fileList.hasOwnProperty(key)) {
                this.fileList[key] = jsonObj.map((i) => ({
                  name: i.name,
                  url: i.url,
                  response: i,
                }));
              }
            } catch (err) {
              if (this.form.hasOwnProperty(key)) {
                this.form[key] = data[key];
              }
            }
          }
          this.fileList = Object.assign({}, this.fileList);
          loading.close();
        } catch (err) {
          console.error(err);
          this.$message.error("配置失败");
          loading.close();
        }
      }
    },

    async submit(type) {
      let copyForm,copyFile;
      if (this.device === "desktop") {
        copyForm = deepCopy(this.$refs["desktopForm"].form);
        copyFile = deepCopy(this.$refs["desktopForm"].file);
      } else {
        copyForm = deepCopy(this.$refs["mobileForm"].form);
        copyFile = deepCopy(this.$refs["mobileForm"].file);
      }
      console.log(copyForm,copyFile)
      for (let [key, value] of Object.entries(copyFile)) {
        if (copyForm.hasOwnProperty(key)) {
          copyForm[key] = value.map((i) => i.response?.id)?.toString();
        }
      }
      copyForm["current_node_id"] = this.config.currentNode.id;

      try {
        let callback;
        switch (type) {
          case "only-submit":
            if (this.$route.query.flow_id) {
              copyForm["temporary_save"] = 1;
            }
            callback = () => this.$router.push("/flow/list/todo");
            break;
          case "assign":
            if (this.$route.query.flow_id) {
              copyForm["temporary_save"] = 0;
            }
            callback = () => (this.isShowAssign = true);
            break;
        }
        if (this.device === "desktop") {
          if(!await this.$refs['desktopForm'].validate()) return
        }
        if (this.$route.query.flow_id) {
          copyForm.id = this.$route.query.flow_id;
          const { flow, is_last_handled_log } = await deal(
            this.$route.query.flow_id,
            copyForm
          );
          this.result = flow;
          if(!is_last_handled_log) {
            await this.$alert('办理成功，其他会签办理完成后，由最后办理的成员流转到下一节点。','提示',{
              showClose: false,
            })
            callback = () => this.$router.push("/flow/list/todo");
          }
        } else {
          this.result = await create(this.$route.query.module_id, copyForm);
        }
        callback();
      } catch (err) {
        console.error(err);
      }
    },
  },
  computed: {
    device() {
      return this.$store.state.app.device;
    },
    fields() {
      return this.config?.customModel?.fields || [];
    },
    readableFields() {
      return /\/detail/.test(this.$route.path) ? this.fields?.map(i => i.id) : (this.config?.currentNode?.readable || []);
    },
    writeableFields() {
      return this.config?.currentNode?.writeable || [];
    },
    node() {
      return this.config?.currentNode || {};
    },
    scriptContent() {
      if (this.config?.customModel?.view_js && this.$route.query.flow_id) {
        return this.config?.customModel?.view_js;
      } else if (this.config?.customModel?.js && !this.$route.query.flow_id) {
        return this.config?.customModel?.js;
      }
    },
    diffTime() {
      return function (end,start) {
        const diff = this.$moment(end).diff(this.$moment(start))
        return this.formatTime(diff)
      }
    },
    footerData() {
      const diff = this.$moment(this.config?.logs?.at(-1)?.updated_at).diff(this.$moment(this.config?.logs?.at(0)?.created_at));
      return [
        {
          seq: "总耗时",
          'use_time': this.formatTime(diff),
        }
      ]
    },
  },
  created() {
    this.getConfig();
  },
  mounted() {},
};
</script>

<style scoped lang="scss">
::v-deep .el-card__header {
}
.container {
  padding: 20px;

  .card {
    position: relative;
  }
  .btns {
    display: flex;
    justify-content: center;
    margin-top: 10px;
    flex-wrap: wrap;
  }
}
.form-container {
}
@media (max-width: 768px) {
  .container {
    padding: 0;
  }
  .btns  {
    justify-content: space-evenly;
    & > * {
      margin: 4px 6px;
    }
  }
}
</style>
<style lang="scss">
.log-table-scroll {
  ::-webkit-scrollbar {
    height: 0;
  }
}
</style>
