<template>
  <d2-container>
    <template #header>
      <div class="search-bar">
        <el-form :inline="true" size="mini">
          <el-form-item :label="$t(key('team_name'))">
            <el-input v-model.trim="search.name" :placeholder="$t(key('enter_team_name'))" clearable style="width:200px" @keyup.enter.native="onSearch" />
          </el-form-item>
          <el-form-item :label="$t(key('area'))">
            <el-select v-model="search.area_id" :placeholder="$t(key('select_area'))" clearable filterable style="width:200px" @change="onSearchAreaChange">
              <el-option v-for="item in areaOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t(key('production_line'))">
            <el-select v-model="search.line_id" :placeholder="$t(key('select_area_then_line'))" clearable filterable style="width:200px">
              <el-option v-for="item in searchLineOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t(key('last_create_time'))">
            <el-date-picker v-model="search.create_time" type="datetimerange" value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="$t(key('start_time'))" :end-placeholder="$t(key('end_time'))" style="width:330px" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" @click="onSearch">{{ $t(key('search')) }}</el-button>
            <el-button icon="el-icon-refresh" @click="onReset">{{ $t(key('reset')) }}</el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>

    <page-table ref="pageTable" :columns="columns" :data="tableData" :loading="loading" :toolbar-buttons="toolbarButtons" :row-buttons="rowButtons" :pagination="pagination" auto-height @page-change="onPageChange" @selection-change="selectedRows = $event" />

    <el-dialog :title="$t(dialogTitle)" :visible.sync="dialogVisible" width="80%" :close-on-click-modal="false" @close="closeDialog">
      <el-form ref="form" :model="formData" :rules="translatedRules" inline label-width="150px" size="small">
        <el-form-item :label="$t(key('team_name'))" prop="name"><el-input v-model="formData.name" /></el-form-item>
        <el-form-item :label="$t(key('affiliated_factory'))" prop="area_id">
          <el-select v-model="formData.area_id" clearable filterable :placeholder="$t(key('please_select'))" @change="onFormAreaChange">
            <el-option v-for="item in areaOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item :label="$t(key('affiliated_production_line'))" prop="line_id">
          <el-select v-model="formData.line_id" clearable filterable :placeholder="$t(key('please_select_factory_then_line'))">
            <el-option v-for="item in formLineOptions" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>
      <el-divider />
      <el-button size="mini" type="success" icon="el-icon-plus" @click="addMember">{{ $t(key('add_member')) }}</el-button>
      <el-table :data="membersData" style="width:100%;margin-top:10px" border>
        <el-table-column :label="$t(key('member_name'))">
          <template slot-scope="scope">
            <el-select v-model="membersData[scope.$index].user_id" size="small" clearable filterable :placeholder="$t(key('please_select'))">
              <el-option v-for="item in userOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column :label="$t(key('is_team_leader'))" width="220">
          <template slot-scope="scope">
            <el-switch v-model="membersData[scope.$index].is_main" :active-text="$t(key('yes'))" :inactive-text="$t(key('no'))" :active-value="1" :inactive-value="0" @change="val => onLeaderChange(val, scope.$index)" />
          </template>
        </el-table-column>
        <el-table-column :label="$t(key('operation'))" width="120">
          <template slot-scope="scope"><el-button type="danger" size="mini" icon="el-icon-delete" @click="deleteMember(scope.row, scope.$index)">{{ $t(key('delete')) }}</el-button></template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-if="memberPagination.total > memberPagination.size"
        :current-page="memberPagination.current"
        :page-size="memberPagination.size"
        :page-sizes="[8, 20, 50, 100]"
        :total="memberPagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        class="member-pagination"
        @size-change="onMemberSizeChange"
        @current-change="onMemberCurrentChange"
      />
      <span slot="footer">
        <el-button @click="closeDialog">{{ $t(key('cancel')) }}</el-button>
        <el-button type="primary" :loading="submitting" @click="submitDialog">{{ $t(key('confirm')) }}</el-button>
      </span>
    </el-dialog>

    <el-dialog :title="$t(key('production_team_data_import'))" :visible.sync="importVisible" width="50%" :close-on-click-modal="false">
      <el-alert :title="$t(key('upload_file_alert_title'))" :description="$t(key('upload_file_alert_description'))" :closable="false" type="warning" />
      <el-upload class="upload" action="" :multiple="false" :auto-upload="false" :show-file-list="true" :file-list="importFileList" accept=".xls,.xlsx" :on-change="onImportFileChange">
        <el-button slot="trigger" size="mini" type="success">{{ $t(key('select_file')) }}</el-button>
        <el-button style="margin-left:10px" size="mini" type="primary" :loading="importLoading" @click.stop="downloadTemplate">{{ $t(key('download_template')) }}</el-button>
      </el-upload>
      <el-table :data="importRows" height="320" border style="margin-top:12px" v-loading="importTableLoading">
        <el-table-column prop="name" :label="$t(key('team_name'))" />
        <el-table-column prop="area_name" :label="$t(key('affiliated_factory'))" />
        <el-table-column prop="line_name" :label="$t(key('affiliated_production_line'))" />
        <el-table-column prop="members_user_name" :label="$t(key('member_name'))" />
        <el-table-column prop="is_main" :label="$t(key('is_team_leader'))" />
      </el-table>
      <span slot="footer">
        <el-button @click="importVisible = false">{{ $t(key('cancel')) }}</el-button>
        <el-button type="primary" @click="submitImport">{{ $t(key('confirm')) }}</el-button>
      </span>
    </el-dialog>
  </d2-container>
</template>

<script>
import { useTableColumns } from '@/composables/useTableColumns'
import { useTableButtons } from '@/composables/useTableButtons'
import { i18nMixin } from '@/composables/useI18n'
import { confirmMixin } from '@/composables/useConfirmHandle'
import PageTable from '@/components/page-table'
import { getFactoryAreaALL } from '@/api/production-master-data/factory-area'
import { getProductionLineALL } from '@/api/production-master-data/production-line'
import { getUserList } from '@/api/system-administration/user'
import { downloadRename, readExcel } from '@/utils/file'
import { getTeamList, createTeam, editTeam, deleteTeam, getTeamImportTemplate, importTeamData, exportTeamTask, getTeamMemberList, deleteTeamMember } from '@/api/production-master-data/team-management'

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: 'production-master-data-team-management',
  components: { PageTable },
  mixins: [i18nMixin('page.production_master_data.team_model.team_management'), confirmMixin],
  data () {
    return {
      loading: false,
      submitting: false,
      tableData: [],
      selectedRows: [],
      columns: [],
      toolbarButtons: [],
      rowButtons: [],
      search: { name: '', area_id: '', line_id: '', create_time: '' },
      pagination: { current: 1, size: 10, total: 0 },
      areaOptions: [],
      searchLineOptions: [],
      formLineOptions: [],
      userOptions: [],
      dialogVisible: false,
      dialogTitle: '',
      handleType: 'create',
      editId: '',
      leaderIndex: undefined,
      formData: { name: '', area_id: '', line_id: '' },
      membersData: [],
      memberPagination: { current: 1, size: 8, total: 0 },
      importVisible: false,
      importFileList: [],
      importRows: [],
      importLoading: false,
      importTableLoading: false,
      rules: {
        name: [{ required: true, message: this.key('please_enter_team_name'), trigger: 'blur' }, { min: 2, max: 20, message: this.key('length_2_to_20_characters'), trigger: 'blur' }],
        area_id: [{ required: true, message: this.key('please_select_affiliated_factory'), trigger: 'change' }],
        line_id: [{ required: true, message: this.key('please_select_affiliated_production_line'), trigger: 'change' }]
      }
    }
  },
  computed: {
    translatedRules () {
      const next = {}
      Object.keys(this.rules).forEach(key => { next[key] = this.rules[key].map(rule => ({ ...rule, message: this.$t(rule.message) })) })
      return next
    }
  },
  created () {
    this.initOptions()
    this.columns = useTableColumns([
      { prop: 'sort', label: this.key('serial_number'), width: 80 },
      { prop: 'name', label: this.key('team_name'), minWidth: 140 },
      { prop: 'area_name', label: this.key('affiliated_factory'), minWidth: 140 },
      { prop: 'line_name', label: this.key('affiliated_production_line'), minWidth: 160 },
      { prop: 'create_time', label: this.key('create_time'), minWidth: 160 },
      { prop: 'update_time', label: this.key('update_time'), minWidth: 160 },
      { prop: '_actions', label: this.key('operation'), width: 180, fixed: 'right' }
    ])
    const btns = useTableButtons({
      toolbar: [
        { key: 'add', label: this.key('add'), icon: 'el-icon-plus', type: 'primary', auth: '/system_settings/organization/production_team_manage/create', onClick: this.openAdd },
        { key: 'batch_delete', label: this.key('batch_delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/batch-delete', needSelection: true, onClick: this.handleBatchDelete },
        { key: 'import', label: this.key('import'), icon: 'el-icon-upload2', type: 'success', auth: '/system_settings/organization/production_team_manage/import', onClick: this.openImport },
        { key: 'export', label: this.key('export'), icon: 'el-icon-download', type: 'primary', auth: '/system_settings/organization/production_team_manage/export', onClick: this.handleExport }
      ],
      row: [
        { key: 'edit', label: this.key('edit'), icon: 'el-icon-edit', auth: '/system_settings/organization/production_team_manage/edit', onClick: this.openEdit },
        { key: 'delete', label: this.key('delete'), icon: 'el-icon-delete', color: 'danger', auth: '/system_settings/organization/production_team_manage/delete', onClick: this.handleDelete }
      ]
    }, this.$permission)
    this.toolbarButtons = btns.toolbarButtons
    this.rowButtons = btns.rowButtons
    this.fetchData()
  },
  methods: {
    async initOptions () {
      const [areas, users] = await Promise.all([getFactoryAreaALL({}), getUserList({ page_no: 1, page_size: 10000 })])
      this.areaOptions = ((areas && areas.data) || areas || []).map(item => ({ label: item.name, value: item.area_id || item.id }))
      const userPage = readPageData(users)
      this.userOptions = userPage.list.map(item => ({ label: item.nickname || item.name || item.username, value: item.user_id || item.id }))
    },
    async loadLines (areaId, target) {
      if (!areaId) { this[target] = []; return }
      const res = await getProductionLineALL({ area_id: areaId })
      const { list } = readPageData(res)
      this[target] = list.map(item => ({ label: item.name, value: item.id }))
    },
    onSearchAreaChange (areaId) { this.search.line_id = ''; this.loadLines(areaId, 'searchLineOptions') },
    onFormAreaChange (areaId) { this.formData.line_id = ''; this.loadLines(areaId, 'formLineOptions') },
    buildSearchParams () {
      const params = { ...this.search }
      if (!Array.isArray(params.create_time) || !params.create_time.length) delete params.create_time
      return params
    },
    async fetchData () {
      this.loading = true
      try {
        const res = await getTeamList({ ...this.buildSearchParams(), page_no: this.pagination.current, page_size: this.pagination.size })
        const { list, total } = readPageData(res)
        this.tableData = list
        this.pagination.total = total
      } finally { this.loading = false }
    },
    onSearch () { this.pagination.current = 1; this.fetchData() },
    onReset () { this.search = { name: '', area_id: '', line_id: '', create_time: '' }; this.searchLineOptions = []; this.pagination.current = 1; this.fetchData() },
    onPageChange (page) { this.pagination.current = page.current; this.pagination.size = page.size; this.fetchData() },
    openAdd () { this.handleType = 'create'; this.dialogTitle = this.key('add_team'); this.dialogVisible = true },
    async openEdit (row) {
      this.handleType = 'edit'; this.dialogTitle = this.key('edit_team'); this.editId = row.id
      this.formData = { name: row.name, area_id: row.area_id, line_id: row.line_id }
      await this.loadLines(row.area_id, 'formLineOptions')
      this.memberPagination.current = 1
      await this.loadMembers()
      this.dialogVisible = true
    },
    async loadMembers () {
      const res = await getTeamMemberList({
        production_team_id: this.editId,
        page_no: this.memberPagination.current,
        page_size: this.memberPagination.size
      })
      const { list } = readPageData(res)
      this.membersData = list.map(item => ({ ...item, is_main: Number(item.is_main) }))
      this.memberPagination.total = readPageData(res).total
      this.leaderIndex = this.membersData.findIndex(item => Number(item.is_main) === 1)
      if (this.leaderIndex < 0) this.leaderIndex = undefined
    },
    onMemberSizeChange (size) {
      this.memberPagination.size = size
      this.memberPagination.current = 1
      if (this.editId) this.loadMembers()
    },
    onMemberCurrentChange (current) {
      this.memberPagination.current = current
      if (this.editId) this.loadMembers()
    },
    addMember () { this.membersData.push({ user_id: '', is_main: 0 }) },
    onLeaderChange (val, index) {
      if (Number(val) === 1 && this.leaderIndex !== undefined && this.leaderIndex !== index) {
        this.$message.error(this.$t(this.key('only_one_team_leader_allowed')))
        this.membersData[index].is_main = 0
      } else if (this.leaderIndex === index && Number(val) === 0) this.leaderIndex = undefined
      else if (Number(val) === 1) this.leaderIndex = index
    },
    async deleteMember (row, index) {
      if (row.id) {
        await deleteTeamMember({ id: [row.id] })
        this.$message.success(this.$t(this.key('operation_successful')))
        await this.loadMembers()
        return
      }
      this.membersData.splice(index, 1)
    },
    submitDialog () {
      this.$refs.form.validate(async valid => {
        if (!valid) return
        this.submitting = true
        try {
          const payload = { ...this.formData, membersData: this.membersData }
          if (this.handleType === 'create') await createTeam(payload)
          else await editTeam({ ...payload, id: this.editId })
          this.$message.success(this.$t(this.key('operation_successful')))
          this.closeDialog(); this.fetchData()
        } finally { this.submitting = false }
      })
    },
    closeDialog () {
      this.dialogVisible = false
      this.formData = { name: '', area_id: '', line_id: '' }
      this.membersData = []
      this.formLineOptions = []
      this.memberPagination = { current: 1, size: 8, total: 0 }
      this.leaderIndex = undefined
      this.editId = ''
    },
    async handleDelete (row) {
      const cancelled = await this.$confirmAction({ message: this.key('delete_team_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: [row.id] }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData()
    },
    async handleBatchDelete () {
      if (!this.selectedRows.length) { this.$message.error(this.$t(this.key('please_select_table_data'))); return }
      const cancelled = await this.$confirmAction({ message: this.key('batch_delete_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => deleteTeam({ id: this.selectedRows.map(item => item.id) }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('operation_successful'))); this.fetchData()
    },
    openImport () { this.importFileList = []; this.importRows = []; this.importVisible = true },
    async downloadTemplate () { this.importLoading = true; try { const res = await getTeamImportTemplate({}); downloadRename(res, 'xlsx', this.$t(this.key('team_data_import_template'))) } finally { this.importLoading = false } },
    async onImportFileChange (file) {
      if (!file || !/\.(xls|xlsx)$/i.test(file.name)) { this.$message.error(this.$t(this.key('upload_format_error'))); return }
      this.importFileList = [file]
      this.importTableLoading = true
      try {
        const rows = await readExcel(file.raw)
        this.importRows = rows.map(row => ({ name: row['班组名称'], area_name: row['所属厂区'], line_name: row['所属产线'], members_user_name: row['成员名称'], is_main: row['是否班组组长'] }))
      } finally { this.importTableLoading = false }
    },
    async submitImport () {
      if (!this.importRows.length) { this.$message.error(this.$t(this.key('please_import_department_data'))); return }
      await importTeamData({ import_data: JSON.stringify(this.importRows) })
      this.$message.success(this.$t(this.key('operation_successful'))); this.importVisible = false; this.fetchData()
    },
    async handleExport () {
      const cancelled = await this.$confirmAction({ message: this.key('export_confirm_message'), title: this.key('prompt'), confirmButtonText: this.key('confirm'), cancelButtonText: this.key('cancel') }, () => exportTeamTask({ ...this.buildSearchParams(), action: 'download' }))
      if (cancelled) return
      this.$message.success(this.$t(this.key('download_task_created')))
    }
  }
}
</script>

<style scoped>
.search-bar { padding: 10px 0; }
.member-pagination { margin-top: 12px; text-align: right; }
/deep/ .el-form-item--mini.el-form-item { margin-bottom: 4px; }
</style>
