"use client";

import { useRef, useState, useEffect } from "react";
import { ComponentConfig } from "@/types/report";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";

interface CanvasComponentProps {
  component: ComponentConfig;
}

export function CanvasComponent({ component }: CanvasComponentProps) {
  const { selectedComponentId, selectComponent, updateComponent, getQueryResult } = useReportDesigner();
  const [isDragging, setIsDragging] = useState(false);
  const [isResizing, setIsResizing] = useState(false);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const [resizeStart, setResizeStart] = useState({ x: 0, y: 0, width: 0, height: 0 });
  const componentRef = useRef<HTMLDivElement>(null);

  const isSelected = selectedComponentId === component.id;

  // 드래그 시작
  const handleMouseDown = (e: React.MouseEvent) => {
    if ((e.target as HTMLElement).classList.contains("resize-handle")) {
      return;
    }

    e.stopPropagation();
    selectComponent(component.id);
    setIsDragging(true);
    setDragStart({
      x: e.clientX - component.x,
      y: e.clientY - component.y,
    });
  };

  // 리사이즈 시작
  const handleResizeStart = (e: React.MouseEvent) => {
    e.stopPropagation();
    setIsResizing(true);
    setResizeStart({
      x: e.clientX,
      y: e.clientY,
      width: component.width,
      height: component.height,
    });
  };

  // 마우스 이동 핸들러 (전역)
  useEffect(() => {
    if (!isDragging && !isResizing) return;

    const handleMouseMove = (e: MouseEvent) => {
      if (isDragging) {
        const newX = Math.max(0, e.clientX - dragStart.x);
        const newY = Math.max(0, e.clientY - dragStart.y);
        updateComponent(component.id, { x: newX, y: newY });
      } else if (isResizing) {
        const deltaX = e.clientX - resizeStart.x;
        const deltaY = e.clientY - resizeStart.y;
        const newWidth = Math.max(50, resizeStart.width + deltaX);
        const newHeight = Math.max(30, resizeStart.height + deltaY);
        updateComponent(component.id, { width: newWidth, height: newHeight });
      }
    };

    const handleMouseUp = () => {
      setIsDragging(false);
      setIsResizing(false);
    };

    document.addEventListener("mousemove", handleMouseMove);
    document.addEventListener("mouseup", handleMouseUp);

    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
    };
  }, [
    isDragging,
    isResizing,
    dragStart.x,
    dragStart.y,
    resizeStart.x,
    resizeStart.y,
    resizeStart.width,
    resizeStart.height,
    component.id,
    updateComponent,
  ]);

  // 표시할 값 결정
  const getDisplayValue = (): string => {
    // 쿼리와 필드가 연결되어 있으면 실제 데이터 조회
    if (component.queryId && component.fieldName) {
      const queryResult = getQueryResult(component.queryId);

      // 실행 결과가 있으면 첫 번째 행의 해당 필드 값 표시
      if (queryResult && queryResult.rows.length > 0) {
        const firstRow = queryResult.rows[0];
        const value = firstRow[component.fieldName];

        // 값이 있으면 문자열로 변환하여 반환
        if (value !== null && value !== undefined) {
          return String(value);
        }
      }

      // 실행 결과가 없거나 값이 없으면 필드명 표시
      return `{${component.fieldName}}`;
    }

    // 기본값이 있으면 기본값 표시
    if (component.defaultValue) {
      return component.defaultValue;
    }

    // 둘 다 없으면 타입에 따라 기본 텍스트
    return component.type === "text" ? "텍스트 입력" : "레이블 텍스트";
  };

  // 컴포넌트 타입별 렌더링
  const renderContent = () => {
    const displayValue = getDisplayValue();
    const hasBinding = component.queryId && component.fieldName;

    switch (component.type) {
      case "text":
        return (
          <div className="h-full w-full">
            <div className="mb-1 flex items-center justify-between text-xs text-gray-500">
              <span>텍스트 필드</span>
              {hasBinding && <span className="text-blue-600">● 연결됨</span>}
            </div>
            <div
              style={{
                fontSize: `${component.fontSize}px`,
                color: component.fontColor,
                fontWeight: component.fontWeight,
                textAlign: component.textAlign as "left" | "center" | "right",
              }}
              className="w-full"
            >
              {displayValue}
            </div>
          </div>
        );

      case "label":
        return (
          <div className="h-full w-full">
            <div className="mb-1 flex items-center justify-between text-xs text-gray-500">
              <span>레이블</span>
              {hasBinding && <span className="text-blue-600">● 연결됨</span>}
            </div>
            <div
              style={{
                fontSize: `${component.fontSize}px`,
                color: component.fontColor,
                fontWeight: component.fontWeight,
                textAlign: component.textAlign as "left" | "center" | "right",
              }}
            >
              {displayValue}
            </div>
          </div>
        );

      case "table":
        // 테이블은 쿼리 결과의 모든 행과 필드를 표시
        if (component.queryId) {
          const queryResult = getQueryResult(component.queryId);

          if (queryResult && queryResult.rows.length > 0) {
            return (
              <div className="h-full w-full overflow-auto">
                <div className="mb-1 flex items-center justify-between text-xs text-gray-500">
                  <span>테이블 (디테일 데이터)</span>
                  <span className="text-blue-600">● 연결됨</span>
                </div>
                <table className="w-full border-collapse text-xs">
                  <thead>
                    <tr className="bg-gray-100">
                      {queryResult.fields.map((field) => (
                        <th key={field} className="border p-1">
                          {field}
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {queryResult.rows.slice(0, 3).map((row, idx) => (
                      <tr key={idx}>
                        {queryResult.fields.map((field) => (
                          <td key={field} className="border p-1">
                            {String(row[field] ?? "")}
                          </td>
                        ))}
                      </tr>
                    ))}
                    {queryResult.rows.length > 3 && (
                      <tr>
                        <td colSpan={queryResult.fields.length} className="border p-1 text-center text-gray-400">
                          ... 외 {queryResult.rows.length - 3}건
                        </td>
                      </tr>
                    )}
                  </tbody>
                </table>
              </div>
            );
          }
        }

        // 기본 테이블 (데이터 없을 때)
        return (
          <div className="h-full w-full overflow-auto">
            <div className="mb-1 text-xs text-gray-500">테이블 (디테일 데이터)</div>
            <table className="w-full border-collapse text-xs">
              <thead>
                <tr className="bg-gray-100">
                  <th className="border p-1">품목명</th>
                  <th className="border p-1">수량</th>
                  <th className="border p-1">단가</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td className="border p-1">품목1</td>
                  <td className="border p-1">10</td>
                  <td className="border p-1">50,000</td>
                </tr>
              </tbody>
            </table>
          </div>
        );

      default:
        return <div>알 수 없는 컴포넌트</div>;
    }
  };

  return (
    <div
      ref={componentRef}
      className={`absolute cursor-move p-2 shadow-sm ${isSelected ? "ring-2 ring-blue-500" : ""}`}
      style={{
        left: `${component.x}px`,
        top: `${component.y}px`,
        width: `${component.width}px`,
        height: `${component.height}px`,
        zIndex: component.zIndex,
        backgroundColor: component.backgroundColor,
        border: component.borderWidth
          ? `${component.borderWidth}px solid ${component.borderColor}`
          : "1px solid #e5e7eb",
      }}
      onMouseDown={handleMouseDown}
    >
      {renderContent()}

      {/* 리사이즈 핸들 (선택된 경우만) */}
      {isSelected && (
        <div
          className="resize-handle absolute right-0 bottom-0 h-3 w-3 cursor-se-resize rounded-full bg-blue-500"
          style={{ transform: "translate(50%, 50%)" }}
          onMouseDown={handleResizeStart}
        />
      )}
    </div>
  );
}
