<template>
  <div class="warehouse-page">
    <el-card shadow="never" class="warehouse-card">
      <template #header>
        <div class="page-header">
          <div>
            <h2>仓储管理</h2>
            <p>仓库→库区→货位；物料类型/实例绑定（无数量）；在库与库存事件审计。</p>
          </div>
          <el-button :icon="Refresh" :loading="loading" @click="loadAll">刷新</el-button>
        </div>
      </template>

      <el-tabs v-model="activeGroup">
        <el-tab-pane label="基础资料" name="master">
          <el-tabs v-model="activeMaster" lazy>
            <el-tab-pane label="库区" name="areas">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索编码/名称" clearable />
                <el-button type="primary" @click="openArea()">新增库区</el-button>
                <el-button type="danger" :disabled="batchAreas.batchCount === 0" @click="batchDeleteAreas">批量删除 ({{ batchAreas.batchCount }})</el-button>
              </div>
              <el-table :data="filteredAreas" border size="small" @selection-change="batchAreas.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchAreas.selectable" />
                <el-table-column prop="code" label="编码" width="120" />
                <el-table-column prop="name" label="名称" />
                <el-table-column prop="type" label="类型" width="100" />
                <el-table-column label="布局" width="80"><template #default="{ row }">{{ labelOf(AREA_LAYOUT_MODES, row.layoutMode) }}</template></el-table-column>
                <el-table-column prop="sortOrder" label="排序" width="70" />
                <el-table-column prop="enabled" label="启用" width="80"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column prop="isLock" label="锁定" width="80"><template #default="{ row }"><el-tag :type="row.isLock ? 'warning' : 'info'" size="small">{{ row.isLock ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="备注" show-overflow-tooltip><template #default="{ row }">{{ truncate(row.remark) }}</template></el-table-column>
                <el-table-column label="操作" width="150" fixed="right"><template #default="{ row }"><el-button size="small" link :disabled="row.isLock" @click="openArea(row)">编辑</el-button><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeArea(row)">删除</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="库位" name="storages">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索编码/名称/站点" clearable />
                <el-button type="primary" @click="openStorage()">新增库位</el-button>
                <el-button @click="openGenerateBins">批量生成网格</el-button>
                <el-button type="danger" :disabled="batchStorages.batchCount === 0" @click="batchDeleteStorages">批量删除 ({{ batchStorages.batchCount }})</el-button>
              </div>
              <el-table :data="filteredStorages" border size="small" @selection-change="batchStorages.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchStorages.selectable" />
                <el-table-column prop="code" label="编码" width="110" />
                <el-table-column prop="name" label="名称" min-width="100" />
                <el-table-column label="库区" width="100"><template #default="{ row }">{{ areaName(row.areaId) }}</template></el-table-column>
                <el-table-column label="类型" width="100"><template #default="{ row }">{{ labelOf(STORAGE_TYPES, row.storageType) }}</template></el-table-column>
                <el-table-column prop="siteId" label="站点" width="90" />
                <el-table-column label="状态" width="100"><template #default="{ row }"><el-tag :type="STORAGE_STATUS_TYPE[row.status] ?? 'info'" size="small">{{ labelOf(STORAGE_STATUSES, row.status) }}</el-tag></template></el-table-column>
                <el-table-column label="种类" width="90"><template #default="{ row }">{{ labelOf(LOCATION_KINDS, row.locationKind) }}</template></el-table-column>
                <el-table-column label="列/层/深" width="100"><template #default="{ row }">{{ row.locationKind === 'Grid' ? `${row.columnNo}/${row.levelNo}/${row.depthNo}` : '—' }}</template></el-table-column>
                <el-table-column prop="priority" label="优先级" width="70" />
                <el-table-column prop="zoneCode" label="区域" width="80" />
                <el-table-column label="占用" width="70"><template #default="{ row }"><el-tag :type="isStorageOccupied(row.id) ? 'warning' : 'success'" size="small">{{ isStorageOccupied(row.id) ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="入库" width="60"><template #default="{ row }">{{ row.allowInbound ? '是' : '否' }}</template></el-table-column>
                <el-table-column label="出库" width="60"><template #default="{ row }">{{ row.allowOutbound ? '是' : '否' }}</template></el-table-column>
                <el-table-column prop="enabled" label="启用" width="70"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="操作" width="150" fixed="right"><template #default="{ row }"><el-button size="small" link :disabled="row.isLock" @click="openStorage(row)">编辑</el-button><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeStorage(row)">删除</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="容器" name="containers">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索编码/名称" clearable />
                <el-button type="primary" @click="openContainer()">新增容器</el-button>
                <el-button type="danger" :disabled="batchContainers.batchCount === 0" @click="batchDeleteContainers">批量删除 ({{ batchContainers.batchCount }})</el-button>
              </div>
              <el-table :data="filteredContainers" border size="small" @selection-change="batchContainers.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchContainers.selectable" />
                <el-table-column prop="code" label="编码" width="120" />
                <el-table-column prop="name" label="名称" />
                <el-table-column label="类型" width="90"><template #default="{ row }">{{ labelOf(CONTAINER_TYPES, row.containerType) }}</template></el-table-column>
                <el-table-column label="状态" width="90"><template #default="{ row }">{{ labelOf(CONTAINER_STATUSES, row.status) }}</template></el-table-column>
                <el-table-column label="当前位置" min-width="120"><template #default="{ row }">{{ containerLocationLabel(row.id) }}</template></el-table-column>
                <el-table-column prop="enabled" label="启用" width="70"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column prop="isLock" label="锁定" width="70"><template #default="{ row }"><el-tag :type="row.isLock ? 'warning' : 'info'" size="small">{{ row.isLock ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="操作" width="150" fixed="right"><template #default="{ row }"><el-button size="small" link :disabled="row.isLock" @click="openContainer(row)">编辑</el-button><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeContainer(row)">删除</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="物料类型" name="materialTypes">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索编码/名称" clearable />
                <el-button type="primary" @click="openMaterialType()">新增类型</el-button>
                <el-button type="danger" :disabled="batchMaterialTypes.batchCount === 0" @click="batchDeleteMaterialTypes">批量删除 ({{ batchMaterialTypes.batchCount }})</el-button>
              </div>
              <el-table :data="filteredMaterialTypes" border size="small" @selection-change="batchMaterialTypes.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchMaterialTypes.selectable" />
                <el-table-column prop="code" label="编码" width="120" />
                <el-table-column prop="name" label="名称" />
                <el-table-column prop="spec" label="规格" />
                <el-table-column prop="unit" label="单位" width="70" />
                <el-table-column prop="category" label="类别" width="100" />
                <el-table-column prop="barcodePrefix" label="条码前缀" width="100" />
                <el-table-column prop="enabled" label="启用" width="70"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="操作" width="150" fixed="right"><template #default="{ row }"><el-button size="small" link :disabled="row.isLock" @click="openMaterialType(row)">编辑</el-button><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeMaterialType(row)">删除</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="物料" name="materials">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索编码/名称/规格" clearable />
                <el-select v-model="materialLifecycleFilter" clearable placeholder="生命周期" style="width: 120px" @change="reloadMaterials">
                  <el-option v-for="o in MATERIAL_LIFECYCLES" :key="o.value" :label="o.label" :value="o.value" />
                </el-select>
                <el-button type="primary" @click="openMaterial()">新增物料</el-button>
                <el-button type="danger" :disabled="batchMaterials.batchCount === 0" @click="batchDeleteMaterials">批量删除 ({{ batchMaterials.batchCount }})</el-button>
              </div>
              <el-table :data="filteredMaterials" border size="small" @selection-change="batchMaterials.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchMaterials.selectable" />
                <el-table-column prop="code" label="编码" width="120" />
                <el-table-column prop="name" label="名称" />
                <el-table-column prop="typeCode" label="类型" width="100" />
                <el-table-column prop="barcode" label="条码" width="120" show-overflow-tooltip />
                <el-table-column prop="spec" label="规格" />
                <el-table-column prop="unit" label="单位" width="70" />
                <el-table-column label="生命周期" width="90"><template #default="{ row }"><el-tag :type="row.lifecycleStatus === 'Active' ? 'success' : 'info'" size="small">{{ labelOf(MATERIAL_LIFECYCLES, row.lifecycleStatus) }}</el-tag></template></el-table-column>
                <el-table-column prop="enabled" label="启用" width="70"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="操作" width="200" fixed="right">
                  <template #default="{ row }">
                    <el-button size="small" link :disabled="row.isLock" @click="openMaterial(row)">编辑</el-button>
                    <el-button v-if="row.lifecycleStatus === 'Active'" size="small" link :disabled="row.isLock" @click="archiveMaterial(row)">归档</el-button>
                    <el-button size="small" link type="danger" :disabled="row.isLock" @click="removeMaterial(row)">删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="库区立面" name="facade" lazy>
              <AreaFacadePanel :areas="areas" :storages="storages" @edit="openStorage" />
            </el-tab-pane>
          </el-tabs>
        </el-tab-pane>

        <el-tab-pane label="关系与历史" name="relations" lazy>
          <el-tabs v-model="activeRelation" lazy>
            <el-tab-pane label="容器位置" name="locations">
              <div class="toolbar">
                <el-select v-model="locationFilter" clearable placeholder="位置类型"><el-option label="库位" value="Storage" /><el-option label="车辆" value="Car" /></el-select>
                <el-input v-model="keyword" placeholder="搜索位置编码/名称" clearable />
                <el-button type="primary" @click="openLocation()">绑定/转移</el-button>
                <el-button type="danger" :disabled="batchLocations.batchCount === 0" @click="batchUnbindLocations">批量解绑 ({{ batchLocations.batchCount }})</el-button>
              </div>
              <el-table :data="filteredContainerLocations" border size="small" @selection-change="batchLocations.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchLocations.selectable" />
                <el-table-column label="容器" width="140"><template #default="{ row }">{{ containerName(row.containerId) }}</template></el-table-column>
                <el-table-column prop="locationType" label="位置类型" width="90" />
                <el-table-column prop="locationCode" label="位置编码" width="120" />
                <el-table-column prop="locationName" label="位置名称" />
                <el-table-column label="状态" width="80"><template #default="{ row }">{{ labelOf(CONTAINER_LOCATION_STATUSES, row.status) }}</template></el-table-column>
                <el-table-column prop="enteredAt" label="进入时间" width="170" />
                <el-table-column label="操作" width="90" fixed="right"><template #default="{ row }"><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeLocation(row)">解绑</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="容器物料" name="materials">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索" clearable />
                <el-button type="primary" @click="openContainerMaterial()">绑定物料</el-button>
                <el-button type="danger" :disabled="batchContainerMaterials.batchCount === 0" @click="batchUnloadMaterials">批量解绑 ({{ batchContainerMaterials.batchCount }})</el-button>
              </div>
              <el-table :data="filteredContainerMaterials" border size="small" @selection-change="batchContainerMaterials.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchContainerMaterials.selectable" />
                <el-table-column label="容器" width="140"><template #default="{ row }">{{ containerName(row.containerId) }}</template></el-table-column>
                <el-table-column label="物料" width="180"><template #default="{ row }">{{ materialName(row.materialId) }}</template></el-table-column>
                <el-table-column prop="status" label="状态" width="90" />
                <el-table-column prop="boundAt" label="绑定时间" width="170" />
                <el-table-column label="操作" width="180" fixed="right">
                  <template #default="{ row }">
                    <el-button size="small" link type="danger" :disabled="row.isLock" @click="removeContainerMaterial(row, false)">解绑</el-button>
                    <el-button size="small" link type="warning" :disabled="row.isLock" @click="removeContainerMaterial(row, true)">解绑并归档</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="在库物料" name="inventory">
              <div class="toolbar">
                <el-input v-model="keyword" placeholder="搜索物料/容器/货位" clearable />
                <el-button @click="loadInventory">刷新</el-button>
              </div>
              <el-table :data="filteredInventory" border size="small">
                <el-table-column prop="materialCode" label="物料编码" width="120" />
                <el-table-column prop="materialName" label="物料名称" />
                <el-table-column prop="containerCode" label="容器" width="100" />
                <el-table-column prop="storageCode" label="货位" width="100" />
                <el-table-column prop="areaCode" label="库区" width="90" />
                <el-table-column prop="boundAt" label="绑定时间" width="170" />
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="库存事件" name="stockEvents">
              <el-table :data="stockEvents" border size="small">
                <el-table-column prop="eventType" label="事件" width="120" />
                <el-table-column prop="materialCode" label="物料" width="120" />
                <el-table-column prop="containerCode" label="容器" width="100" />
                <el-table-column prop="storageCode" label="货位" width="100" />
                <el-table-column prop="fromStorageCode" label="从" width="90" />
                <el-table-column prop="toStorageCode" label="到" width="90" />
                <el-table-column prop="operator" label="操作人" width="100" />
                <el-table-column prop="operatedAt" label="时间" width="170" />
                <el-table-column prop="reason" label="原因" show-overflow-tooltip />
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="历史记录" name="history">
              <el-table :data="historyRows" border size="small">
                <el-table-column prop="kind" label="类型" width="80" />
                <el-table-column prop="eventType" label="事件" width="100" />
                <el-table-column label="容器" width="120"><template #default="{ row }">{{ row.containerId ? containerName(row.containerId) : '—' }}</template></el-table-column>
                <el-table-column label="库位/位置" min-width="120"><template #default="{ row }">{{ historyLocationLabel(row) }}</template></el-table-column>
                <el-table-column prop="operator" label="操作人" width="100" />
                <el-table-column prop="operatedAt" label="时间" width="170" />
                <el-table-column prop="reason" label="原因" show-overflow-tooltip />
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-tab-pane>

        <el-tab-pane label="搬运配置" name="transport" lazy>
          <el-tabs v-model="activeTransport" lazy>
            <el-tab-pane label="搬运规则" name="rules">
              <div class="toolbar">
                <el-select v-model="ruleTriggerFilter" clearable placeholder="触发类型">
                  <el-option label="呼叫物料" value="MaterialCall" />
                  <el-option label="成品下线" value="FinishedGoodsOffline" />
                  <el-option label="自动转运" value="AutoTransfer" />
                </el-select>
                <el-button type="primary" @click="openRule()">新增规则</el-button>
                <el-button type="danger" :disabled="batchRules.batchCount === 0" @click="batchDeleteRules">批量删除 ({{ batchRules.batchCount }})</el-button>
              </div>
              <el-table :data="filteredRules" border size="small" @selection-change="batchRules.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="batchRules.selectable" />
                <el-table-column prop="code" label="编码" width="120" />
                <el-table-column prop="name" label="名称" />
                <el-table-column label="触发类型" width="120"><template #default="{ row }">{{ TRANSPORT_TRIGGER_LABELS[row.triggerType] ?? row.triggerType }}</template></el-table-column>
                <el-table-column prop="priority" label="优先级" width="80" />
                <el-table-column prop="enabled" label="启用" width="70"><template #default="{ row }"><el-tag :type="row.enabled ? 'success' : 'info'" size="small">{{ row.enabled ? '是' : '否' }}</el-tag></template></el-table-column>
                <el-table-column label="操作" width="150" fixed="right"><template #default="{ row }"><el-button size="small" link :disabled="row.isLock" @click="openRule(row)">编辑</el-button><el-button size="small" link type="danger" :disabled="row.isLock" @click="removeRule(row)">删除</el-button></template></el-table-column>
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="候选预览" name="candidates">
              <el-form inline class="preview-form">
                <el-form-item label="触发类型"><el-select v-model="previewForm.triggerType"><el-option label="呼叫物料" value="MaterialCall" /><el-option label="成品下线" value="FinishedGoodsOffline" /><el-option label="自动转运" value="AutoTransfer" /></el-select></el-form-item>
                <el-form-item label="呼叫站点"><el-input v-model="previewForm.requestSiteId" placeholder="站点 ID" /></el-form-item>
                <el-form-item label="物料"><el-select v-model="previewForm.materialId" clearable><el-option v-for="m in materials" :key="m.id" :label="m.code" :value="m.id" /></el-select></el-form-item>
                <el-form-item label="容器"><el-select v-model="previewForm.containerId" clearable><el-option v-for="c in containers" :key="c.id" :label="c.code" :value="c.id" /></el-select></el-form-item>
                <el-form-item><el-button type="primary" :loading="previewLoading" @click="runPreview">预览候选</el-button><el-button type="success" :loading="previewLoading" @click="generateFromPreview">生成任务</el-button></el-form-item>
              </el-form>
              <el-table :data="previewResult?.candidates ?? []" border size="small">
                <el-table-column prop="ruleCode" label="规则" width="110" />
                <el-table-column prop="sourceStorageCode" label="起点库位" width="110" />
                <el-table-column prop="targetStorageCode" label="终点库位" width="110" />
                <el-table-column prop="containerCode" label="容器" width="100" />
                <el-table-column prop="materialCode" label="物料" width="100" />
                <el-table-column prop="score" label="评分" width="70" />
              </el-table>
            </el-tab-pane>

            <el-tab-pane label="搬运任务" name="tasks">
              <div class="toolbar">
                <el-select v-model="taskStatusFilter" clearable placeholder="状态" @change="loadTransportTasks"><el-option v-for="s in taskStatuses" :key="s" :label="s" :value="s" /></el-select>
                <el-button @click="loadTransportTasks">刷新</el-button>
                <el-button type="danger" :disabled="batchTasks.batchCount === 0" @click="batchCancelTasks">批量取消 ({{ batchTasks.batchCount }})</el-button>
              </div>
              <el-table :data="transportTasks" border size="small" @selection-change="batchTasks.onSelectionChange">
                <el-table-column type="selection" width="42" :selectable="taskSelectable" />
                <el-table-column label="业务类型" width="110"><template #default="{ row }">{{ TRANSPORT_TRIGGER_LABELS[row.businessType] ?? row.businessType }}</template></el-table-column>
                <el-table-column label="起点" width="100"><template #default="{ row }">{{ storageCode(row.sourceStorageId) }}</template></el-table-column>
                <el-table-column label="终点" width="100"><template #default="{ row }">{{ storageCode(row.targetStorageId) }}</template></el-table-column>
                <el-table-column label="容器" width="100"><template #default="{ row }">{{ containerName(row.containerId) }}</template></el-table-column>
                <el-table-column label="状态" width="100"><template #default="{ row }"><el-tag :type="TRANSPORT_TASK_STATUS_TYPE[row.status] ?? 'info'" size="small">{{ row.status }}</el-tag></template></el-table-column>
                <el-table-column prop="taskPriority" label="优先级" width="70" />
                <el-table-column prop="createdAt" label="创建时间" width="170" />
                <el-table-column prop="reason" label="原因" show-overflow-tooltip />
                <el-table-column prop="errorMessage" label="错误" show-overflow-tooltip />
                <el-table-column label="操作" width="220" fixed="right">
                  <template #default="{ row }">
                    <el-button v-if="row.status === 'Pending'" size="small" link @click="reserveTask(row)">预占</el-button>
                    <el-button v-if="row.status === 'Reserved'" size="small" link @click="completeTask(row)">完成</el-button>
                    <el-button v-if="['Pending','Reserved','Failed'].includes(row.status)" size="small" link type="danger" @click="cancelTask(row)">取消</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <WmsEntityDialog
      v-model:visible="dialogVisible"
      v-model:area-layout-mode="areaLayoutMode"
      v-model:container-barcode="containerBarcode"
      :kind="dialogKind"
      :saving="saving"
      :areas="areas"
      :storages="storages"
      :containers="containers"
      :materials="materials"
      :material-types="materialTypes"
      :occupied-storage-ids="occupiedStorageIds"
      :master-form="masterForm"
      :storage-form="storageForm"
      :material-form="materialForm"
      :material-type-form="materialTypeForm"
      :location-form="locationForm"
      :container-material-form="containerMaterialForm"
      :rule-form="ruleForm"
      @save="submitDialog"
    />

    <el-dialog v-model="generateBinsVisible" title="批量生成网格货位" width="480px">
      <el-form label-width="100px">
        <el-form-item label="库区">
          <el-select v-model="generateBinsAreaId"><el-option v-for="a in areas" :key="a.id" :label="a.name" :value="a.id" /></el-select>
        </el-form-item>
        <el-form-item label="列范围">
          <el-input-number v-model="generateBinsForm.columnFrom" :min="1" />
          <span style="margin: 0 8px">~</span>
          <el-input-number v-model="generateBinsForm.columnTo" :min="1" />
        </el-form-item>
        <el-form-item label="层范围">
          <el-input-number v-model="generateBinsForm.levelFrom" :min="1" />
          <span style="margin: 0 8px">~</span>
          <el-input-number v-model="generateBinsForm.levelTo" :min="1" />
        </el-form-item>
        <el-form-item label="进深范围">
          <el-input-number v-model="generateBinsForm.depthFrom" :min="1" />
          <span style="margin: 0 8px">~</span>
          <el-input-number v-model="generateBinsForm.depthTo" :min="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="generateBinsVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="submitGenerateBins">生成</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Refresh } from '@element-plus/icons-vue'
import * as wmsApi from '@/api/wms'
import WmsEntityDialog, { type DialogKind } from '@/views/admin/warehouse/WmsEntityDialog.vue'
import AreaFacadePanel from '@/views/admin/warehouse/AreaFacadePanel.vue'
import { useWmsBatchActions } from '@/views/admin/warehouse/useWmsBatchActions'
import {
  AREA_LAYOUT_MODES, STORAGE_TYPES, STORAGE_STATUSES, STORAGE_STATUS_TYPE, LOCATION_KINDS,
  CONTAINER_TYPES, CONTAINER_STATUSES, CONTAINER_LOCATION_STATUSES, MATERIAL_LIFECYCLES,
  TRANSPORT_TRIGGER_LABELS, TRANSPORT_TASK_STATUS_TYPE, labelOf, truncate
} from '@/views/admin/warehouse/wmsOptions'
import type {
  WarehouseArea, Storage, Container, Material, MaterialType, ContainerLocation, ContainerMaterial,
  ContainerLocationHistory, ContainerMaterialHistory, InventoryMaterialRow, StockEvent,
  MasterDataPayload, StoragePayload, MaterialPayload, MaterialTypePayload, ContainerLocationPayload, BindMaterialPayload,
  WmsTransportRule, WmsTransportTask, TransportRulePayload, TransportRequestQuery, TransportCandidatePreview
} from '@/types/wms'

const activeGroup = ref('master')
const activeMaster = ref('areas')
const activeRelation = ref('locations')
const activeTransport = ref('rules')
const keyword = ref('')
const locationFilter = ref('')
const ruleTriggerFilter = ref('')
const taskStatusFilter = ref('')
const materialLifecycleFilter = ref('Active')
const previewLoading = ref(false)
const taskStatuses = ['Pending', 'Reserved', 'Dispatched', 'InTransit', 'Completed', 'Failed', 'Cancelled']
const loading = ref(false)
const saving = ref(false)
const dialogVisible = ref(false)
const dialogKind = ref<DialogKind>('area')
const areaLayoutMode = ref('Flat')
const containerBarcode = ref('')
const generateBinsVisible = ref(false)
const generateBinsAreaId = ref('')
const generateBinsForm = reactive({ columnFrom: 1, columnTo: 5, levelFrom: 1, levelTo: 3, depthFrom: 1, depthTo: 1 })

const areas = ref<WarehouseArea[]>([])
const storages = ref<Storage[]>([])
const containers = ref<Container[]>([])
const materialTypes = ref<MaterialType[]>([])
const materials = ref<Material[]>([])
const containerLocations = ref<ContainerLocation[]>([])
const containerMaterials = ref<ContainerMaterial[]>([])
const inventoryRows = ref<InventoryMaterialRow[]>([])
const stockEvents = ref<StockEvent[]>([])
const locationHistory = ref<ContainerLocationHistory[]>([])
const materialHistory = ref<ContainerMaterialHistory[]>([])
const transportRules = ref<WmsTransportRule[]>([])
const transportTasks = ref<WmsTransportTask[]>([])
const previewResult = ref<TransportCandidatePreview | null>(null)

const masterForm = reactive<MasterDataPayload>(baseMaster())
const storageForm = reactive<StoragePayload>(baseStorage())
const materialForm = reactive<MaterialPayload>(baseMaterial())
const materialTypeForm = reactive<MaterialTypePayload>(baseMaterialType())
const locationForm = reactive<ContainerLocationPayload>(baseLocation())
const containerMaterialForm = reactive<BindMaterialPayload>(baseContainerMaterial())
const ruleForm = reactive<TransportRulePayload>(baseRule())
const previewForm = reactive<TransportRequestQuery>({ triggerType: 'MaterialCall', priority: 0, reason: '' })

const batchAreas = useWmsBatchActions<WarehouseArea>()
const batchStorages = useWmsBatchActions<Storage>()
const batchContainers = useWmsBatchActions<Container>()
const batchMaterialTypes = useWmsBatchActions<MaterialType>()
const batchMaterials = useWmsBatchActions<Material>()
const batchRules = useWmsBatchActions<WmsTransportRule>()
const batchLocations = useWmsBatchActions<ContainerLocation>()
const batchContainerMaterials = useWmsBatchActions<ContainerMaterial>()
const batchTasks = useWmsBatchActions<WmsTransportTask>()

const occupiedStorageIds = computed(() => {
  const set = new Set<string>()
  for (const loc of containerLocations.value) {
    if (loc.locationType === 'Storage') set.add(loc.locationId)
  }
  return set
})

const filteredAreas = computed(() => filterRows(areas.value, keyword.value))
const filteredStorages = computed(() => filterRows(storages.value, keyword.value))
const filteredContainers = computed(() => filterRows(containers.value, keyword.value))
const filteredMaterialTypes = computed(() => filterRows(materialTypes.value, keyword.value))
const filteredMaterials = computed(() => filterRows(materials.value, keyword.value))
const filteredContainerLocations = computed(() => containerLocations.value.filter((r) =>
  (!locationFilter.value || r.locationType === locationFilter.value) &&
  (!keyword.value || `${r.locationCode} ${r.locationName}`.toLowerCase().includes(keyword.value.toLowerCase()))))
const filteredContainerMaterials = computed(() => filterRows(containerMaterials.value, keyword.value))
const filteredInventory = computed(() => {
  if (!keyword.value) return inventoryRows.value
  const s = keyword.value.toLowerCase()
  return inventoryRows.value.filter((r) =>
    `${r.materialCode} ${r.materialName} ${r.containerCode} ${r.storageCode} ${r.areaCode}`.toLowerCase().includes(s))
})
const filteredRules = computed(() => transportRules.value.filter((r) => !ruleTriggerFilter.value || r.triggerType === ruleTriggerFilter.value))
const historyRows = computed(() => [
  ...locationHistory.value.map((x) => ({ ...x, kind: '位置' })),
  ...materialHistory.value.map((x) => ({ ...x, kind: '物料' }))
].sort((a, b) => String(b.operatedAt).localeCompare(String(a.operatedAt))))

function isStorageOccupied(id: string) { return occupiedStorageIds.value.has(id) }
function taskSelectable(row: WmsTransportTask) {
  return !row.isLock && ['Pending', 'Reserved', 'Failed'].includes(row.status)
}

async function reloadMaterials() {
  materials.value = await wmsApi.listMaterials({
    lifecycle: materialLifecycleFilter.value || undefined
  })
}

async function loadAll() {
  loading.value = true
  try {
    const [a, s, c, mt, m, cl, cm, lh, mh, inv, ev] = await Promise.all([
      wmsApi.listAreas(), wmsApi.listStorages(), wmsApi.listContainers(), wmsApi.listMaterialTypes(),
      wmsApi.listMaterials({ lifecycle: materialLifecycleFilter.value || undefined }),
      wmsApi.listContainerLocations(), wmsApi.listContainerMaterials(), wmsApi.listContainerLocationHistory(), wmsApi.listContainerMaterialHistory(),
      wmsApi.listInventoryMaterials(), wmsApi.listStockEvents()
    ])
    areas.value = a; storages.value = s; containers.value = c; materialTypes.value = mt; materials.value = m
    containerLocations.value = cl; containerMaterials.value = cm; locationHistory.value = lh; materialHistory.value = mh
    inventoryRows.value = inv; stockEvents.value = ev
    await loadTransportRules()
    await loadTransportTasks()
  } finally {
    loading.value = false
  }
}

async function loadInventory() {
  inventoryRows.value = await wmsApi.listInventoryMaterials()
  stockEvents.value = await wmsApi.listStockEvents()
}

function openArea(row?: WarehouseArea) {
  dialogKind.value = 'area'
  Object.assign(masterForm, baseMaster(row))
  areaLayoutMode.value = row?.layoutMode ?? 'Flat'
  dialogVisible.value = true
}
function openStorage(row?: Storage) { dialogKind.value = 'storage'; Object.assign(storageForm, baseStorage(row)); dialogVisible.value = true }
function openContainer(row?: Container) {
  dialogKind.value = 'container'
  Object.assign(masterForm, baseMaster(row))
  if (row) masterForm.type = row.containerType
  containerBarcode.value = row?.barcode ?? ''
  dialogVisible.value = true
}
function openMaterialType(row?: MaterialType) { dialogKind.value = 'materialType'; Object.assign(materialTypeForm, baseMaterialType(row)); dialogVisible.value = true }
function openMaterial(row?: Material) { dialogKind.value = 'material'; Object.assign(materialForm, baseMaterial(row)); dialogVisible.value = true }
function openLocation(row?: ContainerLocation) { dialogKind.value = 'location'; Object.assign(locationForm, baseLocation(row)); dialogVisible.value = true }
function openContainerMaterial(row?: ContainerMaterial) { dialogKind.value = 'containerMaterial'; Object.assign(containerMaterialForm, baseContainerMaterial(row)); dialogVisible.value = true }
function openRule(row?: WmsTransportRule) { dialogKind.value = 'rule'; Object.assign(ruleForm, baseRule(row)); dialogVisible.value = true }
function openGenerateBins() {
  generateBinsAreaId.value = areas.value[0]?.id ?? ''
  generateBinsVisible.value = true
}

async function submitGenerateBins() {
  if (!generateBinsAreaId.value) { ElMessage.warning('请选择库区'); return }
  saving.value = true
  try {
    const r = await wmsApi.generateBins(generateBinsAreaId.value, { ...generateBinsForm })
    ElMessage.success(`已生成 ${r.created} 个货位`)
    generateBinsVisible.value = false
    await loadAll()
  } catch (e) {
    ElMessage.error(e instanceof Error ? e.message : String(e))
  } finally { saving.value = false }
}

async function loadTransportRules() { transportRules.value = await wmsApi.listTransportRules() }
async function loadTransportTasks() { transportTasks.value = await wmsApi.listTransportTasks({ status: taskStatusFilter.value || undefined }) }

async function runPreview() {
  previewLoading.value = true
  try {
    previewResult.value = await wmsApi.previewTransportCandidates({ ...previewForm })
    ElMessage.success(`找到 ${previewResult.value.candidates.length} 个候选`)
  } finally { previewLoading.value = false }
}

async function generateFromPreview() {
  previewLoading.value = true
  try {
    await wmsApi.generateTransportTask({ ...previewForm })
    ElMessage.success('任务已生成')
    await loadTransportTasks()
    activeGroup.value = 'transport'
    activeTransport.value = 'tasks'
  } finally { previewLoading.value = false }
}

async function submitDialog() {
  saving.value = true
  const kind = dialogKind.value
  try {
    const extendSrc = kind === 'storage' ? storageForm
      : kind === 'material' ? materialForm
      : kind === 'materialType' ? materialTypeForm
      : kind === 'rule' ? ruleForm
      : masterForm
    JSON.parse(extendSrc.extend || '{}')
    if (kind === 'area') {
      await wmsApi.saveArea({
        ...masterForm,
        warehouseId: undefined,
        layoutMode: areaLayoutMode.value,
        state: 'Default'
      })
    }
    else if (kind === 'container') {
      await wmsApi.saveContainer({
        ...masterForm,
        barcode: containerBarcode.value,
        length: 0, width: 0, height: 0,
        status: 'EmptyMaterial'
      })
    }
    else if (kind === 'storage') await wmsApi.saveStorage(storageForm)
    else if (kind === 'materialType') await wmsApi.saveMaterialType(materialTypeForm)
    else if (kind === 'material') await wmsApi.saveMaterial(materialForm)
    else if (kind === 'location') await wmsApi.saveContainerLocation(locationForm)
    else if (kind === 'rule') {
      JSON.parse(ruleForm.sourceSelectorJson || '{}')
      JSON.parse(ruleForm.targetSelectorJson || '{}')
      JSON.parse(ruleForm.taskOptionsJson || '{}')
      await wmsApi.saveTransportRule(ruleForm)
    }
    else await wmsApi.bindMaterial(containerMaterialForm)
    ElMessage.success('已保存')
    dialogVisible.value = false
    await loadAll()
    if (kind === 'rule') await loadTransportRules()
  } catch (e) {
    ElMessage.error(e instanceof Error ? e.message : String(e))
  } finally {
    saving.value = false
  }
}

async function confirmDelete(message: string) {
  await ElMessageBox.confirm(message, '确认操作', { type: 'warning' })
}

async function removeArea(row: WarehouseArea) { await confirmDelete('删除该库区？'); await wmsApi.deleteArea(row.id, row.version); await loadAll() }
async function removeStorage(row: Storage) { await confirmDelete('删除该库位？'); await wmsApi.deleteStorage(row.id, row.version); await loadAll() }
async function removeContainer(row: Container) { await confirmDelete('删除该容器？'); await wmsApi.deleteContainer(row.id, row.version); await loadAll() }
async function removeMaterialType(row: MaterialType) { await confirmDelete('删除该物料类型？'); await wmsApi.deleteMaterialType(row.id, row.version); await loadAll() }
async function removeMaterial(row: Material) { await confirmDelete('删除该物料？'); await wmsApi.deleteMaterial(row.id, row.version); await loadAll() }
async function archiveMaterial(row: Material) {
  await confirmDelete(`归档物料 ${row.code}？归档后仍保留主数据，可后续 purge。`)
  await wmsApi.archiveMaterial(row.id, row.version)
  ElMessage.success('已归档')
  await loadAll()
}
async function removeLocation(row: ContainerLocation) { await confirmDelete('解绑该容器位置？'); await wmsApi.deleteContainerLocation(row.containerId); await loadAll() }
async function removeContainerMaterial(row: ContainerMaterial, archive = false) {
  await confirmDelete(archive ? '解绑并归档该物料？' : '解绑该容器物料？')
  await wmsApi.deleteContainerMaterial(row.id, undefined, archive)
  await loadAll()
}
async function removeRule(row: WmsTransportRule) { await confirmDelete('删除该规则？'); await wmsApi.deleteTransportRule(row.id, row.version); await loadTransportRules() }
async function reserveTask(row: WmsTransportTask) { await wmsApi.reserveTransportTask(row.id); ElMessage.success('已预占'); await loadTransportTasks() }
async function completeTask(row: WmsTransportTask) { await wmsApi.completeTransportTask(row.id); ElMessage.success('已完成'); await loadAll() }
async function cancelTask(row: WmsTransportTask) { await wmsApi.cancelTransportTask(row.id); ElMessage.success('已取消'); await loadTransportTasks() }

async function batchDeleteAreas() {
  const r = await batchAreas.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 个库区？', run: (row) => wmsApi.deleteArea(row.id, row.version) })
  if (r.ok > 0) await loadAll()
}
async function batchDeleteStorages() {
  const r = await batchStorages.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 个库位？', run: (row) => wmsApi.deleteStorage(row.id, row.version) })
  if (r.ok > 0) await loadAll()
}
async function batchDeleteContainers() {
  const r = await batchContainers.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 个容器？', run: (row) => wmsApi.deleteContainer(row.id, row.version) })
  if (r.ok > 0) await loadAll()
}
async function batchDeleteMaterialTypes() {
  const r = await batchMaterialTypes.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 个物料类型？', run: (row) => wmsApi.deleteMaterialType(row.id, row.version) })
  if (r.ok > 0) await loadAll()
}
async function batchDeleteMaterials() {
  const r = await batchMaterials.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 个物料？', run: (row) => wmsApi.deleteMaterial(row.id, row.version) })
  if (r.ok > 0) await loadAll()
}
async function batchDeleteRules() {
  const r = await batchRules.runBatch({ actionLabel: '批量删除', confirmMessage: '确认删除选中的 {n} 条规则？', run: (row) => wmsApi.deleteTransportRule(row.id, row.version) })
  if (r.ok > 0) await loadTransportRules()
}
async function batchUnbindLocations() {
  const r = await batchLocations.runBatch({ actionLabel: '批量解绑', confirmMessage: '确认解绑选中的 {n} 条容器位置？', run: (row) => wmsApi.deleteContainerLocation(row.containerId) })
  if (r.ok > 0) await loadAll()
}
async function batchUnloadMaterials() {
  const r = await batchContainerMaterials.runBatch({ actionLabel: '批量卸料', confirmMessage: '确认卸载选中的 {n} 条容器物料？', run: (row) => wmsApi.deleteContainerMaterial(row.id) })
  if (r.ok > 0) await loadAll()
}
async function batchCancelTasks() {
  const r = await batchTasks.runBatch({
    actionLabel: '批量取消',
    confirmMessage: '确认取消选中的 {n} 个搬运任务？',
    canRun: (row) => ['Pending', 'Reserved', 'Failed'].includes(row.status),
    run: (row) => wmsApi.cancelTransportTask(row.id)
  })
  if (r.ok > 0) await loadTransportTasks()
}

function storageCode(id: string) { return storages.value.find((s) => s.id === id)?.code ?? id }
function areaName(id: string) { return areas.value.find((a) => a.id === id)?.name ?? id }
function containerName(id: string) { const c = containers.value.find((x) => x.id === id); return c ? `${c.code}` : id }
function materialName(id: string) { const m = materials.value.find((x) => x.id === id); return m ? `${m.code}` : id }
function containerLocationLabel(id: string) {
  const loc = containerLocations.value.find((x) => x.containerId === id)
  return loc ? `${loc.locationType}:${loc.locationCode || loc.locationId}` : '未绑定'
}
function historyLocationLabel(row: ContainerLocationHistory | ContainerMaterialHistory) {
  if ('toLocationId' in row && row.toLocationId) return `${row.toLocationType}:${row.toLocationId}`
  if ('fromLocationId' in row && row.fromLocationId) return `${row.fromLocationType}:${row.fromLocationId}`
  return '—'
}
function filterRows<T extends Record<string, unknown>>(rows: T[], q: string) {
  if (!q) return rows
  const s = q.toLowerCase()
  return rows.filter((r) => Object.values(r).some((v) => String(v ?? '').toLowerCase().includes(s)))
}
function baseCommon(row?: { id: string; version: number; isLock: boolean; remark: string; extend: string; updatedAt?: string }) {
  return { id: row?.id, version: row?.version, isLock: row?.isLock ?? false, remark: row?.remark ?? '', extend: row?.extend ?? '{}', updatedAt: row?.updatedAt }
}
function baseMaster(row?: WarehouseArea | Container): MasterDataPayload {
  return {
    ...baseCommon(row),
    code: row?.code ?? '',
    name: row?.name ?? '',
    type: 'type' in (row ?? {}) ? (row as WarehouseArea).type : (row as Container | undefined)?.containerType ?? 'Box',
    status: (row as Container | undefined)?.status ?? 'Idle',
    enabled: row?.enabled ?? true,
    sortOrder: (row as WarehouseArea | undefined)?.sortOrder ?? 0
  }
}
function baseStorage(row?: Storage): StoragePayload {
  return {
    ...baseCommon(row), areaId: row?.areaId ?? areas.value[0]?.id ?? '', code: row?.code ?? '', name: row?.name ?? '',
    storageType: row?.storageType ?? 'Storage', locationKind: row?.locationKind ?? 'Station',
    columnNo: row?.columnNo ?? 0, levelNo: row?.levelNo ?? 1, depthNo: row?.depthNo ?? 1,
    siteId: row?.siteId ?? '', siteCode: row?.siteCode ?? row?.siteId ?? '', barcode: row?.barcode ?? '', capacity: 1,
    status: row?.status ?? 'Empty', usage: row?.usage ?? '', priority: row?.priority ?? 0, zoneCode: row?.zoneCode ?? '',
    allowInbound: row?.allowInbound ?? true, allowOutbound: row?.allowOutbound ?? true, enabled: row?.enabled ?? true
  }
}
function baseRule(row?: WmsTransportRule): TransportRulePayload {
  const defaultSource = JSON.stringify({ schemaVersion: 1, storage: { requireOccupied: true, allowOutbound: true }, container: { excludeReserved: true }, material: {}, ranking: [{ field: 'enteredAt', direction: 'asc' }] }, null, 2)
  const defaultTarget = JSON.stringify({ schemaVersion: 1, storage: { requireEmpty: true, allowInbound: true, requireSiteId: true }, ranking: [{ field: 'storagePriority', direction: 'desc' }] }, null, 2)
  const defaultOptions = JSON.stringify({ autoReserve: true, requireManualConfirm: false, allowSameStorage: false, reservationTtlSeconds: 600, dispatchMode: 'Manual', maxCandidateCount: 20 }, null, 2)
  return {
    ...baseCommon(row), code: row?.code ?? '', name: row?.name ?? '', triggerType: row?.triggerType ?? 'MaterialCall',
    enabled: row?.enabled ?? true, priority: row?.priority ?? 0,
    sourceSelectorJson: row?.sourceSelectorJson ?? defaultSource,
    targetSelectorJson: row?.targetSelectorJson ?? defaultTarget,
    taskOptionsJson: row?.taskOptionsJson ?? defaultOptions
  }
}
function baseMaterialType(row?: MaterialType): MaterialTypePayload {
  return {
    ...baseCommon(row), code: row?.code ?? '', name: row?.name ?? '',
    spec: row?.spec ?? '', unit: row?.unit ?? 'pcs', category: row?.category ?? '',
    barcodePrefix: row?.barcodePrefix ?? '', enabled: row?.enabled ?? true
  }
}
function baseMaterial(row?: Material): MaterialPayload {
  return {
    ...baseCommon(row), code: row?.code ?? '', name: row?.name ?? '', typeCode: row?.typeCode ?? materialTypes.value[0]?.code ?? '',
    barcode: row?.barcode ?? '', spec: row?.spec ?? '', unit: row?.unit ?? 'pcs', category: row?.category ?? '',
    lifecycleStatus: row?.lifecycleStatus ?? 'Active', enabled: row?.enabled ?? true
  }
}
function baseLocation(row?: ContainerLocation): ContainerLocationPayload {
  return { ...baseCommon(row), containerId: row?.containerId ?? containers.value[0]?.id ?? '', locationType: row?.locationType ?? 'Storage', locationId: row?.locationId ?? '', status: row?.status ?? 'Active', enteredAt: row?.enteredAt, source: 'Manual', reason: '' }
}
function baseContainerMaterial(row?: ContainerMaterial): BindMaterialPayload {
  return {
    ...baseCommon(row),
    containerId: row?.containerId ?? containers.value[0]?.id ?? '',
    materialId: row?.materialId ?? materials.value[0]?.id ?? '',
    source: 'Manual',
    reason: ''
  }
}

onMounted(loadAll)
</script>

<style scoped>
.warehouse-page { padding: 16px; height: 100%; overflow: auto; }
.warehouse-card { min-height: 100%; }
.page-header { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.page-header h2 { margin: 0 0 4px; font-size: 20px; color: var(--mg-text-light); }
.page-header p { margin: 0; color: var(--mg-text-muted); font-size: 13px; }
.toolbar { display: flex; gap: 10px; align-items: center; margin: 0 0 12px; flex-wrap: wrap; }
.toolbar .el-input { max-width: 260px; }
.toolbar .el-select { width: 160px; }
.preview-form { margin-bottom: 12px; flex-wrap: wrap; }
</style>
