import { useEffect, useState } from 'react';

const OPACITY_THRESHOLD = 0.03;
const ALPHA_THRESHOLD = 32;
const PIXEL_SAMPLE_STEP = 4;

const analysisCache = new Map<string, number[]>();

function analyzeSpritesheet(img: HTMLImageElement, cols: number, rows: number): number[] | null {
  const w = img.naturalWidth;
  const h = img.naturalHeight;
  if (w < cols || h < rows) return null;

  const canvas = document.createElement('canvas');
  canvas.width = w;
  canvas.height = h;
  const ctx = canvas.getContext('2d', { willReadFrequently: true });
  if (!ctx) return null;
  ctx.drawImage(img, 0, 0);

  const cellW = Math.floor(w / cols);
  const cellH = Math.floor(h / rows);
  const result: number[] = [];

  try {
    for (let row = 0; row < rows; row++) {
      let lastNonEmpty = -1;
      for (let col = 0; col < cols; col++) {
        const data = ctx.getImageData(col * cellW, row * cellH, cellW, cellH).data;
        let opaque = 0;
        let total = 0;
        for (let y = 0; y < cellH; y += PIXEL_SAMPLE_STEP) {
          for (let x = 0; x < cellW; x += PIXEL_SAMPLE_STEP) {
            total++;
            if (data[(y * cellW + x) * 4 + 3]! > ALPHA_THRESHOLD) opaque++;
          }
        }
        if (total > 0 && opaque / total > OPACITY_THRESHOLD) lastNonEmpty = col;
      }
      result.push(lastNonEmpty + 1);
    }
    return result;
  } catch {
    return null;
  }
}

export function usePetFrameAnalysis(
  imageUrl: string | null,
  cols: number | null,
  rows: number | null,
): number[] | null {
  const [counts, setCounts] = useState<number[] | null>(null);

  useEffect(() => {
    if (!imageUrl || !cols || !rows) {
      setCounts(null);
      return;
    }

    const cacheKey = `${imageUrl}|${cols}x${rows}`;
    const cached = analysisCache.get(cacheKey);
    if (cached) {
      setCounts(cached);
      return;
    }

    let cancelled = false;
    const img = new Image();
    img.onload = () => {
      if (cancelled) return;
      const result = analyzeSpritesheet(img, cols, rows);
      if (result) analysisCache.set(cacheKey, result);
      if (!cancelled) setCounts(result);
    };
    img.onerror = () => {
      if (!cancelled) setCounts(null);
    };
    img.src = imageUrl;

    return () => {
      cancelled = true;
    };
  }, [imageUrl, cols, rows]);

  return counts;
}
