"use client";

import { useRef, useState, useEffect } from "react";
import { BarcodeLabelComponent } from "@/types/barcode";
import { useBarcodeDesigner } from "@/contexts/BarcodeDesignerContext";
import JsBarcode from "jsbarcode";
import QRCode from "qrcode";
import { getFullImageUrl } from "@/lib/api/client";
import { MM_TO_PX } from "@/contexts/BarcodeDesignerContext";

interface Props {
  component: BarcodeLabelComponent;
}

// 1D 바코드 렌더
function Barcode1DRender({
  value,
  format,
  width,
  height,
  showText,
}: {
  value: string;
  format: string;
  width: number;
  height: number;
  showText: boolean;
}) {
  const svgRef = useRef<SVGSVGElement>(null);
  useEffect(() => {
    if (!svgRef.current || !value.trim()) return;
    try {
      JsBarcode(svgRef.current, value.trim(), {
        format: format.toLowerCase(),
        width: 2,
        height: Math.max(20, height - (showText ? 14 : 4)),
        displayValue: showText,
        margin: 2,
      });
    } catch {
      // ignore
    }
  }, [value, format, height, showText]);

  return (
    <div className="flex h-full w-full items-center justify-center overflow-hidden">
      <svg ref={svgRef} className="max-h-full max-w-full" />
    </div>
  );
}

// QR 렌더
function QRRender({ value, size }: { value: string; size: number }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  useEffect(() => {
    if (!canvasRef.current || !value.trim()) return;
    QRCode.toCanvas(canvasRef.current, value.trim(), {
      width: Math.max(40, size),
      margin: 1,
    });
  }, [value, size]);

  return (
    <div className="flex h-full w-full items-center justify-center overflow-hidden">
      <canvas ref={canvasRef} />
    </div>
  );
}

export function BarcodeLabelCanvasComponent({ component }: Props) {
  const {
    updateComponent,
    removeComponent,
    selectComponent,
    selectedComponentId,
    snapValueToGrid,
  } = useBarcodeDesigner();

  const [isDragging, setIsDragging] = useState(false);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0, compX: 0, compY: 0 });
  const [isResizing, setIsResizing] = useState(false);
  const [resizeStart, setResizeStart] = useState({ x: 0, y: 0, w: 0, h: 0 });
  const ref = useRef<HTMLDivElement>(null);
  const selected = selectedComponentId === component.id;

  const handleMouseDown = (e: React.MouseEvent) => {
    e.stopPropagation();
    selectComponent(component.id);
    if ((e.target as HTMLElement).closest("[data-resize-handle]")) {
      setIsResizing(true);
      setResizeStart({
        x: e.clientX,
        y: e.clientY,
        w: component.width,
        h: component.height,
      });
    } else {
      setIsDragging(true);
      setDragStart({ x: e.clientX, y: e.clientY, compX: component.x, compY: component.y });
    }
  };

  useEffect(() => {
    if (!isDragging && !isResizing) return;

    const onMove = (e: MouseEvent) => {
      if (isDragging) {
        const dx = e.clientX - dragStart.x;
        const dy = e.clientY - dragStart.y;
        updateComponent(component.id, {
          x: Math.max(0, snapValueToGrid(dragStart.compX + dx)),
          y: Math.max(0, snapValueToGrid(dragStart.compY + dy)),
        });
      } else if (isResizing) {
        const dx = e.clientX - resizeStart.x;
        const dy = e.clientY - resizeStart.y;
        updateComponent(component.id, {
          width: Math.max(20, resizeStart.w + dx),
          height: Math.max(10, resizeStart.h + dy),
        });
      }
    };
    const onUp = () => {
      setIsDragging(false);
      setIsResizing(false);
    };

    document.addEventListener("mousemove", onMove);
    document.addEventListener("mouseup", onUp);
    return () => {
      document.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseup", onUp);
    };
  }, [
    isDragging,
    isResizing,
    dragStart,
    resizeStart,
    component.id,
    updateComponent,
    snapValueToGrid,
  ]);

  const style: React.CSSProperties = {
    position: "absolute",
    left: component.x,
    top: component.y,
    width: component.width,
    height: component.height,
    zIndex: component.zIndex,
  };

  const border = selected ? "2px solid #2563eb" : "1px solid transparent";
  const isBarcode = component.type === "barcode";
  const isQR = component.barcodeType === "QR";

  const content = () => {
    switch (component.type) {
      case "text":
        return (
          <div
            style={{
              fontSize: component.fontSize || 10,
              color: component.fontColor || "#000",
              fontWeight: component.fontWeight || "normal",
              overflow: "hidden",
              wordBreak: "break-all",
              width: "100%",
              height: "100%",
            }}
          >
            {component.content || "텍스트"}
          </div>
        );
      case "barcode":
        if (isQR) {
          return (
            <QRRender
              value={component.barcodeValue || ""}
              size={Math.min(component.width, component.height)}
            />
          );
        }
        return (
          <Barcode1DRender
            value={component.barcodeValue || "123456789"}
            format={component.barcodeType || "CODE128"}
            width={component.width}
            height={component.height}
            showText={component.showBarcodeText !== false}
          />
        );
      case "image":
        return component.imageUrl ? (
          <img
            src={getFullImageUrl(component.imageUrl)}
            alt=""
            style={{
              width: "100%",
              height: "100%",
              objectFit: (component.objectFit as "contain") || "contain",
            }}
          />
        ) : (
          <div className="flex h-full w-full items-center justify-center bg-muted text-xs text-muted-foreground/70">
            이미지
          </div>
        );
      case "line":
        return (
          <div
            style={{
              width: "100%",
              height: component.lineWidth || 1,
              backgroundColor: component.lineColor || "#000",
              marginTop: (component.height - (component.lineWidth || 1)) / 2,
            }}
          />
        );
      case "rectangle":
        return (
          <div
            style={{
              width: "100%",
              height: "100%",
              backgroundColor: component.backgroundColor || "transparent",
              border: `${component.lineWidth || 1}px solid ${component.lineColor || "#000"}`,
            }}
          />
        );
      default:
        return null;
    }
  };

  return (
    <div
      ref={ref}
      style={{ ...style, border }}
      className="cursor-move overflow-hidden bg-white"
      onMouseDown={handleMouseDown}
    >
      {content()}
      {selected && component.type !== "line" && (
        <div
          data-resize-handle
          className="absolute bottom-0 right-0 h-2 w-2 cursor-se-resize bg-primary"
          onMouseDown={(e) => {
            e.stopPropagation();
            setIsResizing(true);
            setResizeStart({
              x: e.clientX,
              y: e.clientY,
              w: component.width,
              h: component.height,
            });
          }}
        />
      )}
    </div>
  );
}
