<script setup lang="ts">
/**
 * 产品与库存管理 —— 全真实 API 驱动
 * 左树右表 + 分类 CRUD + 新增/编辑 SKU + 库存变更原子事务
 */
import { ref, reactive, onMounted, nextTick } from 'vue'
import { Search, Plus, View, Box, Edit, Delete, CirclePlus, Upload } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import request from '@/api/request'

// ════════════════════════ 分类树 ════════════════════════
const treeData = ref<any[]>([])
const currentCategoryId = ref<string | null>(null)
const treeProps = { children: 'children', label: 'name' }

const fetchCategoryTree = async () => {
  try {
    const data: any = await request.get('/api/products/categories/tree')
    treeData.value = Array.isArray(data) ? data : []
  } catch { /* 已统一 */ }
}

const handleNodeClick = (data: any) => {
  currentCategoryId.value = data.id
  fetchSkus()
}

const clearCategoryFilter = () => {
  currentCategoryId.value = null
  fetchSkus()
}

// ── 分类 CRUD 弹窗 ──
const catDialogVisible = ref(false)
const catDialogTitle = ref('新建分类')
const catSubmitting = ref(false)
const catFormRef = ref<FormInstance>()
const isCatEdit = ref(false)
const editCatId = ref('')

const catForm = reactive({ name: '', parent_id: null as string | null })
const catRules = reactive<FormRules>({
  name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
})

const openAddTopCategory = () => {
  isCatEdit.value = false
  catDialogTitle.value = '新建顶级分类'
  editCatId.value = ''
  catForm.name = ''
  catForm.parent_id = null
  catDialogVisible.value = true
  nextTick(() => catFormRef.value?.clearValidate())
}

const openAddChildCategory = (parentNode: any) => {
  isCatEdit.value = false
  catDialogTitle.value = `新建子分类（上级：${parentNode.name}）`
  editCatId.value = ''
  catForm.name = ''
  catForm.parent_id = parentNode.id
  catDialogVisible.value = true
  nextTick(() => catFormRef.value?.clearValidate())
}

const openEditCategory = (node: any) => {
  isCatEdit.value = true
  catDialogTitle.value = '编辑分类'
  editCatId.value = node.id
  catForm.name = node.name
  catForm.parent_id = node.parent_id || null
  catDialogVisible.value = true
  nextTick(() => catFormRef.value?.clearValidate())
}

const submitCategory = async () => {
  const valid = await catFormRef.value?.validate().catch(() => false)
  if (!valid) return
  catSubmitting.value = true
  try {
    if (isCatEdit.value) {
      await request.put(`/api/products/categories/${editCatId.value}`, { name: catForm.name })
      ElMessage.success('分类已更新')
    } else {
      const payload: any = { name: catForm.name }
      if (catForm.parent_id) payload.parent_id = catForm.parent_id
      await request.post('/api/products/categories', payload)
      ElMessage.success('分类创建成功')
    }
    catDialogVisible.value = false
    await fetchCategoryTree()
  } catch { /* 已统一 */ }
  finally { catSubmitting.value = false }
}

const deleteCategory = (node: any) => {
  ElMessageBox.confirm(`确定删除分类「${node.name}」吗？`, '删除确认', { type: 'warning' })
    .then(async () => {
      try {
        await request.delete(`/api/products/categories/${node.id}`)
        ElMessage.success('分类已删除')
        if (currentCategoryId.value === node.id) {
          currentCategoryId.value = null
          fetchSkus()
        }
        await fetchCategoryTree()
      } catch { /* 已统一 */ }
    })
    .catch(() => {})
}

// ════════════════════════ SKU 列表 ════════════════════════
const loading = ref(false)
const skuList = ref<any[]>([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(20)
const keyword = ref('')

const fetchSkus = async () => {
  loading.value = true
  try {
    const params: Record<string, any> = { page: page.value, size: pageSize.value }
    if (currentCategoryId.value) params.category_id = currentCategoryId.value
    if (keyword.value.trim()) params.keyword = keyword.value.trim()
    const data: any = await request.get('/api/products/skus', { params })
    skuList.value = data?.items || []
    total.value = data?.total || 0
  } catch { /* 已统一 */ }
  finally { loading.value = false }
}

const handleSearch = () => { page.value = 1; fetchSkus() }
const handlePageChange = (p: number) => { page.value = p; fetchSkus() }
const handleSizeChange = (s: number) => { pageSize.value = s; page.value = 1; fetchSkus() }

// ════════════════════════ 新增/编辑 SKU ════════════════════════
const skuDialogVisible = ref(false)
const skuDialogTitle = ref('新增产品')
const skuSubmitting = ref(false)
const skuFormRef = ref<FormInstance>()
const isEditMode = ref(false)
const editSkuId = ref('')

const skuForm = reactive({
  sku_code: '',
  name: '',
  category_id: '' as string | null,
  spec: '',
  standard_price: 0,
  stock_qty: 0,
  warning_threshold: 0,
  unit: '桶',
  status: 1,
})

const skuRules = reactive<FormRules>({
  sku_code: [{ required: true, message: '请输入 SKU 编码', trigger: 'blur' }],
  name: [{ required: true, message: '请输入产品名称', trigger: 'blur' }],
})

const openAddSku = () => {
  isEditMode.value = false
  skuDialogTitle.value = '新增产品'
  editSkuId.value = ''
  Object.assign(skuForm, {
    sku_code: '', name: '', category_id: currentCategoryId.value || null,
    spec: '', standard_price: 0, stock_qty: 0, warning_threshold: 0, unit: '桶', status: 1
  })
  skuDialogVisible.value = true
  nextTick(() => skuFormRef.value?.clearValidate())
}

const openEditSku = (row: any) => {
  isEditMode.value = true
  skuDialogTitle.value = '编辑产品'
  editSkuId.value = row.id
  Object.assign(skuForm, {
    sku_code: row.sku_code, name: row.name, category_id: row.category_id || null,
    spec: row.spec || '', standard_price: row.standard_price, stock_qty: row.stock_qty,
    warning_threshold: row.warning_threshold, unit: row.unit || '桶', status: row.status
  })
  skuDialogVisible.value = true
  nextTick(() => skuFormRef.value?.clearValidate())
}

const submitSku = async () => {
  const valid = await skuFormRef.value?.validate().catch(() => false)
  if (!valid) return
  skuSubmitting.value = true
  try {
    if (isEditMode.value) {
      // ⚠️ 编辑时不传 stock_qty 和 sku_code
      const { stock_qty, sku_code, ...editData } = skuForm
      await request.put(`/api/products/skus/${editSkuId.value}`, editData)
      ElMessage.success('产品信息已更新')
    } else {
      await request.post('/api/products/skus', skuForm)
      ElMessage.success('产品创建成功')
    }
    skuDialogVisible.value = false
    fetchSkus()
  } catch { /* 已统一 */ }
  finally { skuSubmitting.value = false }
}

// ════════════════════════ 详情抽屉 ════════════════════════
const detailVisible = ref(false)
const currentDetail = ref<any>({})
const openDetail = (row: any) => { currentDetail.value = row; detailVisible.value = true }

// ════════════════════════ 导入 SKU ════════════════════════
const importDialogVisible = ref(false)

const getUploadHeaders = () => {
  return { Authorization: `Bearer ${localStorage.getItem('crm_token') || ''}` }
}

const handleImportSuccess = (response: any) => {
  if (response.code === 200) {
    ElMessage.success(response.message || '导入成功')
    importDialogVisible.value = false
    fetchSkus()
  } else {
    ElMessage.error(response.message || '导入失败')
  }
}
const handleImportError = () => { ElMessage.error('上传失败，请检查网络或后端服务') }

// ════════════════════════ 库存变更 ════════════════════════
const invDialogVisible = ref(false)
const invSubmitting = ref(false)
const invFormRef = ref<FormInstance>()
const currentInvSku = ref<any>({})

const invForm = reactive({
  direction: 'in' as 'in' | 'out',
  qty: 1,
  reason: 'purchase',
  remark: '',
})

const invRules = reactive<FormRules>({
  qty: [{ required: true, message: '请输入变更数量', trigger: 'blur' }],
  reason: [{ required: true, message: '请选择变动原因', trigger: 'change' }],
})

const inReasons = [
  { label: '厂家进货', value: 'purchase' },
  { label: '盘点盘盈', value: 'adjust' },
  { label: '客户退货', value: 'return' },
]
const outReasons = [
  { label: '发货出库', value: 'shipment' },
  { label: '送样损耗', value: 'loss' },
  { label: '盘点盘亏', value: 'adjust' },
]

const openInventory = (row: any) => {
  currentInvSku.value = row
  Object.assign(invForm, { direction: 'in', qty: 1, reason: 'purchase', remark: '' })
  invDialogVisible.value = true
  nextTick(() => invFormRef.value?.clearValidate())
}

const submitInventory = async () => {
  const valid = await invFormRef.value?.validate().catch(() => false)
  if (!valid) return
  const changeQty = invForm.direction === 'in' ? invForm.qty : -invForm.qty
  try {
    await ElMessageBox.confirm(
      `确认对「${currentInvSku.value.name}」${invForm.direction === 'in' ? '入库' : '出库'} ${invForm.qty} ${currentInvSku.value.unit || '件'}？`,
      '库存变更确认', { type: 'warning' }
    )
  } catch { return }
  invSubmitting.value = true
  try {
    await request.post('/api/products/inventory/flow', {
      sku_id: currentInvSku.value.id,
      change_qty: changeQty,
      reason: invForm.reason,
      remark: invForm.remark || null,
    })
    ElMessage.success('库存变更成功')
    invDialogVisible.value = false
    fetchSkus()
  } catch { /* 已统一 */ }
  finally { invSubmitting.value = false }
}

// ════════════════════════ Init ════════════════════════
onMounted(async () => {
  await fetchCategoryTree()
  await fetchSkus()
})
</script>

<template>
  <div class="product-management-wrapper">
    <el-row :gutter="20" class="page-row">
      <!-- 1. 左侧分类树 -->
      <el-col :span="5" class="left-col">
        <el-card shadow="never" class="tree-card">
          <template #header>
            <div class="card-header">
              <span class="tree-title">产品目录</span>
              <el-button type="primary" :icon="Plus" link @click="openAddTopCategory">新建</el-button>
            </div>
          </template>
          <el-button v-if="currentCategoryId" link type="primary" size="small" style="margin-bottom:8px" @click="clearCategoryFilter">
            ✕ 清除分类筛选
          </el-button>
          <el-tree
            :data="treeData"
            :props="treeProps"
            node-key="id"
            @node-click="handleNodeClick"
            default-expand-all
            highlight-current
            class="filter-tree"
          >
            <template #default="{ data }">
              <span class="tree-node">
                <span class="tree-node-label">{{ data.name }}</span>
                <span class="tree-node-actions">
                  <el-icon class="tree-action-icon" @click.stop="openAddChildCategory(data)"><CirclePlus /></el-icon>
                  <el-icon class="tree-action-icon" @click.stop="openEditCategory(data)"><Edit /></el-icon>
                  <el-icon class="tree-action-icon danger" @click.stop="deleteCategory(data)"><Delete /></el-icon>
                </span>
              </span>
            </template>
          </el-tree>
          <el-empty v-if="!treeData.length" description="暂无分类，请先新建" :image-size="60" />
        </el-card>
      </el-col>

      <!-- 2 & 3. 右侧主体区 -->
      <el-col :span="19" class="right-col">
        <!-- 检索区 -->
        <el-card shadow="never" class="filter-card">
          <div class="filter-wrapper">
            <el-form :inline="true" class="filter-form">
              <el-form-item label="模糊搜索">
                <el-input v-model="keyword" placeholder="SKU编码 / 产品名称" clearable style="width:280px" @keyup.enter="handleSearch" />
              </el-form-item>
            </el-form>
            <div class="action-buttons">
              <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
              <el-button type="warning" :icon="Upload" @click="importDialogVisible = true">导入SKU</el-button>
              <el-button type="success" :icon="Plus" @click="openAddSku">新增产品</el-button>
            </div>
          </div>
        </el-card>

        <!-- 表格区 -->
        <el-card shadow="never" class="table-card">
          <el-table :data="skuList" v-loading="loading" stripe border height="calc(100vh - 320px)" style="width:100%">
            <el-table-column prop="sku_code" label="产品编码 (SKU)" width="180" fixed="left">
              <template #default="{ row }">
                <span class="sku-bold">{{ row.sku_code }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="name" label="中文名称" min-width="200" show-overflow-tooltip />
            <el-table-column prop="category_name" label="分类" width="130" />
            <el-table-column prop="spec" label="规格" width="120" align="center" />
            <el-table-column label="指导价" width="120" align="right">
              <template #default="{ row }">
                ￥{{ row.standard_price?.toFixed(2) }}
              </template>
            </el-table-column>
            <el-table-column label="当前库存" width="110" align="center">
              <template #default="{ row }">
                <el-tag v-if="row.stock_qty <= row.warning_threshold && row.warning_threshold > 0" type="danger" effect="dark" size="small">
                  <b>{{ row.stock_qty }}</b>
                </el-tag>
                <span v-else class="normal-stock">{{ row.stock_qty }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="unit" label="单位" width="70" align="center" />
            <el-table-column label="操作" width="260" fixed="right">
              <template #default="{ row }">
                <el-button type="primary" link :icon="View" @click="openDetail(row)">详情</el-button>
                <el-button type="warning" link :icon="Box" @click="openInventory(row)">库存变更</el-button>
                <el-button type="primary" link :icon="Edit" @click="openEditSku(row)">编辑</el-button>
              </template>
            </el-table-column>
          </el-table>

          <el-pagination
            style="margin-top:16px; justify-content:flex-end"
            background layout="total, sizes, prev, pager, next"
            :total="total" :page-size="pageSize" :current-page="page" :page-sizes="[10, 20, 50]"
            @current-change="handlePageChange" @size-change="handleSizeChange"
          />
        </el-card>
      </el-col>
    </el-row>

    <!-- ═══════ 分类新增/编辑弹窗 ═══════ -->
    <el-dialog v-model="catDialogVisible" :title="catDialogTitle" width="420px" destroy-on-close>
      <el-form ref="catFormRef" :model="catForm" :rules="catRules" label-width="80px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="catForm.name" placeholder="如 工业润滑油" />
        </el-form-item>
        <el-form-item label="上级分类">
          <el-tree-select
            v-model="catForm.parent_id"
            :data="treeData"
            :props="{ children: 'children', label: 'name', value: 'id' }"
            node-key="id"
            check-strictly
            clearable
            placeholder="不选则为顶级分类"
            style="width:100%"
            :disabled="!isCatEdit"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="catDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="catSubmitting" @click="submitCategory">
          {{ isCatEdit ? '保存' : '新建' }}
        </el-button>
      </template>
    </el-dialog>

    <!-- ═══════ 新增/编辑 SKU 弹窗 ═══════ -->
    <el-dialog v-model="skuDialogVisible" :title="skuDialogTitle" width="560px" destroy-on-close>
      <el-form ref="skuFormRef" :model="skuForm" :rules="skuRules" label-width="100px">
        <el-form-item label="SKU 编码" prop="sku_code">
          <el-input v-model="skuForm.sku_code" :disabled="isEditMode" placeholder="如 LUB-HYD-46-200L" />
        </el-form-item>
        <el-form-item label="产品名称" prop="name">
          <el-input v-model="skuForm.name" placeholder="如 长城卓力 AE 46 号抗磨液压油" />
        </el-form-item>
        <el-form-item label="所属分类">
          <el-tree-select
            v-model="skuForm.category_id"
            :data="treeData"
            :props="{ children: 'children', label: 'name', value: 'id' }"
            node-key="id"
            check-strictly
            clearable
            placeholder="请选择分类"
            style="width:100%"
          />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="包装规格">
              <el-input v-model="skuForm.spec" placeholder="如 200L/桶" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="计量单位">
              <el-input v-model="skuForm.unit" placeholder="桶 / 件 / KG" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="指导价">
              <el-input-number v-model="skuForm.standard_price" :min="0" :precision="2" style="width:100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="预警阈值">
              <el-input-number v-model="skuForm.warning_threshold" :min="0" style="width:100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item v-if="!isEditMode" label="初始库存">
          <el-input-number v-model="skuForm.stock_qty" :min="0" style="width:100%" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="skuDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="skuSubmitting" @click="submitSku">
          {{ isEditMode ? '保存修改' : '确认新增' }}
        </el-button>
      </template>
    </el-dialog>

    <!-- ═══════ 详情抽屉 ═══════ -->
    <el-drawer v-model="detailVisible" title="产品详细档案" size="420px">
      <el-descriptions :column="1" border direction="vertical">
        <el-descriptions-item label="产品编码 (SKU)">
          <span class="sku-bold">{{ currentDetail.sku_code }}</span>
        </el-descriptions-item>
        <el-descriptions-item label="中文名称">{{ currentDetail.name }}</el-descriptions-item>
        <el-descriptions-item label="所属分类">{{ currentDetail.category_name || '-' }}</el-descriptions-item>
        <el-descriptions-item label="包装规格">{{ currentDetail.spec || '-' }}</el-descriptions-item>
        <el-descriptions-item label="标准指导价">
          <b>￥{{ currentDetail.standard_price?.toFixed(2) }}</b>
        </el-descriptions-item>
        <el-descriptions-item label="当前库存">
          {{ currentDetail.stock_qty }} {{ currentDetail.unit }}
        </el-descriptions-item>
        <el-descriptions-item label="预警阈值">{{ currentDetail.warning_threshold }} {{ currentDetail.unit }}</el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ currentDetail.created_at }}</el-descriptions-item>
        <el-descriptions-item label="更新时间">{{ currentDetail.updated_at }}</el-descriptions-item>
      </el-descriptions>
    </el-drawer>

    <!-- ═══════ 库存变更弹窗 ═══════ -->
    <el-dialog v-model="invDialogVisible" title="库存变更" width="500px" destroy-on-close>
      <el-alert
        :title="`当前操作：${currentInvSku.name}（${currentInvSku.sku_code}）— 现有库存 ${currentInvSku.stock_qty} ${currentInvSku.unit || '件'}`"
        type="info" show-icon :closable="false" style="margin-bottom:20px"
      />
      <el-form ref="invFormRef" :model="invForm" :rules="invRules" label-width="90px">
        <el-form-item label="变更方向">
          <el-radio-group v-model="invForm.direction" @change="invForm.reason = invForm.direction === 'in' ? 'purchase' : 'shipment'">
            <el-radio-button value="in">📦 入库</el-radio-button>
            <el-radio-button value="out">📤 出库</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="变动原因" prop="reason">
          <el-select v-model="invForm.reason" style="width:100%">
            <template v-if="invForm.direction === 'in'">
              <el-option v-for="r in inReasons" :key="r.value" :label="r.label" :value="r.value" />
            </template>
            <template v-else>
              <el-option v-for="r in outReasons" :key="r.value" :label="r.label" :value="r.value" />
            </template>
          </el-select>
        </el-form-item>
        <el-form-item label="变更数量" prop="qty">
          <el-input-number v-model="invForm.qty" :min="1" :max="99999" controls-position="right" style="width:100%" />
        </el-form-item>
        <el-form-item label="操作备注">
          <el-input v-model="invForm.remark" type="textarea" :rows="2" placeholder="非必填，记录特殊单号或说明" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="invDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="invSubmitting" @click="submitInventory">确认变更</el-button>
      </template>
    </el-dialog>

    <!-- ═══════ 批量导入弹窗 ═══════ -->
    <el-dialog v-model="importDialogVisible" title="批量导入产品 SKU" width="400px" destroy-on-close>
      <div style="margin-bottom: 20px; line-height: 1.6;">
        <p>1. 请先下载标准模板，按要求填写数据；</p>
        <p>2. 仅支持 .xlsx 格式文件；</p>
        <p>3. 系统将根据 SKU 编码自动防重。</p>
        <p style="margin-top: 10px;">
          <a href="/api/templates/product_import_template.xlsx" target="_blank" style="color: #409eff; text-decoration: none;">
            ⬇️ 点击下载《产品导入模板.xlsx》
          </a>
        </p>
      </div>
      <el-upload
        drag
        action="/api/products/import"
        :headers="getUploadHeaders()"
        accept=".xlsx,.xls"
        :show-file-list="false"
        :on-success="handleImportSuccess"
        :on-error="handleImportError"
      >
        <el-icon class="el-icon--upload"><Upload /></el-icon>
        <div class="el-upload__text">将文件拖到此处，或 <em>点击上传</em></div>
      </el-upload>
    </el-dialog>
  </div>
</template>

<style scoped>
.product-management-wrapper { height: 100%; }
.page-row { height: 100%; }
.tree-card { height: calc(100vh - 100px); border-radius: 8px; border: none; box-shadow: 0 1px 4px rgba(0,21,41,0.08); overflow-y: auto; }
.card-header { display: flex; justify-content: space-between; align-items: center; }
.card-header .tree-title { font-weight: bold; font-size: 15px; color: #303133; }
.filter-tree { margin-top: -10px; }

/* 树节点 — 悬浮显示操作按钮 */
.tree-node { display: flex; align-items: center; justify-content: space-between; width: 100%; padding-right: 4px; }
.tree-node-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-node-actions { display: none; flex-shrink: 0; margin-left: 6px; }
.tree-node:hover .tree-node-actions { display: inline-flex; gap: 4px; }
.tree-action-icon { font-size: 14px; cursor: pointer; color: #909399; transition: color 0.2s; }
.tree-action-icon:hover { color: #409eff; }
.tree-action-icon.danger:hover { color: #f56c6c; }

.right-col { display: flex; flex-direction: column; gap: 15px; }
.filter-card { border-radius: 8px; border: none; box-shadow: 0 1px 4px rgba(0,21,41,0.08); }
.filter-wrapper { display: flex; justify-content: space-between; align-items: center; }
.filter-form .el-form-item { margin-bottom: 0; }
.table-card { flex: 1; border-radius: 8px; border: none; box-shadow: 0 1px 4px rgba(0,21,41,0.08); }
.sku-bold { font-family: Consolas, 'Courier New', monospace; font-weight: bold; color: #409eff; }
.normal-stock { font-weight: bold; color: #606266; }
</style>
