<template>
  <d2-container>
    <template #header>
      <div class="search-bar">
        <el-form ref="form" :inline="true" :model="form" size="mini">
          <el-form-item :label="$t(key('battery_id'))" prop="battery_id">
            <el-input
              v-model="form.battery_id"
              :placeholder="$t(key('enter_battery_id'))"
              clearable
              style="width:260px"
              @keyup.enter.native="fetchData"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" :disabled="loading" :loading="loading" @click="fetchData">
              {{ $t(key('query')) }}
            </el-button>
            <el-button icon="el-icon-download" :disabled="loading" @click="exportTree">
              {{ $t(key('export')) }}
            </el-button>
            <el-button icon="el-icon-refresh" :disabled="loading" @click="resetForm">
              {{ $t(key('reset')) }}
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>

    <div v-loading="loading" class="traceability-page">
      <el-empty v-if="!hasGraph" :description="$t(key('enter_battery_id'))" />
      <template v-else>
        <div class="trace-toolbar">
          <div class="trace-toolbar__group">
            <span class="toolbar-label">{{ $t(key('view_type')) }}</span>
            <el-radio-group v-model="viewType" size="mini">
              <el-radio-button label="horizontal">{{ $t(key('horizontal')) }}</el-radio-button>
              <el-radio-button label="vertical">{{ $t(key('vertical')) }}</el-radio-button>
            </el-radio-group>
          </div>
          <div class="trace-toolbar__locate">
            <span class="toolbar-label">{{ $t(key('position')) }}</span>
            <el-input v-model.trim="locator.item_code" size="mini" clearable :placeholder="$t(key('enter_item_code'))" />
            <el-button size="mini" type="primary" @click="locateNode('item_code', locator.item_code)">
              {{ $t(key('confirm_position')) }}
            </el-button>
            <el-input v-model.trim="locator.item_batch" size="mini" clearable :placeholder="$t(key('enter_item_batch'))" />
            <el-button size="mini" type="primary" @click="locateNode('item_batch', locator.item_batch)">
              {{ $t(key('confirm_position')) }}
            </el-button>
            <el-input
              v-model.trim="locator.workingsubclass_code"
              size="mini"
              clearable
              :placeholder="$t(key('enter_work_unit'))"
            />
            <el-button size="mini" type="primary" @click="locateNode('workingsubclass_code', locator.workingsubclass_code, true)">
              {{ $t(key('confirm_position')) }}
            </el-button>
          </div>
        </div>

        <div :class="['trace-tree-wrap', 'trace-tree-wrap--' + viewType]">
          <el-tree
            ref="tree"
            class="trace-tree"
            :data="treeData"
            node-key="id"
            default-expand-all
            :expand-on-click-node="false"
          >
            <template #default="{ data }">
              <div :class="['trace-node', { 'is-active': activeNodeId === data.id }]" :data-node-id="data.id" @click="activeNodeId = data.id">
                <div class="trace-node__title">
                  <el-tag size="mini" type="warning" effect="dark">{{ data.data.type_name || '-' }}</el-tag>
                  <strong>{{ data.text || data.id }}</strong>
                </div>
                <div class="trace-node__body">
                  <p>{{ $t(key('item_name')) }}: {{ data.data.item_name || '-' }}</p>
                  <p>{{ $t(key('item_code')) }}: {{ data.data.item_code || '-' }}</p>
                  <p>{{ $t(key('item_batch')) }}: {{ data.data.item_batch || '-' }}</p>
                  <p>{{ $t(key('work_unit')) }}: {{ data.data.workingsubclass_code || '-' }}</p>
                  <p>{{ $t(key('work_unit_name')) }}: {{ data.data.workingsubclass_name || '-' }}</p>
                  <p>{{ $t(key('process_code')) }}: {{ data.data.process_code || '-' }}</p>
                  <p>{{ $t(key('start_time')) }}: {{ data.data.start_time || '-' }}</p>
                  <p>{{ $t(key('finish_time')) }}: {{ data.data.finish_time || '-' }}</p>
                  <p>{{ $t(key('inspection_person')) }}: {{ data.data.inspection_person || '-' }}</p>
                  <p>{{ $t(key('inspection_time')) }}: {{ data.data.inspection_time || '-' }}</p>
                  <p>{{ $t(key('quality_person')) }}: {{ data.data.quality_person || '-' }}</p>
                  <p>{{ $t(key('quality_time')) }}: {{ data.data.quality_time || '-' }}</p>
                  <p>{{ $t(key('device_name')) }}: {{ data.data.device_name || '-' }}</p>
                  <p>{{ $t(key('device_code')) }}: {{ data.data.device_code || '-' }}</p>
                </div>
              </div>
            </template>
          </el-tree>
        </div>
      </template>
    </div>
  </d2-container>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import {
  exportBackwardTraceabilityTree,
  getBackwardTraceabilityData
} from '@/api/data-platform/traceability/backward'

export default {
  name: 'data-platform-traceability-backward',
  mixins: [i18nMixin('page.data_platform.traceability.backward')],
  data () {
    return {
      loading: false,
      form: {
        battery_id: this.$route.params.battery_id || ''
      },
      traceData: {},
      viewType: 'horizontal',
      activeNodeId: '',
      locator: {
        item_code: '',
        item_batch: '',
        workingsubclass_code: ''
      }
    }
  },
  computed: {
    graph () {
      return this.traceData.relation_graph || {}
    },
    hasGraph () {
      return Array.isArray(this.graph.nodes) && this.graph.nodes.length > 0
    },
    treeData () {
      if (!this.hasGraph) return []
      const nodeMap = new Map()
      this.graph.nodes.forEach(node => {
        nodeMap.set(String(node.id), {
          ...node,
          id: String(node.id),
          data: node.data || {},
          children: []
        })
      })
      const childIds = new Set()
      const lines = Array.isArray(this.graph.lines) ? this.graph.lines : []
      lines.forEach(line => {
        const from = nodeMap.get(String(line.from))
        const to = nodeMap.get(String(line.to))
        if (from && to) {
          from.children.push(to)
          childIds.add(to.id)
        }
      })
      const rootId = this.graph.rootId ? String(this.graph.rootId) : ''
      const root = rootId && nodeMap.get(rootId)
      if (root) return [root]
      return Array.from(nodeMap.values()).filter(node => !childIds.has(node.id))
    }
  },
  mounted () {
    if (this.form.battery_id) this.fetchData()
  },
  methods: {
    ensureBatteryInput () {
      if (this.form.battery_id) return true
      this.$message.error(this.$t(this.key('enter_battery_id')))
      return false
    },
    async fetchData () {
      if (!this.ensureBatteryInput()) return
      this.loading = true
      try {
        const res = await getBackwardTraceabilityData({ ...this.form })
        const data = res && res.data ? res.data : res
        this.traceData = data || {}
        const firstNode = this.graph.nodes && this.graph.nodes[0]
        this.activeNodeId = firstNode ? String(firstNode.id) : ''
      } finally {
        this.loading = false
      }
    },
    resetForm () {
      this.form.battery_id = ''
      this.traceData = {}
      this.activeNodeId = ''
      this.locator = {
        item_code: '',
        item_batch: '',
        workingsubclass_code: ''
      }
    },
    locateNode (field, value, onlyFinalProduct = false) {
      if (!value) return
      const nodes = Array.isArray(this.graph.nodes) ? this.graph.nodes : []
      const target = nodes.find(node => {
        const data = node.data || {}
        if (String(data[field] || '') !== String(value)) return false
        if (!onlyFinalProduct) return true
        return data.type_name === '制成品' && Number(data.status) === -1
      })
      if (!target) {
        this.$message.warning(this.$t(this.key('node_not_found')))
        return
      }
      this.activeNodeId = String(target.id)
      if (this.$refs.tree) {
        this.$refs.tree.setCurrentKey(this.activeNodeId)
      }
      this.$nextTick(() => {
        const element = this.$el.querySelector(`[data-node-id="${this.activeNodeId}"]`)
        if (element && element.scrollIntoView) {
          element.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' })
        }
      })
    },
    async exportTree () {
      if (!this.ensureBatteryInput()) return
      if (!this.hasGraph) {
        this.$message.warning(this.$t(this.key('query_before_export')))
        return
      }
      const res = await exportBackwardTraceabilityTree({
        ...this.form,
        tree_list: JSON.stringify(this.graph.nodes || [])
      })
      const data = res && res.data ? res.data : res
      this.downloadExport(data)
    },
    downloadExport (url) {
      if (!url) return
      const link = document.createElement('a')
      link.href = url
      link.download = `${this.form.battery_id}${this.$t(this.key('reverse'))}`
      link.target = '_blank'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    }
  }
}
</script>

<style lang="scss" scoped>
.search-bar {
  margin-bottom: -18px;
}

.traceability-page {
  min-height: 560px;
}

.trace-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  align-items: center;
  margin-bottom: 12px;
}

.trace-toolbar__group,
.trace-toolbar__locate {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.trace-toolbar__locate .el-input {
  width: 190px;
}

.toolbar-label {
  color: #606266;
  font-size: 13px;
  font-weight: 600;
}

.trace-tree-wrap {
  height: calc(100vh - 230px);
  min-height: 520px;
  overflow: auto;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background: #f7f9fb;
  padding: 12px;
}

.trace-tree-wrap--horizontal {
  ::v-deep .el-tree-node__children {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
  }
}

.trace-tree {
  min-width: max-content;
  background: transparent;
}

.trace-node {
  width: 300px;
  min-height: 300px;
  padding: 10px;
  margin: 8px 0;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: #fff;
  color: #303133;
  cursor: pointer;
}

.trace-node.is-active {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.15);
}

.trace-node__title {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}

.trace-node__body p {
  margin: 0;
  padding: 4px 0;
  border-bottom: 1px solid #f0f2f5;
  line-height: 1.35;
  white-space: normal;
}
</style>
