<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    append-to-body
    :close-on-click-modal="false"
    width="80%"
    :before-close="handleClose"
  >
    <div class="result-param-layout">
      <el-card class="filter-panel" shadow="never">
        <div slot="header">
          <span>{{ $t(key('search')) }}</span>
          <el-button type="text" style="float:right;padding:3px 0" @click="onSearch">
            {{ $t(key('query')) }}
          </el-button>
        </div>
        <el-form label-position="top" :model="searchForm" size="mini">
          <el-form-item :label="$t(key('name'))">
            <el-input v-model.trim="searchForm.name" :placeholder="$t(key('enter_name'))" clearable />
          </el-form-item>
          <el-form-item :label="$t(key('param'))">
            <el-input v-model.trim="searchForm.code" :placeholder="$t(key('enter_param'))" clearable />
          </el-form-item>
        </el-form>
      </el-card>

      <div class="table-panel">
        <div class="table-actions">
          <el-button type="primary" size="mini" icon="el-icon-plus" @click="openBindDialog">
            {{ $t(key('add_result_param')) }}
          </el-button>
        </div>
        <el-table :data="tableData" v-loading="loading" border height="480">
          <el-table-column prop="name" :label="$t(key('name'))" width="220" show-overflow-tooltip />
          <el-table-column prop="code" :label="$t(key('param'))" width="180" show-overflow-tooltip />
          <el-table-column prop="field_type" :label="$t(key('category'))" width="140" />
          <el-table-column prop="remark" :label="$t(key('remark'))" show-overflow-tooltip />
        </el-table>
      </div>
    </div>

    <el-pagination
      style="margin-top:12px;text-align:right"
      :current-page="pagination.current"
      :page-size="pagination.size"
      :page-sizes="[10, 20, 50, 100]"
      :total="pagination.total"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="onSizeChange"
      @current-change="onCurrentChange"
    />

    <div slot="footer">
      <el-button @click="handleClose">{{ $t(key('close')) }}</el-button>
    </div>

    <el-dialog
      :title="$t(key('add_result_param'))"
      :visible.sync="bindVisible"
      append-to-body
      width="720px"
      :close-on-click-modal="false"
    >
      <el-alert :title="$t(key('result_param_bind_tip'))" type="warning" :closable="false" show-icon />
      <div class="bind-layout">
        <el-card class="bind-card" shadow="never">
          <div slot="header">
            <span>{{ $t(key('all_result_params')) }}</span>
            <el-button type="text" style="float:right;padding:3px 0">{{ checkedCount }} / {{ leftParams.length }}</el-button>
          </div>
          <el-tree
            ref="leftTree"
            :data="leftParams"
            show-checkbox
            node-key="code"
            accordion
            :check-strictly="true"
            :default-checked-keys="defaultCheckedKeys"
            :props="treeProps"
            @check="onTreeCheck"
          />
        </el-card>
        <div class="bind-arrow">
          <el-button type="primary" icon="el-icon-arrow-right" circle @click="syncRightParams" />
        </div>
        <el-card class="bind-card" shadow="never">
          <div slot="header">
            <span>{{ $t(key('selected_result_params')) }}</span>
            <el-button type="text" style="float:right;padding:3px 0">{{ rightParams.length }}</el-button>
          </div>
          <el-tree :data="rightParams" node-key="code" :props="treeProps" />
        </el-card>
      </div>
      <span slot="footer">
        <el-button size="mini" @click="bindVisible = false">{{ $t(key('cancel')) }}</el-button>
        <el-button size="mini" type="primary" @click="submitBindParams">{{ $t(key('submit')) }}</el-button>
      </span>
    </el-dialog>
  </el-dialog>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import {
  getOptionalParamsDetails,
  getAllWorkingsubclassParams,
  addOptionalParams
} from '@/api/production-master-data/process-routing-card'

function readListData (res) {
  const data = res && res.data ? res.data : res
  if (!data) return { list: [], total: 0 }
  if (Array.isArray(data)) return { list: data, total: data.length }
  const list = data.data || data.list || []
  return { list: Array.isArray(list) ? list : [], total: Number(data.count || data.total || list.length || 0) }
}

export default {
  name: 'ProcessRoutingCardResultParam',
  mixins: [i18nMixin('page.production_master_data.process_model.process_routing.card')],
  props: {
    title: { type: String, default: '' },
    visible: { type: Boolean, default: false },
    workingsubclassId: { type: [String, Number], default: '' },
    flowProcessId: { type: [String, Number], default: '' }
  },
  data () {
    return {
      loading: false,
      tableData: [],
      searchForm: { name: '', code: '' },
      pagination: { current: 1, size: 10, total: 0 },
      bindVisible: false,
      leftParams: [],
      rightParams: [],
      defaultCheckedKeys: [],
      selectedCodes: [],
      changed: false,
      treeProps: { children: 'children', label: 'label' }
    }
  },
  computed: {
    checkedCount () {
      return this.selectedCodes.length
    }
  },
  watch: {
    visible (val) {
      if (val) this.fetchData(true)
    },
    flowProcessId (val) {
      if (val && this.visible) this.fetchData(true)
    }
  },
  methods: {
    handleClose () {
      this.pagination.current = 1
      this.pagination.size = 10
      this.$emit('close')
    },
    onSearch () {
      this.fetchData(true)
    },
    onSizeChange (size) {
      this.pagination.size = size
      this.fetchData(true)
    },
    onCurrentChange (current) {
      this.pagination.current = current
      this.fetchData(false)
    },
    async fetchData (resetPage = false) {
      if (!this.flowProcessId) return
      if (resetPage) this.pagination.current = 1
      this.loading = true
      try {
        const res = await getOptionalParamsDetails({
          page_no: this.pagination.current,
          page_size: this.pagination.size,
          process_id: this.flowProcessId,
          ...this.searchForm
        })
        const { list, total } = readListData(res)
        this.tableData = list
        this.pagination.total = total
      } finally {
        this.loading = false
      }
    },
    async openBindDialog () {
      if (!this.flowProcessId) return
      const res = await getAllWorkingsubclassParams({ process_id: this.flowProcessId })
      const data = res && res.data ? res.data : res || {}
      this.leftParams = data.left_optional_params || []
      this.rightParams = data.right_optional_params || []
      this.defaultCheckedKeys = data.default_checked_keys || []
      this.selectedCodes = [...this.defaultCheckedKeys]
      this.changed = false
      this.bindVisible = true
    },
    onTreeCheck () {
      this.selectedCodes = this.$refs.leftTree ? this.$refs.leftTree.getCheckedKeys() : []
      this.changed = true
    },
    syncRightParams () {
      const checked = this.$refs.leftTree ? this.$refs.leftTree.getCheckedNodes() : []
      this.rightParams = checked.map(item => ({ ...item }))
      this.changed = true
    },
    async submitBindParams () {
      if (!this.changed) {
        this.$message.error(this.$t(this.key('please_select_param')))
        return
      }
      await addOptionalParams({
        process_id: this.flowProcessId,
        optional_params: JSON.stringify(this.rightParams)
      })
      this.$message.success(this.$t(this.key('operation_success')))
      this.bindVisible = false
      this.fetchData(true)
    }
  }
}
</script>

<style scoped>
.result-param-layout,
.bind-layout {
  display: flex;
  gap: 16px;
}
.filter-panel {
  width: 220px;
  flex: none;
}
.table-panel {
  flex: 1;
  min-width: 0;
}
.table-actions {
  margin-bottom: 10px;
}
.bind-card {
  width: 300px;
  min-height: 360px;
}
.bind-arrow {
  display: flex;
  align-items: center;
}
</style>
