"use client";

import { useRef, useState, useEffect } from "react";
import { useDrop } from "react-dnd";
import { useBarcodeDesigner, MM_TO_PX } from "@/contexts/BarcodeDesignerContext";
import { BarcodeLabelCanvasComponent } from "./BarcodeLabelCanvasComponent";
import { BarcodeLabelComponent } from "@/types/barcode";
import { v4 as uuidv4 } from "uuid";

/** 작업 영역에 라벨이 들어가도록 스케일 (최소 0.5=작게 맞춤, 최대 3) */
const MIN_SCALE = 0.5;
const MAX_SCALE = 3;

export function BarcodeDesignerCanvas() {
  const containerRef = useRef<HTMLDivElement>(null);
  const canvasRef = useRef<HTMLDivElement>(null);
  const [scale, setScale] = useState(1);
  const {
    widthMm,
    heightMm,
    components,
    addComponent,
    selectComponent,
    showGrid,
    snapValueToGrid,
  } = useBarcodeDesigner();

  const widthPx = widthMm * MM_TO_PX;
  const heightPx = heightMm * MM_TO_PX;

  // 컨테이너 크기에 맞춰 캔버스 스케일 계산 (라벨이 너무 작게 보이지 않도록)
  useEffect(() => {
    const el = containerRef.current;
    if (!el || widthPx <= 0 || heightPx <= 0) return;
    const observer = new ResizeObserver(() => {
      const w = el.clientWidth - 48;
      const h = el.clientHeight - 48;
      if (w <= 0 || h <= 0) return;
      const scaleX = w / widthPx;
      const scaleY = h / heightPx;
      const fitScale = Math.min(scaleX, scaleY);
      const s = Math.max(MIN_SCALE, Math.min(MAX_SCALE, fitScale));
      setScale(s);
    });
    observer.observe(el);
    const w = el.clientWidth - 48;
    const h = el.clientHeight - 48;
    if (w > 0 && h > 0) {
      const scaleX = w / widthPx;
      const scaleY = h / heightPx;
      const fitScale = Math.min(scaleX, scaleY);
      const s = Math.max(MIN_SCALE, Math.min(MAX_SCALE, fitScale));
      setScale(s);
    }
    return () => observer.disconnect();
  }, [widthPx, heightPx]);

  const [{ isOver }, drop] = useDrop(() => ({
    accept: "barcode-component",
    drop: (item: { component: BarcodeLabelComponent }, monitor) => {
      const canvasEl = canvasRef.current;
      if (!canvasEl) return;
      const offset = monitor.getClientOffset();
      const rect = canvasEl.getBoundingClientRect();
      if (!offset) return;
      // 스케일 적용된 좌표 → 실제 캔버스 좌표
      const s = scale;
      let x = (offset.x - rect.left) / s;
      let y = (offset.y - rect.top) / s;
      x -= item.component.width / 2;
      y -= item.component.height / 2;
      x = Math.max(0, Math.min(x, widthPx - item.component.width));
      y = Math.max(0, Math.min(y, heightPx - item.component.height));

      const newComp: BarcodeLabelComponent = {
        ...item.component,
        id: `comp_${uuidv4()}`,
        x: snapValueToGrid(x),
        y: snapValueToGrid(y),
        zIndex: components.length,
      };
      addComponent(newComp);
    },
    collect: (m) => ({ isOver: m.isOver() }),
  }), [widthPx, heightPx, scale, components.length, addComponent, snapValueToGrid]);

  // 스케일된 캔버스가 컨테이너 안에 들어가도록 fit (하단 잘림 방지)
  const scaledW = widthPx * scale;
  const scaledH = heightPx * scale;

  return (
    <div
      ref={containerRef}
      className="flex min-h-0 flex-1 items-center justify-center overflow-auto bg-gray-100 p-6"
    >
      {/* 래퍼: 스케일된 크기만큼 차지해서 flex로 정확히 가운데 + 하단 잘림 방지 */}
      <div
        className="flex shrink-0 items-center justify-center"
        style={{ width: scaledW, height: scaledH }}
      >
        <div
          style={{
            transform: `scale(${scale})`,
            transformOrigin: "0 0",
          }}
        >
          <div
            key={`canvas-${widthMm}-${heightMm}`}
            ref={(r) => {
              (canvasRef as { current: HTMLDivElement | null }).current = r;
              drop(r);
            }}
            className="relative bg-white shadow-lg"
            style={{
              width: widthPx,
              height: heightPx,
              minWidth: widthPx,
              minHeight: heightPx,
              backgroundImage: showGrid
                ? `linear-gradient(to right, #e5e7eb 1px, transparent 1px),
                   linear-gradient(to bottom, #e5e7eb 1px, transparent 1px)`
                : undefined,
              backgroundSize: showGrid ? `${MM_TO_PX * 5}px ${MM_TO_PX * 5}px` : undefined,
              outline: isOver ? "2px dashed #2563eb" : "1px solid #d1d5db",
            }}
            onClick={(e) => {
              if (e.target === e.currentTarget) selectComponent(null);
            }}
          >
            {components.map((c) => (
              <BarcodeLabelCanvasComponent key={c.id} component={c} />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
