<template>
  <div class="grid-page p-40 flex-col gap-20">
    <h2 class="fs-18 color-333">宫格切分示例（方案 A：CSS Grid 叠加层）</h2>

    <!-- 控制条 -->
    <div class="flex-items-center gap-12">
      <span class="fs-14 color-666">宫格规格：</span>
      <button
        v-for="opt in gridOptions"
        :key="opt.label"
        class="grid-opt py-6 px-12 border-none round-6 fs-13 pointer"
        :class="{ active: rows === opt.rows && cols === opt.cols }"
        @click="setGrid(opt.rows, opt.cols)"
      >
        {{ opt.label }}
      </button>

      <span class="color-ccc">|</span>
      <button class="py-6 px-12 border-none round-6 fs-13 pointer clear-btn" @click="clearSelection">清空选区</button>
      <button class="py-6 px-12 color-fff border-none round-6 fs-13 pointer confirm-btn" @click="submit">确定</button>
    </div>

    <!-- 图片 + 宫格叠加层 -->
    <div class="img-wrap relative hidden round-8" :style="{ width: imgW + 'px' }">
      <img :src="imgUrl" class="block" :style="{ width: imgW + 'px' }" draggable="false" alt="" />
      <div class="grid-overlay absolute" :style="{ gridTemplateColumns: `repeat(${cols}, 1fr)`, gridTemplateRows: `repeat(${rows}, 1fr)` }">
        <div
          v-for="cell in cells"
          :key="cell.key"
          class="grid-cell relative pointer"
          :class="{ selected: selected.has(cell.key) }"
          @click="toggleCell(cell.key)"
        >
          <span class="cell-badge">{{ cell.r }}-{{ cell.c }}</span>
        </div>
      </div>
    </div>

    <!-- 结果 -->
    <div class="result flex-col gap-8">
      <span class="fs-14 color-666">已选区域：</span>
      <div class="flex flex-wrap gap-8">
        <span v-if="selectedList.length === 0" class="fs-13 color-999">（未选择）</span>
        <span v-for="key in selectedList" :key="key" class="tag px-10 py-4 round-6 fs-12 color-fff">{{ key }}</span>
      </div>

      <!-- 切出的图片块 -->
      <template v-if="croppedTiles.length">
        <span class="fs-14 color-666">切出的图片块：</span>
        <div class="flex flex-wrap gap-10">
          <div v-for="tile in croppedTiles" :key="tile.key" class="tile flex-col gap-4">
            <img :src="tile.dataUrl" class="block round-4 tile-img" alt="" />
            <span class="fs-11 color-666 text-center">{{ tile.key }}</span>
          </div>
        </div>
      </template>
      <span v-if="lastSubmit" class="fs-13 color-409">提交：{{ lastSubmit }}</span>
    </div>
    <div class="flex flex-wrap w-170">
      <div
        v-for="(item, index) in customOptions"
        :key="index"
        @mouseenter="mouseenter(item.rows, item.cols)"
        @mouseleave="mouseenter(0, 0)"
        @click="handleGG(item.rows, item.cols)"
        class="w-30 h-30 p-2"
      >
        <button :class="item.active ? 'active' : ''" class="w-full h-full bg-000 border-none round-4"></button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import imgUrl from '@/static/image/meinv.png';

const mouseenter = (row: number, col: number) => {
  customOptions.value.forEach((item: any) => {
    item.active = false;
    if (item.rows <= row && item.cols <= col) {
      item.active = true;
    }
  });
};
const handleGG = (row: number, col: number) => {
  setGrid(row, col);
};
// 自定义 25 宫格
const customOptions: any = ref([
  { rows: 1, cols: 1 },
  { rows: 1, cols: 2 },
  { rows: 1, cols: 3 },
  { rows: 1, cols: 4 },
  { rows: 1, cols: 5 },
  { rows: 2, cols: 1 },
  { rows: 2, cols: 2 },
  { rows: 2, cols: 3 },
  { rows: 2, cols: 4 },
  { rows: 2, cols: 5 },
  { rows: 3, cols: 1 },
  { rows: 3, cols: 2 },
  { rows: 3, cols: 3 },
  { rows: 3, cols: 4 },
  { rows: 3, cols: 5 },
  { rows: 4, cols: 1 },
  { rows: 4, cols: 2 },
  { rows: 4, cols: 3 },
  { rows: 4, cols: 4 },
  { rows: 4, cols: 5 },
  { rows: 5, cols: 1 },
  { rows: 5, cols: 2 },
  { rows: 5, cols: 3 },
  { rows: 5, cols: 4 },
  { rows: 5, cols: 5 },
]);

// 宫格规格
const rows = ref(3);
const cols = ref(3);
const imgW = 360;

const gridOptions = [
  { label: '2×2', rows: 2, cols: 2 },
  { label: '3×3', rows: 3, cols: 3 },
  { label: '4×4', rows: 4, cols: 4 },
  { label: '5×5', rows: 5, cols: 5 },
];

const setGrid = (r: number, c: number) => {
  rows.value = r;
  cols.value = c;
  selected.value.clear();
};

// 单元格列表（行-列，从 1 开始）
const cells = computed(() => {
  const list: { key: string; r: number; c: number }[] = [];
  for (let r = 1; r <= rows.value; r++) {
    for (let c = 1; c <= cols.value; c++) {
      list.push({ key: `${r}-${c}`, r, c });
    }
  }
  return list;
});

// 选中集合
const selected = ref(new Set<string>());
const toggleCell = (key: string) => {
  const s = new Set(selected.value);
  if (s.has(key)) s.delete(key);
  else s.add(key);
  selected.value = s;
};
const clearSelection = () => {
  selected.value = new Set();
};
const selectedList = computed(() => Array.from(selected.value).sort());

// 加载原图（用于按像素切图）
let imgEl: HTMLImageElement | null = null;
onMounted(() => {
  imgEl = new Image();
  imgEl.src = imgUrl;
});

// 切图结果：[{ key, dataUrl }]
const croppedTiles = ref<{ key: string; dataUrl: string }[]>([]);

// 把某个宫格区域从原图切出来，返回 dataURL
const cropCell = (key: string): string => {
  if (!imgEl) return '';
  const [r, c] = key.split('-').map(Number);
  const nw = imgEl.naturalWidth;
  const nh = imgEl.naturalHeight;
  const sw = nw / cols.value;
  const sh = nh / rows.value;
  const sx = (c - 1) * sw;
  const sy = (r - 1) * sh;
  const canvas = document.createElement('canvas');
  canvas.width = Math.round(sw);
  canvas.height = Math.round(sh);
  const ctx = canvas.getContext('2d');
  if (!ctx) return '';
  ctx.drawImage(imgEl, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);
  return canvas.toDataURL('image/png');
};

const lastSubmit = ref('');
const submit = () => {
  // 每个选中格按比例换算成像素区域，并实际切出图片
  const result = selectedList.value.map((key) => {
    const [r, c] = key.split('-').map(Number);
    return {
      key,
      x: (c - 1) / cols.value,
      y: (r - 1) / rows.value,
      w: 1 / cols.value,
      h: 1 / rows.value,
    };
  });
  croppedTiles.value = selectedList.value.map((key) => ({ key, dataUrl: cropCell(key) }));
  lastSubmit.value = JSON.stringify(result);
  console.log('宫格切分提交', result, croppedTiles.value);
};
</script>

<style scoped lang="scss">
button {
  user-select: none;
}
.active {
  background: #409eff;
}
.grid-page {
  background: #f5f5f5;
  min-height: 100vh;
}

.grid-opt {
  background: #fff;
  color: #666;
  border: 1px solid #ddd !important;
  &.active {
    background: #409eff;
    color: #fff;
    border-color: #409eff !important;
  }
}

.clear-btn {
  background: #f0f0f0;
  color: #666;
}

.confirm-btn {
  background: #409eff;
}

.img-wrap {
  border: 1px solid #ddd;
  width: fit-content;
  user-select: none;

  img {
    display: block;
  }
}

.grid-overlay {
  inset: 0;
  display: grid;
}

.grid-cell {
  border-right: 1px solid rgba(0, 0, 0, 0.35);
  border-bottom: 1px solid rgba(0, 0, 0, 0.35);
  transition: background 0.15s;
  &:hover {
    background: rgba(64, 158, 255, 0.12);
  }
  &.selected {
    background: rgba(64, 158, 255, 0.32);
    box-shadow: inset 0 0 0 2px #11fdbe;
  }
}

.cell-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 1px 6px;
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.4;  
  pointer-events: none;
}

.tag {
  background: #409eff;
}

.tile {
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 6px;
}
.tile-img {
  max-width: 120px;
  max-height: 120px;
  object-fit: contain;
}

.color-409 {
  color: #409eff;
}
</style>
