<template>
  <div class="main">
    <div class="card">
      <el-form-item label="选择库区">
        <el-select v-model="selectedPartition" placeholder="请选择库区" @change="onPartitionChange" style="width: 180px">
          <el-option v-for="item in partitionList" :key="item.PartitionCode" :label="item.PartitionName"
            :value="item.PartitionCode" />
        </el-select>
      </el-form-item>
      <div class="storList">
        <div class="storList-item modern-item" v-for="item in stockList" :key="item.StockCode"
          @click="onStockCardClick(item)">
          <div class="storList-header">
            <span class="storList-title">{{ item.StockName }}</span>
            <div class="storList-tags">
              <van-tag type="danger" v-if="item.TaskId != null">任务中</van-tag>
              <van-tag type="primary" v-if="item.StockStatus == false && !item.TrayNo">空库位</van-tag>
              <van-tag type="warning" v-if="item.StockStatus == false && item.TrayNo">空托盘</van-tag>
              <van-tag type="success" v-if="item.StockStatus == true">满料</van-tag>
            </div>
          </div>
          <div class="storList-info">
            <span>项目名称：<b>{{ item.ProjectNo || '-' }}</b></span>
            <span>间隔编号：<b>{{ item.IntervalNo || '-' }}</b></span>
            <span>部件位置：<b>{{ item.ComponentLocation || '-' }}</b></span>
            <span>托盘编号：<b>{{ item.TrayNo || '-' }}</b></span>
          </div>
        </div>
      </div>
    </div>
    <el-dialog v-model="showEditStockDialog" title="修改库位信息" width="340px" :close-on-click-modal="false"
      @close="onEditStockCancel">
      <el-form @submit.prevent>
        <el-form-item label="项目名称">
          <el-input v-model="editStockForm.ProjectName" placeholder="请扫描或输入 项目名称 或 三段码" clearable @input="onProjectNameInput" />
        </el-form-item>
        <el-form-item label="间隔编号">
          <el-input v-model="editStockForm.IntervalNo" placeholder="请输入 间隔编号" clearable />
        </el-form-item>
        <el-form-item label="部件位置">
          <el-input v-model="editStockForm.ComponentLocation" placeholder="请输入 部件位置" clearable />
        </el-form-item>
        <el-form-item label="托盘编号">
          <el-input v-model="editStockForm.TrayNo" placeholder="请输入 托盘编号（仅托盘码时只填此项）" clearable />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="onEditStockCancel">取消</el-button>
        <el-button type="primary" @click="onEditStockConfirm">确认</el-button>
      </template>
    </el-dialog>
    <van-action-sheet v-model:show="showEditActionSheet" :actions="editActionList" @select="onEditActionSelect"
      title="请选择操作" />
    <van-action-sheet v-model:show="showTaskActionSheet" :actions="taskActionList" @select="onTaskActionSelect" title="任务操作" />
    
    <!-- 增加目标库区选择弹窗 -->
    <el-dialog v-model="showTargetPartitionDialog" title="选择目标库区" width="320px" :close-on-click-modal="false">
      <el-select v-model="selectedTargetPartition" placeholder="请选择目标库区" style="width: 100%">
        <el-option v-for="item in partitionList" :key="item.PartitionCode" :label="item.PartitionName"
          :value="item.PartitionCode" />
      </el-select>
      <template #footer>
        <el-button @click="showTargetPartitionDialog = false">取消</el-button>
        <el-button type="primary" @click="onTargetPartitionConfirm">确认</el-button>
      </template>
    </el-dialog>

    <!-- 增加目标库位选择弹窗 -->
    <el-dialog v-model="showTargetStockDialog" :title="targetPartitionName" width="400px" :close-on-click-modal="false">
      <div v-if="targetStockList.length > 0">
        <div v-for="item in targetStockList" :key="item.StockCode" @click="onTargetStockClick(item)"
          style="cursor:pointer; border-bottom:1px solid #eee; padding:12px 0;">
          <div style="display:flex;flex-direction:column;">
            <span><b>库位名称：</b>{{ item.StockName }}</span>
            <span><b>项目名称：</b>{{ item.ProjectNo || '-' }}</span>
            <span><b>间隔编号：</b>{{ item.IntervalNo || '-' }}</span>
            <span><b>部件位置：</b>{{ item.ComponentLocation || '-' }}</span>
          </div>
        </div>
      </div>
      <div v-else style="text-align:center;color:#888;">暂无可用库位</div>
    </el-dialog>
  </div>
</template>

<script setup>
import { inject, onMounted, onUnmounted, reactive, ref } from 'vue'
import { ElForm, ElFormItem, ElSelect, ElOption } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Dialog } from 'vant'
import { useAppStore } from '@/store/app.js'
import { storeToRefs } from 'pinia'
import { v4 as uuidv4 } from 'uuid'
const store = useAppStore()
const { user } = storeToRefs(store)

const ExecDatabaseByParam = inject('ExecDatabaseByParam')
const ExecAgvApi = inject('ExecAgvApi')

const partitionList = ref([])
const selectedPartition = ref()
const stockList = ref([])
const showEditStockDialog = ref(false)
const showEditActionSheet = ref(false)
const showTargetPartitionDialog = ref(false)
const showTargetStockDialog = ref(false)
const selectedTargetPartition = ref('')
const targetPartitionName = ref('')
const targetStockList = ref([])
const currentSourceStock = ref(null)
const showTaskActionSheet = ref(false)

const editActionList = [
  { name: '修改库位信息' },
  { name: '送料' }
]
const taskActionList = [
  { name: '取消任务' }
]
const editStockForm = reactive({
  ProjectName: '',
  IntervalNo: '',
  ComponentLocation: '',
  TrayNo: '',
  StockCode: '',
  TaskId: ''
})

onMounted(async () => {
  // 1) 获取 AGV 全量库区列表（名称映射用）
  const partitionRes = await ExecAgvApi('getPartitionList', {})
  if (!partitionRes.Result) {
    ElMessage.error(partitionRes.ErrMsg || '获取库区失败')
    return
  }
  const allPartitions = partitionRes.Data || []

  // 2) 根据工位查询可用库区：-1 表示可选全部；否则为逗号分隔的库区号
  const mesRes = await ExecDatabaseByParam('11', 'MES_计划BOM_工位与名称_库位编号_查询', [['工位号', user.value.opName]])
  if (mesRes.data && mesRes.data.length > 0) {
    const codeStr = mesRes.data[0].库位编号
    const isAll = codeStr != null && codeStr.toString().trim() === '-1'
    if (isAll) {
      partitionList.value = allPartitions
    } else {
      const codes = codeStr.toString().split(',').map(s => s.trim()).filter(Boolean)
      partitionList.value = allPartitions.filter(p => codes.includes(p.PartitionCode?.toString()))
    }
  } else {
    ElMessage.warning('此工位无对应库区权限配置')
    partitionList.value = []
  }

  // 3) 默认选中第一个可用库区并加载库位
  if (partitionList.value.length > 0) {
    selectedPartition.value = partitionList.value[0].PartitionCode
    await onPartitionChange(selectedPartition.value)
  }
})

const onProjectNameInput = () => {
  const raw = editStockForm.ProjectName || ''
  const parts = raw.split('&')
  if (parts.length === 3) {
    editStockForm.ProjectName = parts[0].trim()
    editStockForm.IntervalNo = parts[1].trim()
    editStockForm.ComponentLocation = parts[2].trim()
  }
}

const onPartitionChange = async (val) => {
  // 拉该库区下的库位列表
  const stockRes = await ExecAgvApi('getStockList', { PartitionCode: val })
  if (stockRes.Result) {
    stockList.value = stockRes.Data
  } else {
    ElMessage.error(stockRes.ErrMsg || '获取库位失败')
  }
}

const onStockCardClick = (item) => {
  // 任务中的库位不可操作
  if (item.TaskId != null) {
    // 弹出操作菜单，只有取消任务选项
    currentSourceStock.value = item
    showEditActionSheet.value = false
    showTaskActionSheet.value = true
    return
  }
  
  // 保存被点击的库位信息
  editStockForm.ProjectName = item.ProjectNo || ''
  editStockForm.IntervalNo = item.IntervalNo || ''
  editStockForm.ComponentLocation = item.ComponentLocation || ''
  editStockForm.TrayNo = item.TrayNo || ''
  editStockForm.StockCode = item.StockCode
  editStockForm.TaskId = item.TaskId
  currentSourceStock.value = item
  
  // 显示操作菜单
  showEditActionSheet.value = true
}

const onEditActionSelect = (action) => {
  showEditActionSheet.value = false
  if (action.name === '修改库位信息') {
    showEditStockDialog.value = true
  } else if (action.name === '送料') {
    // 空库位无料无托盘无法送料
    if (!currentSourceStock.value.StockStatus && !currentSourceStock.value.TrayNo) {
      Dialog.alert({
        title: '提示',
        message: '空库位无托盘无法送料',
      })
      return
    }
    // 打开目标库区选择弹窗
    showTargetPartitionDialog.value = true
  }
}

const onEditStockConfirm = async () => {
  // 处理参数
  const TrayNo = editStockForm.TrayNo ? editStockForm.TrayNo : null
  const ProjectNo = editStockForm.ProjectName ? editStockForm.ProjectName : null
  const IntervalNo = editStockForm.IntervalNo ? editStockForm.IntervalNo : null
  const ComponentLocation = editStockForm.ComponentLocation ? editStockForm.ComponentLocation : null
  // 间隔号与部件位置都存在则判定满料
  const StockStatus = (IntervalNo && ComponentLocation) ? true : false
  const params = {
    StockCode: editStockForm.StockCode,
    TrayNo,
    ProjectNo,
    IntervalNo,
    ComponentLocation,
    StockStatus,
    TaskId: editStockForm.TaskId
  }
  // 记录旧值
  const oldTrayNo = stockList.value.find(i => i.StockCode === editStockForm.StockCode)?.TrayNo || null
  const oldProjectNo = stockList.value.find(i => i.StockCode === editStockForm.StockCode)?.ProjectNo || null
  const oldIntervalNo = stockList.value.find(i => i.StockCode === editStockForm.StockCode)?.IntervalNo || null
  const oldComponentLocation = stockList.value.find(i => i.StockCode === editStockForm.StockCode)?.ComponentLocation || null
  const stockName = stockList.value.find(i => i.StockCode === editStockForm.StockCode)?.StockName || ''
  const res = await ExecAgvApi('updateStockInfo', params)
  if (res.Result) {
    // 调用存储过程记录日志
    await ExecDatabaseByParam('12', 'PTCHV_AGV_库位更新记录_增加', [
      ['库位号', editStockForm.StockCode],
      ['库位名称', stockName],
      ['项目名称', ProjectNo || ''],
      ['间隔编号', IntervalNo || ''],
      ['部件位置', ComponentLocation || ''],
      ['托盘编号', TrayNo || ''],
      ['项目名称_old', oldProjectNo || ''],
      ['间隔编号_old', oldIntervalNo || ''],
      ['部件位置_old', oldComponentLocation || ''],
      ['托盘编号_old', oldTrayNo || ''],
      ['操作人', user.value.name],
      ['type', 1],
    ])
    ElMessage.success('库位信息修改成功')
    showEditStockDialog.value = false
    await onPartitionChange(selectedPartition.value)
  } else {
    ElMessage.error(res.ErrMsg || '库位信息修改失败')
  }
}

const onEditStockCancel = () => {
  showEditStockDialog.value = false
}

// 确认目标库区选择
const onTargetPartitionConfirm = async () => {
  if (!selectedTargetPartition.value) {
    ElMessage.warning('请选择目标库区')
    return
  }
  
  // 根据目标库区获取库位列表
  const stockRes = await ExecAgvApi('getStockList', { PartitionCode: selectedTargetPartition.value })
  if (!stockRes.Result) {
    ElMessage.error(stockRes.ErrMsg || '获取库位失败')
    return
  }

  // 只显示空库位(无托盘且无物料)
  targetStockList.value = stockRes.Data
    .filter(i => i.StockStatus === false && !i.TrayNo)
    .map(i => ({ ...i }))

  if (targetStockList.value.length === 0) {
    ElMessage.warning('目标库区没有可用空库位')
    return
  }

  // 获取目标库区名称
  const targetPartition = partitionList.value.find(p => p.PartitionCode == selectedTargetPartition.value)
  targetPartitionName.value = targetPartition ? targetPartition.PartitionName : '未知库区'

  // 关闭库区选择，打开库位选择
  showTargetPartitionDialog.value = false
  showTargetStockDialog.value = true
}

// 点击目标库位，创建送料任务
const onTargetStockClick = (targetStock) => {
  // 二次确认
  ElMessageBox.confirm(`是否将物料从库位【${currentSourceStock.value.StockName}】送至库位【${targetStock.StockName}】？`, '确认送料', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    // 创建AGV任务
    const taskId = uuidv4()
    const res = await ExecAgvApi('createTask', {
      taskId,
      pickPosition: currentSourceStock.value.StockCode,
      dropPosition: targetStock.StockCode,
    })
    
    if (res.Result) {
      // 调用存储过程记录送料日志（新字段）
      await ExecDatabaseByParam('12', 'PTCHV_AGV_送料记录_增加', [
        ['任务号', taskId],
        ['取料库位', currentSourceStock.value.StockCode],
        ['取料库位名称', currentSourceStock.value.StockName],
        ['取料项目名称', currentSourceStock.value.ProjectNo || currentSourceStock.value.ProjectName || ''],
        ['取料间隔编号', currentSourceStock.value.IntervalNo || ''],
        ['取料部件位置', currentSourceStock.value.ComponentLocation || ''],
        ['取料托盘编号', currentSourceStock.value.TrayNo || ''],
        ['送料库位', targetStock.StockCode],
        ['送料库位名称', targetStock.StockName],
        ['操作人', user.value.name],
        ['type', 1],
      ])
      
      ElMessage.success('送料任务创建成功')
      showTargetStockDialog.value = false
      // 刷新库位列表
      await onPartitionChange(selectedPartition.value)
    } else {
      ElMessage.error(res.ErrMsg || '送料任务创建失败')
    }
  }).catch(() => {
    // 取消操作
  })
}

// 任务操作菜单弹窗
const onTaskActionSelect = (action) => {
  showTaskActionSheet.value = false
  if (action.name === '取消任务') {
    ElMessageBox.confirm('是否确认取消该任务？', '取消任务', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      const res = await ExecAgvApi('cancelTask', { taskId: currentSourceStock.value.TaskId })
      if (res.Result) {
        ElMessage.success('任务已取消')
        await onPartitionChange(selectedPartition.value)
      } else {
        ElMessage.error(res.ErrMsg || '取消任务失败')
      }
    }).catch(() => {})
  }
}

</script>

<style lang="scss" scoped>
// 可复用呼叫物料模块的样式
.storList {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

.storList-item.modern-item {
  background: linear-gradient(135deg, #f8fafc 60%, #e0e7ef 100%);
  border-radius: 14px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
  padding: 20px 18px 16px 18px;
  min-width: 260px;
  max-width: 320px;
  flex: 1 1 260px;
  transition: box-shadow 0.2s, transform 0.2s;
  display: flex;
  flex-direction: column;
  gap: 12px;
  cursor: pointer;

  &:hover {
    box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.12);
    transform: translateY(-2px) scale(1.02);
  }
}

.storList-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.storList-title {
  font-size: 1.18rem;
  font-weight: 600;
  color: #222;
}

.storList-tags {
  display: flex;
  gap: 8px;
}

.storList-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.98rem;
  color: #555;

  span {
    display: flex;
    align-items: center;
    gap: 4px;

    b {
      color: #222;
      font-weight: 500;
      margin-left: 2px;
    }
  }
}
</style>
