<template>
  <a-skeleton v-if="loading" :paragraph="{ rows: 5 }" />
  <a-card v-else>
    <a-table
      ref="processinfoTable"
      :columns="columns"
      :row-key="(record, index) => record.dispindex"
      size="middle"
      :expanded-row-keys="expandedRowKeys"
      :data-source="dispLogInfo"
      children-column-name="subFlowLogInfo"
      :indent-size="10"
      :pagination="false"
      :class="hasChildren ? $style.hasSub : ''"
      @expandedRowsChange="(keys) => (expandedRowKeys = keys)"
    >
      <template slot="currentStep" slot-scope="text, record">
        <span :class="record.isactive && record.level === 0 ? $style.setactivefont : ''">
          {{ record.stepName }}
          <a-icon
            v-if="record.props && record.props.source === 'GRCMobileV5'"
            type="mobile"
            title="移动端审批"
          />
          <span v-if="record.subFlowLogInfoOpen && record.subFlowLogInfoOpen.length">
            <a
              @click="
                visible = true
                subFlowLogInfo = record.subFlowLogInfoOpen
              "
            >
              &nbsp;流程跟踪</a
            >&nbsp;
            <!-- 有subInstId且为不0时显示 -->
            <a
              v-if="getSubFlowInstId(record)"
              :href="`#/sd-webflow/done-pages/${getSubFlowInstId(record)}`"
              target="_blank"
              rel="opener"
              >查看文档</a
            >
          </span>
          <span v-else-if="record.subFlowLogInfo && record.subFlowLogInfo.length">
            <a
              v-if="getSubFlowInstId(record)"
              :href="`#/sd-webflow/done-pages/${getSubFlowInstId(record)}`"
              target="_blank"
              rel="opener"
              >&nbsp;查看文档</a
            >
          </span>
        </span>
      </template>
      <template slot="operator" slot-scope="text, record">
        <OperatorView
          :record="record"
          :class="[
            $style.operator,
            record.isactive && record.level === 0 ? $style.setactivefont : '',
          ]"
        />
      </template>
      <template slot="finishDate" slot-scope="text, record">
        <span :class="record.isactive && record.level === 0 ? $style.setactivefont : ''">
          {{ record.finishDate | sdDateFormat('YYYY-MM-DD HH:mm') }}</span
        >
      </template>
      <template slot="startDate" slot-scope="text, record">
        <span :class="record.isactive && record.level === 0 ? $style.setactivefont : ''">
          {{ record.startDate | sdDateFormat('YYYY-MM-DD HH:mm') }}</span
        >
      </template>
      <template slot="status" slot-scope="text, record">
        <span :class="record.isactive && record.level === 0 ? $style.setactivefont : ''">
          {{
            record.isactive
              ? record.status || record.actionName
              : record.props.LogType
              ? record.props.actionName
              : '已处理'
          }}</span
        >
      </template>

      <template slot="actionName" slot-scope="text, record">
        <span :class="record.isactive && record.level === 0 ? $style.setactivefont : ''">
          <span>{{ sdGet(record, 'props?.actionName') || record.actionName }}</span>
        </span>
        <ActionSuffix :record="record" :class="$style.actionSuffix" />
      </template>
      <template slot="processTime" slot-scope="text, record">
        {{ parseProcessTime(record.processTime) }}
      </template>
    </a-table>

    <a-modal
      destroy-on-close
      title="流程跟踪"
      :visible="visible"
      :footer="null"
      :width="1200"
      @cancel="visible = false"
    >
      <sd-process-info
        :process-log-info="subFlowLogInfo"
        :process-active-log-info="subFlowActiveLogInfos"
      ></sd-process-info>
    </a-modal>
  </a-card>
</template>

<script>
import cloneDeep from 'lodash.clonedeep'
import storeMixin from '@/common/store-mixin'
import SdUserItem from '@/common/components/sd-user-item.vue'
import components from './_import-components/sd-process-info-import'

const columns = [
  {
    title: '处理环节',
    dataIndex: 'currentStep',
    scopedSlots: { customRender: 'currentStep' },
  },
  {
    title: '处理人',
    dataIndex: 'operator',
    scopedSlots: { customRender: 'operator' },
    width: '15%',
  },
  {
    title: '处理状态',
    dataIndex: 'status',
    scopedSlots: { customRender: 'status' },
    width: '100px',
  },
  {
    title: '接收时间',
    dataIndex: 'startDate',
    scopedSlots: { customRender: 'startDate' },
  },
  {
    title: '处理时间',
    dataIndex: 'finishDate',
    scopedSlots: { customRender: 'finishDate' },
  },
  {
    title: '后续环节/操作',
    dataIndex: 'actionName',
    width: '20%',
    scopedSlots: { customRender: 'actionName' },
  },
  {
    title: '用时',
    dataIndex: 'processTime',
    scopedSlots: { customRender: 'processTime' },
  },
  {
    title: '审核要素',
    dataIndex: 'auditElement',
    customRender: (text, record, index) => {
      if (record.isactive) {
        return ''
      }
      return record.props.auditContent || ''
    },
  },
]

const ActionSuffix = {
  props: {
    record: {
      type: Object,
      default: undefined,
    },
  },
  render() {
    // 获取下一环节处理人
    let users = []
    const props = this.record?.props || {}
    // props中有_skip_actors_is_null且无_skip_actors_is_null_actionId时，表示为空自动跳过环节，不拼接处理人；
    if (!props._skip_actors_is_null || props._skip_actors_is_null_actionId) {
      const stepCount = Number(props.successorsCount) || 0
      for (let i = 0; i < stepCount; i++) {
        const operatorCount = Number(props[`successorsStep${i}OperatorCount`]) || 0
        for (let j = 0; j < operatorCount; j++) {
          const propPrefix = `successorsStep${i}Operator${j}`
          const itemCode = props[`${propPrefix}Code`]
          const itemName = props[`${propPrefix}Name`]
          const itemUserType = props[`${propPrefix}Type`]
          if (['Role', 'Function', 'UserList'].includes(itemUserType)) {
            const sUser = props[`${propPrefix}Users`]
            if (sUser) {
              try {
                const oUsers = JSON.parse(sUser)
                users = users.concat(
                  oUsers.map((user) => ({
                    code: user.code || user.account,
                    name: user.name,
                    usertype: 'User',
                  }))
                )
              } catch {}
            }
          } else {
            users.push({
              code: itemCode,
              name: itemName,
              usertype: itemUserType,
            })
          }
        }
      }
    }
    let prefix = ''
    // 操作干预时，显示环节名称（直接取第一个环节名称）
    if (this.record.actionId === 'intervene' && props.successorsStep0StepName) {
      prefix = props.actionName ? '' : ': ' + props.successorsStep0StepName
    }
    return users.length > 0 ? (
      <span>
        {prefix}(
        {users.map((user) => {
          if (user.usertype === 'User') {
            return (
              <span class='user-item'>
                <SdUserItem users={[user]} />
              </span>
            )
          } else {
            return <span class='user-item'>{user.name}</span>
          }
        })}
        )
      </span>
    ) : prefix ? (
      <span>{prefix}</span>
    ) : (
      ''
    )
  },
}

const OperatorView = {
  props: {
    record: {
      type: Object,
      default: undefined,
    },
  },
  computed: {
    users() {
      const fmtUsers = [] // 主办(委托人)
      const dbUsers = [] // 代办(被委托人)
      // 区分主办和代办
      this.record?.users?.forEach((u) => {
        if (u.trustType === 1) {
          dbUsers.push(u)
        } else {
          fmtUsers.push(u)
        }
      })
      // 将代办人合并至主办人
      if (dbUsers.length > 0) {
        // 嵌套委托：a委托给b，b委托给c，在委托人中找不到c的委托人，c的委托人在被委托人列表中
        // 1. 先在被委托人列表中梳理委托关系
        dbUsers.reverse()
        dbUsers.forEach((u) => {
          const tmpU = dbUsers.find((_) => _.account === u.trustor)
          if (tmpU) {
            // 找到了委托人，合并 且 标记当前为无效
            if (tmpU.dbUsers?.length) {
              tmpU.dbUsers.push(u)
            } else {
              tmpU.dbUsers = [u]
            }
            u.delete = true
          }
        })
        // 2. 将被委托人追加至委托人列表中
        dbUsers
          .filter((_) => !_.delete)
          .forEach((u) => {
            const user = fmtUsers.find((_) => _.account === u.trustor)
            if (user) {
              if (user.dbUsers?.length) {
                user.dbUsers.push(u)
              } else {
                user.dbUsers = [u]
              }
            }
          })
      }
      return fmtUsers
    },
  },
  render() {
    const dbUsersView = (dbUsers) => {
      if (dbUsers?.length > 0) {
        return dbUsers.map((_) => {
          return (
            <span class='user-item'>
              (
              <SdUserItem users={[{ code: _.account, name: _.name }]} />
              {dbUsersView(_.dbUsers)})
            </span>
          )
        })
      }
      return ''
    }
    const userView = (
      <span class='users'>
        {this.users.length > 0
          ? this.users.map((u) => (
              <span class='user-item'>
                <SdUserItem users={[{ code: u.account, name: u.name }]} />
                {dbUsersView(u.dbUsers)}
              </span>
            ))
          : ''}
      </span>
    )
    if (this.record.isactive) {
      if (['UserList', 'User'].includes(this.record.operatorType)) {
        return (
          <span>
            {this.users.length > 0 ? (
              userView
            ) : (
              <SdUserItem
                users={[{ code: this.record.operatorCode, name: this.record.operator }]}
              />
            )}
          </span>
        )
      } else {
        if (this.record.type === '子流程') {
          return (
            <span>
              {this.record.operator}
              {this.users.length > 0 ? <span>({userView})</span> : ''}
            </span>
          )
        } else {
          return <span>{this.users.length > 0 ? userView : ''}</span>
        }
      }
    } else {
      if (this.record.operator) {
        // 空处理人路过环节：props中有_skip_actors_is_null且无_skip_actors_is_null_actionId
        const isEmptyHandlerSkip =
          this.record.props._skip_actors_is_null && !this.record.props._skip_actors_is_null_actionId
        if (this.record.props?._operatorType === 'User') {
          return (
            <span>
              {isEmptyHandlerSkip ? (
                this.record.operator
              ) : (
                <SdUserItem
                  users={[{ code: this.record.operatorAccount, name: this.record.operator }]}
                />
              )}
              {this.record.trustor ? (
                <span class='trustor'>
                  <SdUserItem
                    users={[
                      {
                        code: this.record.trustor || this.record.operatorAccount,
                        name: this.record.trustorName || this.record.operator,
                      },
                    ]}
                  />
                </span>
              ) : (
                ''
              )}
            </span>
          )
        } else {
          return (
            <span>
              {isEmptyHandlerSkip ? (
                this.record.operator
              ) : (
                <SdUserItem
                  users={[{ code: this.record.operatorAccount, name: this.record.operator }]}
                />
              )}
            </span>
          )
        }
      }
    }
    return ''
  },
}

export default {
  name: 'SdProcessInfo',
  components: {
    ...components,
    ActionSuffix,
    OperatorView,
  },
  mixins: [storeMixin],
  props: {
    processLogInfo: {
      type: Array,
      default: undefined,
    },
    processActiveLogInfo: {
      type: Array,
      default: undefined,
    },
  },
  data() {
    return {
      subFlowLogInfo: [],
      visible: false,
      subFlowActiveLogInfos: [],
      loading: true,
      columns,
      expandedRowKeys: [],
    }
  },
  inject: {
    webflow: { default: () => {} },
  },
  computed: {
    _processLogInfo() {
      return this.filterSubFlowEndNode(
        cloneDeep(this.processLogInfo || this.webflow.FlowData.processLogInfo || [])
      )
    },
    _processActiveLogInfo() {
      return this.filterSubFlowEndNode(
        cloneDeep(this.processActiveLogInfo || this.webflow.FlowData.processActiveLogInfo || [])
      )
    },
    dispLogInfo() {
      // 给活动流程记录作标记  显示状态用
      let myloginfo = this._processLogInfo.concat(
        this.setLogActiveState(cloneDeep(this._processActiveLogInfo), true)
      )
      //  设置流转记录在列表上的key值,同时合并 subFlowActiveLogInfos 到 subFlowLogInfo
      myloginfo = this.setLogDispIndex(myloginfo, 0)
      // 处理人员会签的记录，仅显示符合条件的子记录，本记录不显示，子记录提升一级显示，
      myloginfo = this.resetLoginfo(myloginfo)
      // 标记结果记录的层级标识  用于样式控制
      myloginfo = this.setLogLevel(myloginfo, 0)
      //  从第四级起（相当于子流程第三级，level=2项的子流程）不再自动按子表展示，改用弹窗显示子流程，所以将相应子流程数据更改为其他名称，防止table自动按子表展示
      myloginfo = this.setOpenSubinfo(myloginfo)
      return myloginfo
    },
    hasChildren() {
      // @ts-ignore
      return (this.dispLogInfo || []).findIndex((item) => item.subFlowLogInfo?.length) !== -1
    },
  },
  watch: {
    dispLogInfo(newVal) {
      this.setDefaultExpandNode(newVal)
    },
  },
  mounted() {
    this.webflow.getLog('process').then(() => {
      this.loading = false
      this.setDefaultExpandNode(this.dispLogInfo)
    })
  },
  methods: {
    getSubFlowInstId(record) {
      if (record.isactive) {
        return record.subFlowinstId
      } else {
        return record.subInstId
      }
    },
    parseProcessTime(processTime) {
      if (processTime) {
        try {
          processTime = JSON.parse(processTime)
          const day = processTime.day
          const hour = processTime.hour
          const minute = processTime.minute
          if (day === 0 && hour === 0 && minute === 0) {
            return '小于1分钟'
          }
          return (
            (day === 0 ? '' : day + '天') +
            (hour === 0 ? '' : hour + '小时') +
            (minute === 0 ? '' : minute + '分钟')
          )
        } catch {
          return '-'
        }
      } else {
        return '-'
      }
    },
    // 给处理中的流程记录做状态标记 isactive  根据此标记在表格中显示字体为兰色 但其中的subFlowLogInfo 为已完成 状态
    setLogActiveState(activeloginfo, isactive) {
      return activeloginfo.map((item) => {
        item.isactive = isactive
        if (item.subFlowLogInfo?.[0]) {
          item.subFlowLogInfo = this.setLogActiveState(item.subFlowLogInfo, false)
        }
        if (item.subFlowActiveLogInfos?.[0]) {
          item.subFlowActiveLogInfos = this.setLogActiveState(item.subFlowActiveLogInfos, true)
        }
        return item
      })
    },
    // 设置流转记录在列表上的key值,同时合并 subFlowActiveLogInfos 到 subFlowLogInfo
    setLogDispIndex(loginfo, preindex) {
      loginfo.forEach((element, index) => {
        element.dispindex = preindex + '-' + index
        // 先合并 subFlowActiveLogInfos到 subFlowLogInfo
        if (element.subFlowActiveLogInfos) {
          if (element.subFlowLogInfo) {
            element.subFlowLogInfo = element.subFlowLogInfo.concat(element.subFlowActiveLogInfos)
          } else {
            element.subFlowLogInfo = element.subFlowActiveLogInfos
          }
          element.subFlowActiveLogInfos = null
        }

        if (element.subFlowLogInfo) {
          if (element.subFlowLogInfo.length > 0) {
            element.subFlowLogInfo = this.setLogDispIndex(element.subFlowLogInfo, element.dispindex)
          } else {
            element.subFlowLogInfo = null
          }
        }
      })
      return loginfo
    },
    // 人员会签的记录提升一级，不再显示为子表样式(一步签：开始->结束)
    resetLoginfo(loginfo) {
      const needUplist = []
      loginfo.forEach((element, index) => {
        if (element.subFlowLogInfo) {
          // 人员签(isFromUserCountersign=true，处理中的直接在当前记录中，处理完成的在子流程的流转记录中) 且 只有1条流转记录（流程结束的记录已经被过滤掉了）
          const isPsnHQ =
            element.subFlowLogInfo.length === 1 &&
            (element.operatorAttrs?.isFromUserCountersign === 'true' ||
              element.subFlowLogInfo[0].operatorAttrs?.isFromUserCountersign === 'true')
          if (isPsnHQ) {
            // 重置排序号、处理环节名称
            Object.assign(element.subFlowLogInfo[0], {
              dispindex: element.dispindex,
              stepName: element.stepName,
              actionName: element.actionName,
              props: element.props,
            })
            needUplist.push(element.subFlowLogInfo[0])
            element.subFlowLogInfo = null
            // 此条主记录不再显示
            element.delete = 1
          } else {
            element.subFlowLogInfo = this.resetLoginfo(element.subFlowLogInfo)
          }
        }
      })
      loginfo = loginfo.concat(needUplist).filter((item) => {
        return (
          item.delete !== 1 &&
          ((item.actionId && item.actionId.substring(0, 4) !== 'save') || !item.actionId)
        )
      })
      loginfo = loginfo.sort((a, b) => {
        const value1 = a.dispindex.split('-')
        const value2 = b.dispindex.split('-')
        return Number(value1[value1.length - 1]) - Number(value2[value2.length - 1])
      })
      return loginfo
    },
    // 设置流转记录分级标识  从0开始
    setLogLevel(loginfo, level) {
      loginfo.forEach((element, index) => {
        element.level = level
        if (element.subFlowLogInfo?.[0]) {
          element.subFlowLogInfo = this.setLogLevel(element.subFlowLogInfo, level + 1)
        }
      })
      return loginfo
    },
    // 设置默认展开的节点
    setDefaultExpandNode(logInfos) {
      logInfos.forEach((item) => {
        // 有子节点
        if (item.subFlowLogInfo?.[0]) {
          if (this.expandedRowKeys.indexOf(item.dispindex) === -1) {
            this.expandedRowKeys.push(item.dispindex)
          }
          this.setDefaultExpandNode(item.subFlowLogInfo)
        }
      })
    },
    // 从从第四级起 （子流程第三级）level=2的项的子流程不再自动，所以将子流程数据 更改为其他名称 ，防止table自动按子表展示
    setOpenSubinfo(loginfo) {
      loginfo.forEach((element, index) => {
        if (element.level === 2) {
          // 沟通记录的table自动按子表展示(全部展示，可折叠展开)
          if (element.subFlowLogInfo && !element.props?.LogType) {
            element.subFlowLogInfoOpen = element.subFlowLogInfo
            element.subFlowLogInfo = null
          }
        } else {
          if (element.subFlowLogInfo) {
            element.subFlowLogInfo = this.setOpenSubinfo(element.subFlowLogInfo)
          }
        }
      })
      return loginfo
    },
    // 过滤掉子流程中的流程结束的流转记录
    filterSubFlowEndNode(logs) {
      logs.map((log) => {
        if (log.subFlowLogInfo?.[0]) {
          log.subFlowLogInfo = this.filterSubFlowEndNode(log.subFlowLogInfo)
        }
        return log
      })
      // 需要过滤，过滤掉流程结束环节
      return logs.filter((log) => {
        return log.actionId || log.stepType !== '结束'
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
@use '@/common/components/sd-web-print.scss' as print;

.setactivefont {
  color: $processing-color;
}
.has-sub {
  th:first-child {
    :global(.ant-table-header-column) {
      margin-left: 25px;
    }
  }
}
.action-suffix {
  :global(.user-item) {
    &:not(:last-child)::after {
      content: ' , ';
    }
  }
}
.operator {
  :global(.users .user-item) {
    &:not(:last-child)::after {
      content: ' , ';
    }
  }
  :global(.trustor) {
    &::before {
      content: ' (代';
    }
    &::after {
      content: ')';
    }
  }
}
</style>
