"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="bg-muted flex flex-1 items-center justify-center overflow-auto 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>
  );
}
