<template>
  <el-dialog :visible.sync="visibleProxy" append-to-body :close-on-click-modal="false" fullscreen :show-close="false" @open="bootstrap">
    <template #title>
      <div class="dialog-title">
        <span>{{ relationshipTitle }}</span>
        <el-button size="small" @click="handleClose">{{ $t(key('return')) }}</el-button>
      </div>
    </template>

    <el-row class="relationship-layout">
      <el-col :span="4" class="step-panel">
        <el-menu :default-active="activeStep" @select="handleStepSelect">
          <el-menu-item v-for="item in stepOptions" :key="item.code" :index="item.code">
            <span slot="title">{{ item.name }}</span>
          </el-menu-item>
        </el-menu>
      </el-col>
      <el-col :span="20" class="relation-panel">
        <el-card shadow="never" class="relation-card relation-card-in">
          <div slot="header" class="card-header">
            <span>IN</span>
            <div>
              <el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteSelected('in')">{{ $t(key('delete')) }}</el-button>
              <el-button size="mini" type="success" icon="el-icon-plus" @click="openMaterialDialog('in')">{{ $t(key('add')) }}</el-button>
            </div>
          </div>
          <el-table ref="inTable" :data="inData" border height="360" v-loading="loading" @selection-change="inSelection = $event">
            <el-table-column type="selection" width="48" />
            <el-table-column prop="bom_source_category_name" :label="$t(key('material_category'))" width="120" />
            <el-table-column prop="bom_source_code" :label="$t(key('material_code'))" min-width="180" show-overflow-tooltip />
            <el-table-column prop="bom_source_name" :label="$t(key('material_name'))" min-width="180" show-overflow-tooltip />
            <el-table-column :label="$t(key('input_quantity'))" width="180">
              <template slot-scope="{ row }">
                <el-input v-model="row.input_quantity" size="mini" @blur="saveQuantity(row)" />
              </template>
            </el-table-column>
            <el-table-column prop="unit_name" :label="$t(key('unit'))" width="100" />
            <el-table-column :label="$t(key('operation'))" width="100">
              <template slot-scope="{ row }">
                <el-button type="text" size="mini" style="color:#F56C6C" @click="deleteRows([row])">{{ $t(key('delete')) }}</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <el-card shadow="never" class="relation-card">
          <div slot="header" class="card-header">
            <span>OUT</span>
            <div>
              <el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteSelected('out')">{{ $t(key('delete')) }}</el-button>
              <el-button size="mini" type="success" icon="el-icon-plus" @click="openMaterialDialog('out')">{{ $t(key('add')) }}</el-button>
            </div>
          </div>
          <el-table ref="outTable" :data="outData" border height="250" v-loading="loading" @selection-change="outSelection = $event">
            <el-table-column type="selection" width="48" />
            <el-table-column prop="bom_source_category_name" :label="$t(key('material_category'))" width="120" />
            <el-table-column prop="bom_source_code" :label="$t(key('material_code'))" min-width="180" show-overflow-tooltip />
            <el-table-column prop="bom_source_name" :label="$t(key('material_name'))" min-width="180" show-overflow-tooltip />
            <el-table-column prop="unit_name" :label="$t(key('unit'))" width="140" />
            <el-table-column :label="$t(key('operation'))" width="100">
              <template slot-scope="{ row }">
                <el-button type="text" size="mini" style="color:#F56C6C" @click="deleteRows([row])">{{ $t(key('delete')) }}</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-card>
      </el-col>
    </el-row>

    <el-dialog :title="$t(key('select_add_material'))" :visible.sync="materialVisible" append-to-body width="820px" :close-on-click-modal="false" @open="loadMaterials(true)">
      <el-form :inline="true" size="mini" @submit.native.prevent>
        <el-form-item>
          <el-radio-group v-model="materialOnlySelected" @change="loadMaterials(true)">
            <el-radio-button :label="false">{{ $t(key('all')) }}</el-radio-button>
            <el-radio-button :label="true">{{ $t(key('selected')) }}</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item>
          <el-button-group>
            <el-button @click="changeMaterialCategory('')">{{ $t(key('all')) }}</el-button>
            <el-button v-for="item in materialCategories" :key="item.id" @click="changeMaterialCategory(item.id)">{{ item.name }}</el-button>
          </el-button-group>
        </el-form-item>
        <el-form-item>
          <el-input v-model.trim="materialSearch.all" :placeholder="$t(key('search_by_code_or_name'))" clearable style="width:220px" @keyup.enter.native="loadMaterials(true)">
            <el-button slot="append" icon="el-icon-search" @click="loadMaterials(true)" />
          </el-input>
        </el-form-item>
      </el-form>
      <el-table ref="materialTable" :data="materialData" border height="380" row-key="id" @selection-change="materialSelection = $event">
        <el-table-column type="selection" reserve-selection width="50" />
        <el-table-column prop="bom_source_category_name" :label="$t(key('material_category'))" width="130" />
        <el-table-column prop="code" :label="$t(key('material_code'))" min-width="150" show-overflow-tooltip />
        <el-table-column prop="name" :label="$t(key('material_name'))" min-width="150" show-overflow-tooltip />
        <el-table-column prop="remark" :label="$t(key('remark'))" show-overflow-tooltip />
      </el-table>
      <el-pagination class="material-pagination" :current-page="materialPagination.current" :page-size="materialPagination.size" :total="materialPagination.total" layout="total, prev, pager, next" @current-change="onMaterialPageChange" />
      <span slot="footer">
        <el-button size="small" @click="materialVisible = false">{{ $t(key('cancel')) }}</el-button>
        <el-button size="small" type="primary" @click="confirmMaterialSelection">{{ $t(key('confirm')) }}</el-button>
      </span>
    </el-dialog>
  </el-dialog>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import { getWorkingsubclassAll } from '@/api/production-master-data/process-step'
import { getMaterialCategoryAll } from '@/api/production-master-data/material-category'
import { getMaterialMasterList } from '@/api/production-master-data/material-master'
import { getBomRelationshipList, createBomRelationship, editBomRelationship, deleteBomRelationship } from '@/api/production-master-data/bill-of-materials'

function readPageData (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 }
  return { list: data.data || data.list || [], total: Number(data.count || data.total || 0) }
}

export default {
  name: 'BomRelationship',
  mixins: [i18nMixin('page.production_master_data.material_model.bill_of_materials')],
  props: {
    visible: { type: Boolean, default: false },
    bom: { type: Object, default: () => ({}) }
  },
  data () {
    return {
      loading: false,
      stepOptions: [],
      materialCategories: [],
      activeStep: '',
      inData: [],
      outData: [],
      inSelection: [],
      outSelection: [],
      materialVisible: false,
      materialDirection: 'in',
      materialCategoryId: '',
      materialOnlySelected: false,
      materialSearch: { all: '' },
      materialData: [],
      materialSelection: [],
      materialPagination: { current: 1, size: 10, total: 0 }
    }
  },
  computed: {
    visibleProxy: {
      get () { return this.visible },
      set (val) { this.$emit('update:visible', val) }
    },
    relationshipTitle () {
      return this.bom && this.bom.name ? `【${this.bom.name}】${this.$t(this.key('bom_management'))}` : this.$t(this.key('bom_management'))
    },
    currentCheckList () {
      return this.materialDirection === 'in' ? this.inData : this.outData
    }
  },
  methods: {
    async bootstrap () {
      this.inData = []
      this.outData = []
      this.stepOptions = []
      const [steps, categories] = await Promise.all([getWorkingsubclassAll({}), getMaterialCategoryAll({})])
      this.stepOptions = (steps && steps.data) || steps || []
      this.materialCategories = (categories && categories.data) || categories || []
      this.activeStep = this.stepOptions.length ? this.stepOptions[0].code : ''
      if (this.activeStep) this.loadRelationship()
    },
    handleClose () {
      this.visibleProxy = false
      this.$emit('saved')
    },
    handleStepSelect (key) {
      this.activeStep = key
      this.loadRelationship()
    },
    async loadRelationship () {
      if (!this.bom.id || !this.activeStep) return
      this.loading = true
      try {
        const res = await getBomRelationshipList({ product_bom_id: this.bom.id, workingsubclass_in: this.activeStep, workingsubclass_out: this.activeStep })
        const data = (res && res.data) || res || {}
        this.inData = data.in || []
        this.outData = data.out || []
      } finally {
        this.loading = false
      }
    },
    openMaterialDialog (direction) {
      this.materialDirection = direction
      this.materialOnlySelected = false
      this.materialCategoryId = ''
      this.materialSearch = { all: '' }
      this.materialPagination.current = 1
      this.materialVisible = true
    },
    changeMaterialCategory (categoryId) {
      this.materialCategoryId = categoryId
      this.loadMaterials(true)
    },
    async loadMaterials (resetPage = false) {
      if (resetPage) this.materialPagination.current = 1
      this.$nextTick(() => this.$refs.materialTable && this.$refs.materialTable.clearSelection())
      const idList = this.currentCheckList.map(item => item.bom_source_id).filter(Boolean)
      if (this.materialOnlySelected && this.materialSelection.length === 0) {
        this.materialData = []
        this.materialPagination.total = 0
        return
      }
      const selectedId = this.materialOnlySelected ? this.materialSelection.map(item => item.id) : undefined
      const res = await getMaterialMasterList({
        bom_source_category_id: this.materialCategoryId,
        idList,
        selected_id: selectedId,
        all: this.materialSearch.all,
        page_no: this.materialPagination.current,
        page_size: this.materialPagination.size
      })
      const { list, total } = readPageData(res)
      this.materialData = list
      this.materialPagination.total = total
    },
    onMaterialPageChange (page) {
      this.materialPagination.current = page
      this.loadMaterials(false)
    },
    async confirmMaterialSelection () {
      const relationData = this.materialSelection.map(item => ({ bom_source_id: item.id }))
      if (this.materialDirection === 'in') {
        const duplicates = relationData.filter(next => this.inData.some(old => old.bom_source_id === next.bom_source_id))
        if (duplicates.length) {
          this.$message.warning(this.$t(this.key('duplicate_material_selected')))
          return
        }
      } else if (this.outData.length !== 0 || relationData.length > 1) {
        this.$message.warning(this.$t(this.key('out_only_one')))
        return
      }
      await createBomRelationship({
        bom_id: this.bom.id,
        type: this.materialDirection === 'in' ? 'in_workingsubclass' : 'out_workingsubclass',
        workingsubclass: this.activeStep,
        relation_data: relationData
      })
      this.materialVisible = false
      this.$message.success(this.$t(this.key('operation_success')))
      this.loadRelationship()
    },
    async saveQuantity (row) {
      await editBomRelationship(row)
      this.$message.success(this.$t(this.key('operation_success')))
      this.loadRelationship()
    },
    deleteSelected (direction) {
      const rows = direction === 'in' ? this.inSelection : this.outSelection
      if (!rows.length) {
        this.$message.warning(this.$t(this.key('please_select_data')))
        return
      }
      this.deleteRows(rows)
    },
    async deleteRows (rows) {
      await deleteBomRelationship({ id: rows.map(item => item.id) })
      this.$message.success(this.$t(this.key('operation_success')))
      this.loadRelationship()
    }
  }
}
</script>

<style scoped>
.dialog-title { display: flex; justify-content: space-between; align-items: center; padding: 0 20px; }
.relationship-layout { border-top: 1px solid #dcdfe6; }
.step-panel { height: calc(100vh - 100px); overflow: auto; border-right: 1px solid #ebeef5; }
.relation-panel { height: calc(100vh - 100px); overflow: auto; padding: 16px; }
.relation-card { margin-bottom: 12px; }
.relation-card-in { min-height: 430px; }
.card-header { display: flex; align-items: center; justify-content: space-between; }
.material-pagination { margin-top: 12px; text-align: right; }
/deep/ .el-dialog__body { padding: 0; }
</style>
