<template>
  <div>
    <q-toolbar class="row items-center">
      <q-btn-group push class="btn-group">
        <q-btn
          :label="$t('stock.shelf.shelf_up')"
          icon="upload"
          @click="handleShelfUp()"
        />
        <div class="self-center text-center q-px-sm">
          {{ $t("stock.layertip") }}
        </div>
        <q-input
          dense
          color="primary"
          v-model="shelf.layer_now"
          style="width: 50px"
        />
        <q-btn
          :label="$t('stock.shelf.shelf_down')"
          icon="download"
          @click="handleShelfDown()"
        />
        <q-btn :label="$t('refresh')" icon="refresh" @click="reFresh()">
          <q-tooltip
            content-class="bg-amber text-black shadow-4"
            :offset="[10, 10]"
            content-style="font-size: 12px"
          >
            {{ $t("refreshtip") }}
          </q-tooltip>
        </q-btn>
        <q-separator />
        <!-- <q-btn
          :label="$t('stock.edit')"
          icon="edit"
          v-if="hasPermission('edit')"
          @click="handle_edit()"
        /> -->
        <q-toggle
          v-model="showInventoryStatus"
          checked-icon="check"
          unchecked-icon="close"
          :label="showInventoryStatus ? '显示质检状态' : '显示库位状态'"
          size="sm"
          color="primary"
        />
      </q-btn-group>

      <goodscard
        v-if="showInventoryDetails"
        ref="goodscard"
        :col-index="select_Inventory.colIndex"
        :row-index="select_Inventory.rowIndex"
        :layer-index="select_Inventory.layerIndex"
        :selected-shelf-type="select_Inventory.shelf_type"
        :goods-data="select_Inventory.goods_data"
        @close="showInventoryDetails = false"
      />
    </q-toolbar>

    <q-page class="q-pa-md">

      <div class="layout-container">
        <!-- 货架部分 -->
        <div class="shelf-section">
          <div class="grid-system">
            <!-- Y轴 -->
            <div class="axis y-axis">
              <div class="axis-numbers">
                <div v-for="index in shelf.rows" :key="'y' + index">
                  {{ index }}
                </div>
              </div>
              <div class="axis-arrow"></div>
            </div>

            <!-- X轴 -->
            <div class="axis x-axis">
              <div class="axis-arrow"></div>
              <div class="axis-numbers">
                <div
                  v-for="col in shelf.cols"
                  :key="'x' + col"
                  class="axis-label"
                >
                  {{ col }}
                </div>
                <div class="axis-label"></div>
              </div>
            </div>

            <!-- 网格系统 -->
            <div class="grid-container">
              <!-- 内容层 -->
              <div class="grid-content">
                <div
                  v-for="(row, rowIndex) in shelf.rows"
                  :key="`row-${rowIndex}|${shelf.layer_now}`"
                  class="grid-row"
                  :style="{ cursor: 'pointer' }"
                >
                  <div
                    v-for="(col, colIndex) in shelf.cols"
                    :key="`col-${colIndex}|${shelf.layer_now}`"
                    class="grid-item"
                    :style="{ cursor: 'pointer' }"
                  >
                    <div
                      class="select-item"
                      v-if="
                        shouldShowButton(
                          shelf.rows - rowIndex,
                          colIndex + 1,
                          shelf.layer_now
                        )
                      "
                      :key="`${shelf.rows - rowIndex}-${colIndex}-${
                        shelf.layer_now
                      }`"
                      :style="{
                        border: '1px solid #ccc',
                        borderRadius: '5px',
                        width: 'var(--cell-d)',
                        height: 'var(--cell-d)',
                        backgroundColor: getBinColor(
                          shelf.rows - rowIndex,
                          colIndex + 1,
                          shelf.layer_now
                        ),
                        cursor: 'pointer',
                      }"
                      @click="
                        handleBinClick(
                          shelf.rows - rowIndex,
                          colIndex + 1,
                          shelf.layer_now
                        )
                      "
                    ></div>

                    <q-tooltip
                      v-if="
                        shouldShowButton(
                          shelf.rows - rowIndex,
                          colIndex + 1,
                          shelf.layer_now
                        )
                      "
                      content-class="bg-amber text-black shadow-4"
                      :offset="[20, 20]"
                      content-style="font-size: 12px; max-width: 300px;"
                    >
                      <div class="tooltip-header">
                        {{ $t("stock.rowtip") }} {{ shelf.rows - rowIndex }}
                        {{ $t("stock.coltip") }} {{ colIndex + 1 }}
                      </div>

                      <q-separator color="dark" inset />

                      <div class="tooltip-content">
                        <div
                          v-if="
                            getBinbatch(
                              shelf.rows - rowIndex,
                              colIndex + 1,
                              shelf.layer_now
                            ).length
                          "
                        >
                          <div
                            v-for="(batch, index) in getBinbatch(
                              shelf.rows - rowIndex,
                              colIndex + 1,
                              shelf.layer_now
                            )"
                            :key="index"
                            class="batch-item"
                            :class="{
                              'batch-pending': batch.status === 0,
                              'batch-approved': batch.status === 1,
                              'batch-rejected': batch.status === 2,
                              'batch-no-goods': batch.status === 404,
                            }"
                          >
                            <div class="batch-status">
                              <q-icon
                                :name="getStatusIcon(batch.status)"
                                size="sm"
                                :color="getStatusColor(batch.status)"
                                class="q-mr-xs"
                              />
                              {{ getStatusLabel(batch.status) }}
                            </div>
                            <div
                              v-if="
                                batch.batchId !== 'no_batch' && batch.batchId
                              "
                            >
                              {{ "批次号" }}: {{ batch.batchId }}
                            </div>
                            <div
                              v-if="
                                batch.time !== 'no_check_time' && batch.time
                              "
                            >
                              {{ "库位数目" }}: {{ batch.qty }}
                            </div>
                            <div
                              v-if="
                                batch.time !== 'no_check_time' && batch.time
                              "
                            >
                              {{ "时间" }}: {{ formatDateTime(batch.time) }}
                            </div>
                          </div>
                        </div>
                        <div v-else class="batch-no-goods">
                          <q-icon name="inventory" size="sm" class="q-mr-xs" />
                          {{ $t("stock.batch.no_goods") }}
                        </div>
                      </div>
                    </q-tooltip>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 统计面板部分 -->
        <div class="stats-section">
          <div class="stats-panel" role="region" aria-label="统计面板">
            <div v-if="statsLoaded" class="stats-cards">
              <q-card class="stat-card" @click="reFreshStatistics">
                <q-card-section>
                  <div class="card-title">总体统计</div>
                  <div class="big-num">{{ stats.total_locations }}</div>
                  <div class="row items-center q-mt-sm">
                    <div class="col">
                      <div class="muted">已占用</div>
                      <div class="small-num used">{{ stats.total_used }}</div>
                    </div>
                    <div class="col">
                      <div class="muted">可用</div>
                      <div class="small-num available">
                        {{ stats.total_available }}
                      </div>
                    </div>
                  </div>

                  <div class="util-row q-mt-md">
                    <div class="muted">使用率</div>
                    <div class="util-number">
                      {{ formatPercent(stats.utilization_rate) }}
                    </div>
                  </div>
                  <q-linear-progress
                    :value="(Number(stats.utilization_rate) || 0) / 100"
                    class="q-mt-xs"
                    track-color="grey-3"
                    size="12px"
                  />
                </q-card-section>
              </q-card>

              <q-card class="stat-card" @click="openGroupStatsDialog">
                <q-card-section>
                  <div class="card-title">各类型统计</div>

                  <div class="type-list">
                    <div v-for="t in typeList" :key="t.key" class="type-item">
                      <div class="type-info">
                        <div class="type-name">{{ t.label }}</div>
                        <div class="type-total">
                          共 {{ stats[t.totalKey] }} 个
                        </div>
                      </div>
                      <div class="type-details">
                        <div class="detail-item">
                          <span class="detail-label">占用</span>
                          <span class="detail-value used">{{
                            stats[t.usedKey]
                          }}</span>
                        </div>
                        <div class="detail-item">
                          <span class="detail-label">可用</span>
                          <span class="detail-value available">{{
                            stats[t.availKey]
                          }}</span>
                        </div>
                      </div>
                    </div>
                  </div>
                </q-card-section>
              </q-card>

              <q-card class="stat-card small">
                <q-card-section>
                  <div class="card-title">数据管理</div>
                  <div class="muted q-mt-xs">
                    {{ stats.statistic_time_display || "-" }}
                  </div>
                  <div class="action-buttons q-mt-sm">
                    <q-btn
                      icon="refresh"
                      label="刷新统计"
                      @click="getStatistics()"
                      flat
                      dense
                      class="full-width q-mb-sm"
                    />
                    <q-btn
                      icon="verified"
                      :label="$t('validate') || '数据校验'"
                      @click="runCheck()"
                      :disable="checking"
                      flat
                      dense
                      class="full-width"
                      :color="checking ? 'grey' : 'primary'"
                    >
                      <q-tooltip
                        v-if="!checking"
                        content-class="bg-amber text-black shadow-4"
                        :offset="[10, 10]"
                        content-style="font-size:12px"
                      >
                        执行数据一致性校验
                      </q-tooltip>
                    </q-btn>
                  </div>
                </q-card-section>
              </q-card>
            </div>

            <div v-else class="stats-loading">
              <q-spinner-dots size="36px" color="primary" />
              <div class="muted q-mt-sm">正在加载统计数据...</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 校验结果弹窗 -->
      <q-dialog
        v-model="showCheckDialog"
        maximized
        transition-show="scale"
        transition-hide="scale"
      >
        <q-card class="check-dialog">
          <q-card-section class="dialog-header">
            <div class="header-content">
              <div>
                <div class="dialog-title">数据一致性校验结果</div>
                <div class="dialog-subtitle">
                  {{
                    checkResult?.summary?.check_time
                      ? formatDateTime(checkResult.summary.check_time)
                      : "-"
                  }}
                </div>
              </div>
              <q-btn
                icon="close"
                flat
                round
                dense
                @click="showCheckDialog = false"
              />
            </div>
          </q-card-section>

          <q-separator />

          <q-card-section class="dialog-content">
            <div class="summary-cards">
              <q-card flat class="summary-card">
                <q-card-section>
                  <div class="summary-value">
                    {{ checkResult?.summary?.total_checked?.locations ?? "-" }}
                  </div>
                  <div class="summary-label">已校验位置</div>
                </q-card-section>
              </q-card>

              <q-card flat class="summary-card error">
                <q-card-section>
                  <div class="summary-value">
                    {{ checkResult?.summary?.errors_found?.locations ?? "-" }}
                  </div>
                  <div class="summary-label">发现错误</div>
                </q-card-section>
              </q-card>

              <q-card flat class="summary-card success">
                <q-card-section>
                  <div class="summary-value">
                    {{ checkResult?.summary?.fixed?.locations ?? "-" }}
                  </div>
                  <div class="summary-label">已修复</div>
                </q-card-section>
              </q-card>
            </div>

            <q-separator class="q-my-md" />

            <div class="error-sections">
              <div class="error-section">
                <div class="section-header">
                  <q-icon name="place" class="q-mr-sm" />
                  <span>位置级别错误</span>
                  <q-badge color="negative" class="q-ml-sm">
                    {{ checkResult?.details?.location_errors?.length || 0 }}
                  </q-badge>
                </div>

                <q-table
                  v-if="checkResult?.details?.location_errors?.length"
                  :rows="checkResult.details.location_errors"
                  :columns="checkColumns"
                  row-key="location_id"
                  flat
                  bordered
                  dense
                  class="error-table q-mt-md"
                >
                  <template v-slot:body-cell-actions="props">
                    <div class="action-buttons">
                      <q-btn
                        icon="place"
                        size="sm"
                        flat
                        dense
                        @click="highlightLocation(props.row)"
                        title="定位到该位置"
                      />
                      <q-btn
                        icon="open_in_new"
                        size="sm"
                        flat
                        dense
                        @click="openLocationDetail(props.row)"
                        title="查看详情"
                      />
                    </div>
                  </template>
                </q-table>
                <div v-else class="no-errors">未发现位置级别错误</div>
              </div>

              <div class="error-section q-mt-lg">
                <div class="section-header">
                  <q-icon name="folder" class="q-mr-sm" />
                  <span>分组级别错误</span>
                  <q-badge color="warning" class="q-ml-sm">
                    {{ checkResult?.details?.group_errors?.length || 0 }}
                  </q-badge>
                </div>

                <div
                  v-if="checkResult?.details?.group_errors?.length"
                  class="group-errors q-mt-md"
                >
                  <div
                    v-for="(error, index) in checkResult.details.group_errors"
                    :key="index"
                    class="group-error-item"
                  >
                    <div class="group-info">
                      <strong>{{
                        error.group_name || error.group_code
                      }}</strong>
                      <span class="error-type">{{ error.error_type }}</span>
                    </div>
                    <div class="group-details">
                      当前: {{ error.current_status }} → 期望:
                      {{ error.expected_status }}
                    </div>
                  </div>
                </div>
                <div v-else class="no-errors">未发现分组级别错误</div>
              </div>
            </div>
          </q-card-section>

          <q-card-actions align="right" class="dialog-actions">
            <q-btn label="关闭" flat @click="showCheckDialog = false" />
            <q-btn
              label="导出报告"
              icon="download"
              @click="exportCheckReport()"
              v-if="checkResult"
              color="primary"
            />
          </q-card-actions>
        </q-card>
      </q-dialog>

      <!-- 货位组统计查询弹窗 -->
      <q-dialog v-model="showGroupStatsDialog" persistent>
        <q-card style="min-width: 500px">
          <q-card-section>
            <div class="text-h6">货位组统计查询</div>
          </q-card-section>

          <q-card-section class="q-pt-none">
            <div class="q-gutter-md">
              <q-input
                filled
                type="number"
                v-model="groupStatsParams.min_utilization"
                label="最小使用率 (%)"
                hint="输入0-100之间的数值"
                :rules="[
                  (val) => (val >= 0 && val <= 100) || '请输入0-100之间的数值',
                ]"
              />

              <q-input
                filled
                type="number"
                v-model="groupStatsParams.min_used_locations"
                label="最小使用数目"
                hint="输入最小已使用货位数"
                :rules="[(val) => val >= 0 || '请输入非负数']"
              />
            </div>
          </q-card-section>

          <q-card-actions align="right">
            <q-btn
              flat
              label="取消"
              color="primary"
              @click="showGroupStatsDialog = false"
            />
            <q-btn
              flat
              label="查询"
              color="primary"
              @click="getGroupStatistics()"
              :loading="loadingGroupStats"
            />
          </q-card-actions>
        </q-card>
      </q-dialog>

      <!-- 货位组统计结果弹窗 -->
      <q-dialog v-model="showGroupStatsResult" maximized>
        <q-card>
          <q-card-section>
            <div class="row items-center">
              <div class="text-h6">货位组统计结果</div>
              <q-space />
              <q-btn
                icon="close"
                flat
                round
                dense
                @click="showGroupStatsResult = false"
              />
            </div>
            <div class="text-caption text-grey">
              查询时间:
              {{
                groupStatsResult?.timestamp
                  ? formatDateTime(groupStatsResult.timestamp)
                  : "-"
              }}
              | 筛选条件: 使用率≥{{ groupStatsParams.min_utilization }}%,
              使用数≥{{ groupStatsParams.min_used_locations }} | 共
              {{ groupStatsResult?.filters?.total_records || 0 }} 条记录
            </div>
          </q-card-section>

          <q-separator />

          <q-card-section>
            <q-table
              flat
              bordered
              :data="groupStatsResult?.data || []"
              :columns="groupStatsColumns"
              row-key="id"
              :loading="loadingGroupStats"
              
              @request="onGroupStatsRequest"
            >
              <template v-slot:body-cell-utilization_rate="props">
                <q-td :props="props">
                  <div class="row items-center">
                    <div class="col">{{ props.value }}%</div>
                    <div class="col-auto">
                      <q-linear-progress
                        :value="parseFloat(props.value) / 100"
                        :color="getUtilizationColor(props.value)"
                        style="width: 60px; height: 8px"
                      />
                    </div>
                  </div>
                </q-td>
              </template>

              <template v-slot:body-cell-actions="props">
                <q-td :props="props">
                  <q-btn
                    icon="visibility"
                    size="sm"
                    flat
                    dense
                    @click="highlightGroupLocation(props.row)"
                    title="查看该货位组"
                  />
                </q-td>
              </template>
            </q-table>
          </q-card-section>

          <q-card-actions align="right">
            <q-btn flat label="关闭" @click="showGroupStatsResult = false" />
            <q-btn
              flat
              label="导出数据"
              icon="download"
              @click="exportGroupStats()"
              v-if="groupStatsResult?.data?.length"
              color="primary"
            />
          </q-card-actions>
        </q-card>
      </q-dialog>
    </q-page>
  </div>
</template>

<script>
import goodscard from "components/goodscard.vue";
import { LocalStorage } from "quasar";
import { date } from "quasar";
import {
  getauth,
  postauth,
  post,
  putauth,
  deleteauth,
  getfile,
} from "boot/axios_request";

export default {
  name: "LocationManagement",
  components: { goodscard },
  data() {
    return {
      pathname: "bin/",
      warehouse_code: "",
      warehouse_name: "",
      shelf_name: "A区货架",

      shelf: {
        rows: 17,
        cols: 29,
        layers: 3,
        layer_now: 1,
      },

      filter: "",
      auth_edit: false,
      goodsMap: {},
      goodsMatrix: [],

      binColors: {
        T1: "#FFD700",
        T2: "#FFA500",
        T4: "#FF7300",
        T5: "#FF4100",
        S4: "#FF7300",
        M1: "#C8C8C8",
        E1: "#80620B",
        C1: "#808780",
        B1: "#00C300",
        reserved: "rgba(20, 125, 200, 0.3)",
        occupied: "rgba(20, 125, 255, 0.6)",
        default: "rgba(200, 200, 200, 0.3)",
      },

      showInventoryDetails: false,
      select_Inventory: {
        rowIndex: 0,
        colIndex: 0,
        layerIndex: 0,
        shelf_type: "storage",
        goods_data: {},
      },
      showInventoryStatus: true,
      userComponentPermissions: [],
      login_mode: LocalStorage.getItem("login_mode"),

      stats: {},
      statsLoaded: false,
      typeList: [
        {
          key: "t5",
          label: "T5",
          totalKey: "t5_total",
          usedKey: "t5_used",
          availKey: "t5_available",
        },
        {
          key: "t4",
          label: "T4",
          totalKey: "t4_total",
          usedKey: "t4_used",
          availKey: "t4_available",
        },
        {
          key: "s4",
          label: "S4",
          totalKey: "s4_total",
          usedKey: "s4_used",
          availKey: "s4_available",
        },
        {
          key: "t2",
          label: "T2",
          totalKey: "t2_total",
          usedKey: "t2_used",
          availKey: "t2_available",
        },
        {
          key: "t1",
          label: "T1",
          totalKey: "t1_total",
          usedKey: "t1_used",
          availKey: "t1_available",
        },
      ],

      checking: false,
      showCheckDialog: false,
      checkResult: null,
      checkColumns: [
        {
          name: "location_code",
          label: "位置编码",
          field: "location_code",
          align: "left",
        },
        {
          name: "layer",
          label: "层",
          field: "layer",
          align: "center",
          style: "width:60px",
        },
        {
          name: "row",
          label: "行",
          field: "row",
          align: "center",
          style: "width:60px",
        },
        {
          name: "col",
          label: "列",
          field: "col",
          align: "center",
          style: "width:60px",
        },
        {
          name: "current_status",
          label: "当前状态",
          field: "current_status",
          align: "left",
        },
        {
          name: "expected_status",
          label: "期望状态",
          field: "expected_status",
          align: "left",
        },
        {
          name: "detected_at",
          label: "检测时间",
          field: "detected_at",
          align: "left",
        },
        {
          name: "actions",
          label: "操作",
          field: "actions",
          align: "center",
          style: "width:100px",
        },
      ],

      showGroupStatsDialog: false,
      showGroupStatsResult: false,
      loadingGroupStats: false,
      groupStatsParams: {
        min_utilization: 100,
        min_used_locations: 2,
      },
      groupStatsResult: null,
      groupStatsColumns: [
        {
          name: "location_group",
          label: "货位组",
          field: "location_group",
          align: "left",
          sortable: true,
        },
        {
          name: "warehouse_display",
          label: "仓库",
          field: "warehouse_display",
          align: "left",
          sortable: true,
        },
        {
          name: "layer_display",
          label: "楼层",
          field: "layer_display",
          align: "center",
          sortable: true,
        },
        {
          name: "total_locations",
          label: "总货位数",
          field: "total_locations",
          align: "center",
          sortable: true,
        },
        {
          name: "used_locations",
          label: "已使用",
          field: "used_locations",
          align: "center",
          sortable: true,
        },
        {
          name: "available_locations",
          label: "可用数",
          field: "available_locations",
          align: "center",
          sortable: true,
        },
        {
          name: "utilization_rate",
          label: "使用率",
          field: "utilization_rate",
          align: "center",
          sortable: true,
        },
        {
          name: "statistic_time",
          label: "统计时间",
          field: "statistic_time",
          align: "center",
          sortable: true,
        },
        {
          name: "actions",
          label: "操作",
          field: "actions",
          align: "center",
        },
      ],
      groupStatsPagination: {
        page: 1,
        rowsPerPage: 10,
        rowsNumber: 0,
      },
    };
  },

  methods: {
    openGroupStatsDialog() {
      this.showGroupStatsDialog = true;
    },

    getGroupStatistics() {
      const layer = this.shelf.layer_now || 1;
      const params = new URLSearchParams({
        layer: layer,
        min_utilization: this.groupStatsParams.min_utilization || 0,
        min_used_locations: this.groupStatsParams.min_used_locations || 0,
      });

      const url = `location_statistics/group-statistics/?${params}`;

      this.loadingGroupStats = true;
      getauth(url)
        .then((res) => {
          this.groupStatsResult = res || {};
          this.groupStatsPagination.rowsNumber =
            this.groupStatsResult.filters?.total_records || 0;
          this.showGroupStatsDialog = false;
          this.showGroupStatsResult = true;
        })
        .catch((err) => {
          console.error("获取货位组统计失败", err);
          this.$q.notify({
            type: "negative",
            message: "获取货位组统计失败: " + (err?.message || "未知错误"),
          });
        })
        .finally(() => {
          this.loadingGroupStats = false;
        });
    },

    onGroupStatsRequest(props) {
      const { page, rowsPerPage } = props.pagination;
      this.groupStatsPagination.page = page;
      this.groupStatsPagination.rowsPerPage = rowsPerPage;

      if (this.groupStatsResult?.data) {
        const startRow = (page - 1) * rowsPerPage;
        const endRow = startRow + rowsPerPage;
        this.groupStatsResult.displayData = this.groupStatsResult.data.slice(
          startRow,
          endRow
        );
      }
    },

    highlightGroupLocation(group) {
      this.$q.notify({
        message: `定位到货位组: ${group.location_group}`,
        color: "primary",
      });
    },

    exportGroupStats() {
      if (!this.groupStatsResult?.data) return;

      const dataStr = JSON.stringify(this.groupStatsResult, null, 2);
      const dataBlob = new Blob([dataStr], { type: "application/json" });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(dataBlob);
      link.download = `group-statistics-${
        new Date().toISOString().split("T")[0]
      }.json`;
      link.click();
    },

    getUtilizationColor(rate) {
      const utilization = Number(rate) || 0;
      if (utilization < 30) return "positive";
      if (utilization < 70) return "warning";
      return "negative";
    },

    formatPercent(val) {
      if (val === undefined || val === null || val === "") return "0%";
      const v = Number(val);
      if (Number.isNaN(v)) return "0%";
      return `${v.toFixed(1)}%`;
    },

    exportCheckReport() {
      if (!this.checkResult) return;

      const dataStr = JSON.stringify(this.checkResult, null, 2);
      const dataBlob = new Blob([dataStr], { type: "application/json" });
      const link = document.createElement("a");
      link.href = URL.createObjectURL(dataBlob);
      link.download = `location-check-report-${
        new Date().toISOString().split("T")[0]
      }.json`;
      link.click();
    },

    highlightLocation(row) {
      if (!row) return;
      this.select_Inventory.rowIndex = row.row;
      this.select_Inventory.colIndex = row.col;
      this.select_Inventory.layerIndex = row.layer;
      this.select_Inventory.goods_data =
        this.goodsMap[`${row.row}-${row.col}-${row.layer}`] || {};
      this.select_Inventory.shelf_type = this.select_Inventory.goods_data
        ?.location_type
        ? "storage"
        : "corridor";
      this.showInventoryDetails = true;
    },

    openLocationDetail(row) {
      this.$q.notify({
        message: `打开位置 ${row.location_code} 的详情`,
      });
    },

    loadUserPermissions() {
      postauth("staff/role-comPermissions/" + this.login_mode + "/", {
        page: "/stock/management",
      }).then(
        (response) => {
          this.userComponentPermissions = response;
        },
        (error) => {
          this.$q.notify({
            type: "negative",
            message: "加载用户权限失败," + error.message,
          });
        }
      );
    },

    hasPermission(components) {
      if (!this.userComponentPermissions) return false;
      const permission = this.userComponentPermissions.find(
        (perm) => perm.component === components
      );
      return permission && permission.enabled;
    },

    runCheck() {
      const layer = this.shelf.layer_now || 1;
      const url = `/location_statistics/CheckView/?layer=${layer}`;

      this.checking = true;
      postauth(url, {})
        .then((res) => {
          if (res && res.data) {
            if (res.data.success === false) {
              this.$q.notify({ type: "negative", message: "校验返回失败" });
              this.checkResult = null;
            } else {
              this.checkResult = res.data.data || res.data;
              this.showCheckDialog = true;
            }
          } else {
            this.$q.notify({ type: "warning", message: "校验无返回内容" });
          }
        })
        .catch((err) => {
          this.$q.notify({
            type: "negative",
            message: "校验请求失败: " + (err && err.message),
          });
        })
        .finally(() => {
          this.checking = false;
        });
    },

    shouldShowButton(row, col, layer) {
      const bin = this.goodsMap[`${row}-${col}-${layer}`];
      return ["T1", "T2", "T4", "T5", "S4", "M1", "E1", "C1", "B1"].includes(
        bin?.location_type
      );
    },

    getList() {
      var _this = this;
      postauth(_this.pathname + "check/", {
        layer: _this.shelf.layer_now,
        warehouse_code: _this.warehouse_code,
      }).then((res) => {
        _this.goodsMap = {};
        res.data.forEach((item) => {
          const key = `${item.row}-${item.col}-${item.layer}`;
          _this.goodsMap[key] = {
            id: item.id,
            location_type: item.location_type,
            shelf_type: item.shelf_type,
            status: item.status,
            check: item.batch_statuses,
          };
        });

        _this.$q.notify({
          message: "刷新成功",
          icon: "done",
          color: "positive",
        });
      });
    },

    handle_setting() {
      if (LocalStorage.has("warehouse_code")) {
        this.warehouse_code = LocalStorage.getItem("warehouse_code");
      }
      if (LocalStorage.has("warehouse_name")) {
        this.warehouse_name = LocalStorage.getItem("warehouse_name");
      }
    },

    formatDateTime(dateStr) {
      if (!dateStr) return "";
      if (!dateStr.includes("T") || dateStr.includes("no_check_time")) {
        return dateStr;
      }
      return date.formatDate(new Date(dateStr), "YYYY-MM-DD HH:mm:ss");
    },

    getBinbatch(row, col, layer) {
      const bin = this.goodsMap[`${row}-${col}-${layer}`];
      if (!bin || !bin.check || bin.check.length === 0) {
        return [{ status: 404, time: "", batchId: "" }];
      }

      return bin.check.map((item) => {
        if (item[0] === "404") {
          return { status: 404, time: "no_check_time", batchId: "no_batch" };
        } else {
          return {
            status: item[0],
            time: item[1],
            batchId: item[2],
            qty: item[3],
          };
        }
      });
    },

    getStatusIcon(status) {
      switch (status) {
        case 0:
          return "schedule";
        case 1:
          return "check_circle";
        case 2:
          return "cancel";
        case 404:
          return "block";
        default:
          return "help";
      }
    },

    getStatusColor(status) {
      switch (status) {
        case 0:
          return "yellow";
        case 1:
          return "green";
        case 2:
          return "red";
        case 404:
          return "grey";
        default:
          return "blue";
      }
    },

    getStatusLabel(status) {
      switch (status) {
        case 0:
          return "待检";
        case 1:
          return "合格";
        case 2:
          return "不合格";
        case 404:
          return "无货";
        default:
          return "无货";
      }
    },

    getBinColor(row, col, layer) {
      const bin = this.goodsMap[`${row}-${col}-${layer}`];
      if (this.showInventoryStatus) {
        if (!bin || !bin.check || bin.check.length === 0) {
          return "#CCCCCC";
        }
        const status = bin.check[0][0];
        const statusColors = {
          0: "#FFD700",
          1: "#00FF00",
          2: "#FF0000",
          404: "#CCCCCC",
        };
        return statusColors[status] || "#CCCCCC";
      } else {
        if (!bin) return "#CCCCCC";
        if (bin.status == "reserved" || bin.status == "occupied") {
          return this.binColors[bin.status];
        }
        return this.binColors[bin.location_type] || "#CCCCCC";
      }
    },

    handleBinClick(row, col, layer) {
      this.select_Inventory.rowIndex = row;
      this.select_Inventory.colIndex = col;
      this.select_Inventory.layerIndex = layer;

      const locationType =
        this.goodsMap[`${row}-${col}-${layer}`]?.location_type;
      if (["T1", "T2", "T4", "T5", "S4"].includes(locationType)) {
        this.select_Inventory.shelf_type = "storage";
      } else if (["E1", "C1"].includes(locationType)) {
        this.select_Inventory.shelf_type = "elevator";
      } else {
        this.select_Inventory.shelf_type = "corridor";
      }

      this.select_Inventory.goods_data =
        this.goodsMap[`${row}-${col}-${layer}`];
      this.showInventoryDetails = true;
    },

    handleShelfDown() {
      if (this.shelf.layer_now > this.shelf.layers) {
        this.shelf.layer_now = this.shelf.layers;
      }
      if (this.shelf.layer_now > 1) {
        this.shelf.layer_now -= 1;
        this.reFresh();
      }
    },

    handleShelfUp() {
      if (this.shelf.layer_now < this.shelf.layers) {
        this.shelf.layer_now += 1;
        this.reFresh();
      } else {
        this.shelf.layer_now = this.shelf.layers;
      }
    },

    reFresh() {
      this.handle_setting();
      this.getList();
      this.getStatistics();
    },

    handle_edit() {
      this.auth_edit = !this.auth_edit;
      LocalStorage.set("auth_edit", this.auth_edit);
    },

    getStatistics() {
      const layer = this.shelf.layer_now || 1;
      const url = `location_statistics/refresh-statistics/?layer=${layer}`;

      this.statsLoaded = false;
      getauth(url)
        .then((res) => {
          const arr = res.data && (res.data.data || res.data);
          const item =
            Array.isArray(arr) && arr.length ? arr[0] : res.data || {};
          this._applyStats(item);
          this.statsLoaded = true;
        })
        .catch((err) => {
          console.warn("获取统计失败", err && err.message);
          this.statsLoaded = true;
        });
    },
    reFreshStatistics() {
      const layer = this.shelf.layer_now || 1;
      const url = `location_statistics/refresh-statistics/?layer=${layer}`;
      postauth(url)
      
    },

    _applyStats(item) {
      this.stats = item || {};
      if (this.stats.statistic_time) {
        try {
          this.stats.statistic_time_display = this.formatDateTime(
            this.stats.statistic_time
          );
        } catch (e) {
          this.stats.statistic_time_display = this.stats.statistic_time;
        }
      } else {
        this.stats.statistic_time_display = "";
      }
    },

    updateCSSVariables() {
      const root = document.documentElement;
      const dwidth = document.documentElement.clientWidth;
      const dheight = document.documentElement.clientHeight;

      const width = dwidth * 0.6;
      const height = dheight * 0.6;

      var cell_d = (width * 8.5) / 10 / this.shelf.cols;
      var cell_x = (cell_d * 1) / 5;
      var cellSize = cell_x / 2;
      var cellGap = height / this.shelf.rows - cell_d;

      if (cellGap < 2) {
        cellGap = 2;
        cell_d = (height - cellGap * this.shelf.rows) / this.shelf.rows;
        cell_x = (cell_d * 3) / 5;
        cellSize = cell_x / 2;
      }
      var cellSize_2 = cellGap / 2;
      var axis_x = cell_x * this.shelf.cols + cell_d * this.shelf.cols;

      root.style.setProperty("--cell-d", `${cell_d}px`);
      root.style.setProperty("--cell-d-x", `${cell_d + cell_x}px`);
      root.style.setProperty("--cell-x-2", `${cellSize}px`);
      root.style.setProperty("--cell-x", `${cell_x}px`);
      root.style.setProperty("--cell-y", `${cellGap + cell_d}px`);
      root.style.setProperty("--cell-y-2", `${cellSize_2}px`);
      root.style.setProperty("--axis-x", `${axis_x}px`);
    },

    handleResize() {
      clearTimeout(this.resizeTimer);
      this.resizeTimer = setTimeout(() => {
        this.updateCSSVariables();
      }, 200);
    },
  },

  mounted() {
    this.updateCSSVariables();
    window.addEventListener("resize", this.handleResize);
  },

  beforeUnmount() {
    this.goodsMap = {};
    this.goodsMatrix = [];
    window.removeEventListener("resize", this.handleResize);
    clearTimeout(this.resizeTimer);
    if (this.$refs.goodscard) {
      this.$refs.goodscard.$destroy();
    }
  },

  created() {
    LocalStorage.set("auth_edit", this.auth_edit);
    this.loadUserPermissions();
    this.handle_setting();
    this.getList();
    this.getStatistics();
  },
};
</script>

<style scoped>
/* 新增布局容器样式 */
.layout-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  width: 100%;
}

/* 货架部分 */
.shelf-section {
  flex: 1;
  min-width: 600px;
}

/* 统计面板部分 */
.stats-section {
  flex: 0 0 300px 300px;
  max-width: 200px;
}

:root {
  --cell-d: 40px;
  --cell-d-x: 100px;
  --cell-x-2: 20px;
  --cell-x: 20px;
  --cell-y: 100px;
  --cell-y-2: 20px;
  --axis-x: 20px;
}

.btn-group {
  position: absolute;
  left: var(--cell-x-2);
  display: flex;
  gap: 10px;
}

/* 网格系统托盘 */
.grid-system {
  position: relative;
  padding-left: var(--cell-x-2);
  padding-right: 330px;
  /* 左边留出Y轴空间 */
  padding-top: 10px;
  /* 下边留出X轴空间 */
  min-width: max-content;
}

/* 坐标轴通用样式 */
.axis {
  position: absolute;

  background: #333;
  z-index: 2;
}

/* 箭头 */
.axis-arrow {
  position: absolute;

  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 12px solid #555;
}

.y-axis .axis-arrow {
  top: -10px;
  left: -4px;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 10px solid #333;
}

.x-axis .axis-arrow {
  right: -3px;
  top: -5px;
  border-left-color: #333;
}

/* Y轴样式 */
.y-axis {
  left: 30px;
  top: 0;
  bottom: -10px;
  /* 留出X轴空间 */
  width: 2px;
}

.y-axis .axis-numbers {
  position: absolute;
  right: 6px;

  height: 100%;
  display: flex;
  flex-direction: column-reverse;
}

.y-axis .axis-numbers div {
  position: relative;
  height: var(--cell-y);
  /* 与网格行高一致 */
  line-height: var(--cell-x);
  top: -0.5em;
  /* 垂直居中 */
  color: #111;
  font-size: larger;
}

/* X轴样式 */
.x-axis {
  position: absolute;
  left: 30px;
  width: var(--axis-x);
  /* 直接使用变量控制宽度 */
  right: auto;
  bottom: -10px;

  height: 2px;
}

.x-axis .axis-numbers {
  position: absolute;
  top: 10px;
  /* 数字显示在轴线下方 */

  display: flex;
}

.x-axis .axis-numbers div {
  width: var(--cell-d-x);
  /* 与网格列宽一致 */
  text-align: center;
  color: #333;
}

/* 网格系统 */
.grid-container {
  position: relative;
  margin-left: 30px;
  /* 与Y轴对齐 */
}

/* 网格内容 */
.grid-content {
  position: relative;
  z-index: 2;
}

.grid-row {
  display: flex;
  height: var(--cell-y);
  /* 固定行高上列下行 */
  gap: var(--cell-x);
}

.grid-item {
  width: var(--cell-d);
  /* 固定宽度 */
  height: var(--cell-d);

  background: transparent;
  transition: transform 0.2s;
}

.select-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.stats-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stat-card {
  width: 100%;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}

.card-title {
  font-size: 14px;
  font-weight: 600;
  color: #333;
  margin-bottom: 8px;
}

.big-num {
  font-size: 32px;
  font-weight: 700;
  color: #1976d2;
}

.small-num {
  font-size: 18px;
  font-weight: 600;
}

.small-num.used {
  color: #f57c00;
}

.small-num.available {
  color: #4caf50;
}

.muted {
  color: #888;
  font-size: 12px;
}

.util-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
}

.util-number {
  font-weight: 700;
  color: #1976d2;
}

.type-list {
  space-y: 8px;
}

.type-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
  border-bottom: 1px solid #f0f0f0;
}

.type-info {
  display: flex;
  flex-direction: column;
}

.type-name {
  font-weight: 600;
  font-size: 13px;
}

.type-total {
  font-size: 11px;
  color: #999;
}

.type-details {
  display: flex;
  gap: 12px;
}

.detail-item {
  text-align: center;
}

.detail-label {
  display: block;
  font-size: 10px;
  color: #666;
}

.detail-value {
  display: block;
  font-size: 12px;
  font-weight: 500;
}

.detail-value.used {
  color: #f57c00;
}

.detail-value.available {
  color: #4caf50;
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stats-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  gap: 8px;
  color: #666;
}

.check-dialog {
  min-width: 800px;
  max-width: 90vw;
  max-height: 90vh;
}

.dialog-header {
  padding: 16px 24px;
  background: #f8f9fa;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.dialog-title {
  font-size: 20px;
  font-weight: 700;
  color: #333;
}

.dialog-subtitle {
  font-size: 14px;
  color: #666;
}

.dialog-content {
  padding: 24px;
  overflow-y: auto;
}

.summary-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.summary-card {
  text-align: center;
  padding: 16px;
  border-radius: 8px;
  transition: transform 0.2s ease;
}

.summary-card:hover {
  transform: translateY(-2px);
}

.summary-card.error {
  background: #ffebee;
}

.summary-card.success {
  background: #e8f5e8;
}

.summary-value {
  font-size: 28px;
  font-weight: 700;
  margin-bottom: 4px;
}

.summary-card.error .summary-value {
  color: #f44336;
}

.summary-card.success .summary-value {
  color: #4caf50;
}

.summary-label {
  font-size: 14px;
  color: #666;
}

.error-sections {
  space-y: 24px;
}

.error-section {
  background: white;
  border-radius: 8px;
  padding: 16px;
  border: 1px solid #e0e0e0;
}

.section-header {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.error-table {
  margin-top: 12px;
}

.no-errors {
  text-align: center;
  padding: 20px;
  color: #666;
  font-style: italic;
}

.group-errors {
  space-y: 8px;
}

.group-error-item {
  padding: 12px;
  background: #f8f9fa;
  border-radius: 6px;
  border-left: 4px solid #ffa500;
}

.group-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}

.error-type {
  font-size: 12px;
  color: #666;
  background: #ffecb3;
  padding: 2px 6px;
  border-radius: 3px;
}

.group-details {
  font-size: 12px;
  color: #666;
}

.dialog-actions {
  padding: 16px 24px;
  border-top: 1px solid #e0e0e0;
}

@media (max-width: 1024px) {
  .stats-panel {
    position: relative;
    width: 100%;
    right: 0;
    top: 0;
    margin-top: 20px;
  }

  .summary-cards {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .check-dialog {
    min-width: 95vw;
  }

  .stats-panel {
    width: 100%;
  }
}
</style>
