"use client";

/**
 * V2Layout
 *
 * 통합 레이아웃 컴포넌트
 * - grid: 그리드 레이아웃
 * - split: 분할 레이아웃
 * - flex: 플렉스 레이아웃
 * - divider: 구분선
 * - screen-embed: 화면 임베딩
 */

import React, { forwardRef, useCallback, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import { V2LayoutProps } from "@/types/v2-components";
import { GripVertical, GripHorizontal } from "lucide-react";

/**
 * 그리드 레이아웃 컴포넌트 (12컬럼 시스템)
 *
 * 사용법:
 * - columns: 컬럼 수 (기본 12, 전통적 그리드)
 * - colSpan: 자식 요소별 span 지정 시 사용
 * - Tailwind의 grid-cols-12 기반
 */
const GridLayout = forwardRef<
  HTMLDivElement,
  {
    columns?: number; // 12컬럼 시스템에서 몇 컬럼으로 나눌지 (1-12)
    gap?: string;
    children?: React.ReactNode;
    className?: string;
    use12Column?: boolean; // 12컬럼 시스템 사용 여부
  }
>(({ columns = 12, gap = "16px", children, className, use12Column = true }, ref) => {
  // 12컬럼 그리드 클래스 매핑
  const gridColsClass: Record<number, string> = {
    1: "grid-cols-1",
    2: "grid-cols-2",
    3: "grid-cols-3",
    4: "grid-cols-4",
    5: "grid-cols-5",
    6: "grid-cols-6",
    7: "grid-cols-7",
    8: "grid-cols-8",
    9: "grid-cols-9",
    10: "grid-cols-10",
    11: "grid-cols-11",
    12: "grid-cols-12",
  };

  // 12컬럼 시스템 사용 시
  if (use12Column) {
    return (
      <div ref={ref} className={cn("grid", gridColsClass[columns] || "grid-cols-12", className)} style={{ gap }}>
        {children}
      </div>
    );
  }

  // 기존 방식 (동적 컬럼 수)
  return (
    <div
      ref={ref}
      className={cn("grid", className)}
      style={{
        gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
        gap,
      }}
    >
      {children}
    </div>
  );
});
GridLayout.displayName = "GridLayout";

/**
 * 분할 레이아웃 컴포넌트 (리사이즈 가능)
 */
const SplitLayout = forwardRef<
  HTMLDivElement,
  {
    direction?: "horizontal" | "vertical";
    splitRatio?: number[];
    gap?: string;
    children?: React.ReactNode;
    className?: string;
  }
>(({ direction = "horizontal", splitRatio = [50, 50], gap = "8px", children, className }, ref) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const [ratio, setRatio] = useState(splitRatio);
  const [isDragging, setIsDragging] = useState(false);

  const childArray = React.Children.toArray(children);
  const isHorizontal = direction === "horizontal";

  // 리사이저 드래그 시작
  const handleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault();
      setIsDragging(true);

      const startPos = isHorizontal ? e.clientX : e.clientY;
      const startRatio = [...ratio];
      const container = containerRef.current;

      const handleMouseMove = (moveEvent: MouseEvent) => {
        if (!container) return;

        const containerSize = isHorizontal ? container.offsetWidth : container.offsetHeight;
        const currentPos = isHorizontal ? moveEvent.clientX : moveEvent.clientY;
        const delta = currentPos - startPos;
        const deltaPercent = (delta / containerSize) * 100;

        const newFirst = Math.max(10, Math.min(90, startRatio[0] + deltaPercent));
        const newSecond = 100 - newFirst;

        setRatio([newFirst, newSecond]);
      };

      const handleMouseUp = () => {
        setIsDragging(false);
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    },
    [isHorizontal, ratio],
  );

  return (
    <div
      ref={(node) => {
        (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node;
        if (typeof ref === "function") ref(node);
        else if (ref) ref.current = node;
      }}
      className={cn("flex", isHorizontal ? "flex-row" : "flex-col", className)}
      style={{ gap }}
    >
      {/* 첫 번째 패널 */}
      <div
        className="overflow-auto"
        style={{
          [isHorizontal ? "width" : "height"]: `${ratio[0]}%`,
          flexShrink: 0,
        }}
      >
        {childArray[0]}
      </div>

      {/* 리사이저 */}
      <div
        className={cn(
          "bg-border hover:bg-primary/20 flex items-center justify-center transition-colors",
          isHorizontal ? "w-2 cursor-col-resize" : "h-2 cursor-row-resize",
          isDragging && "bg-primary/30",
        )}
        onMouseDown={handleMouseDown}
      >
        {isHorizontal ? (
          <GripVertical className="text-muted-foreground h-4 w-4" />
        ) : (
          <GripHorizontal className="text-muted-foreground h-4 w-4" />
        )}
      </div>

      {/* 두 번째 패널 */}
      <div
        className="flex-1 overflow-auto"
        style={{
          [isHorizontal ? "width" : "height"]: `${ratio[1]}%`,
        }}
      >
        {childArray[1]}
      </div>
    </div>
  );
});
SplitLayout.displayName = "SplitLayout";

/**
 * 플렉스 레이아웃 컴포넌트
 */
const FlexLayout = forwardRef<
  HTMLDivElement,
  {
    direction?: "horizontal" | "vertical";
    gap?: string;
    wrap?: boolean;
    justify?: "start" | "center" | "end" | "between" | "around";
    align?: "start" | "center" | "end" | "stretch";
    children?: React.ReactNode;
    className?: string;
  }
>(
  (
    { direction = "horizontal", gap = "16px", wrap = false, justify = "start", align = "stretch", children, className },
    ref,
  ) => {
    const justifyMap = {
      start: "flex-start",
      center: "center",
      end: "flex-end",
      between: "space-between",
      around: "space-around",
    };

    const alignMap = {
      start: "flex-start",
      center: "center",
      end: "flex-end",
      stretch: "stretch",
    };

    return (
      <div
        ref={ref}
        className={cn("flex", className)}
        style={{
          flexDirection: direction === "horizontal" ? "row" : "column",
          flexWrap: wrap ? "wrap" : "nowrap",
          justifyContent: justifyMap[justify],
          alignItems: alignMap[align],
          gap,
        }}
      >
        {children}
      </div>
    );
  },
);
FlexLayout.displayName = "FlexLayout";

/**
 * 구분선 컴포넌트
 */
const DividerLayout = forwardRef<
  HTMLDivElement,
  {
    direction?: "horizontal" | "vertical";
    className?: string;
  }
>(({ direction = "horizontal", className }, ref) => {
  return (
    <div
      ref={ref}
      className={cn("bg-border", direction === "horizontal" ? "my-4 h-px w-full" : "mx-4 h-full w-px", className)}
    />
  );
});
DividerLayout.displayName = "DividerLayout";

/**
 * 화면 임베딩 컴포넌트
 */
const ScreenEmbedLayout = forwardRef<
  HTMLDivElement,
  {
    screenId?: number;
    className?: string;
  }
>(({ screenId, className }, ref) => {
  if (!screenId) {
    return (
      <div
        ref={ref}
        className={cn(
          "text-muted-foreground flex h-32 items-center justify-center rounded-lg border-2 border-dashed",
          className,
        )}
      >
        화면을 선택하세요
      </div>
    );
  }

  // TODO: 실제 화면 임베딩 로직 구현
  // InteractiveScreenViewer와 연동 필요
  return (
    <div ref={ref} className={cn("rounded-lg border p-4", className)}>
      <div className="text-muted-foreground mb-2 text-sm">임베딩된 화면 (ID: {screenId})</div>
      <div className="bg-muted/30 flex h-48 items-center justify-center rounded">
        {/* 여기에 InteractiveScreenViewer 렌더링 */}
        화면 내용이 여기에 표시됩니다
      </div>
    </div>
  );
});
ScreenEmbedLayout.displayName = "ScreenEmbedLayout";

/**
 * 메인 V2Layout 컴포넌트
 */
export const V2Layout = forwardRef<HTMLDivElement, V2LayoutProps>((props, ref) => {
  const { id, style, size, config: configProp, children } = props;

  // config가 없으면 기본값 사용
  const config = configProp || { type: "grid" as const, columns: 2 };

  // 타입별 레이아웃 렌더링
  const renderLayout = () => {
    const layoutType = config.type || "grid";
    switch (layoutType) {
      case "grid":
        return (
          <GridLayout columns={config.columns} gap={config.gap}>
            {children}
          </GridLayout>
        );

      case "split":
        return (
          <SplitLayout direction={config.direction} splitRatio={config.splitRatio} gap={config.gap}>
            {children}
          </SplitLayout>
        );

      case "flex":
        return (
          <FlexLayout direction={config.direction} gap={config.gap}>
            {children}
          </FlexLayout>
        );

      case "divider":
        return <DividerLayout direction={config.direction} />;

      case "screen-embed":
        return <ScreenEmbedLayout screenId={config.screenId} />;

      default:
        return (
          <GridLayout columns={config.columns} gap={config.gap}>
            {children}
          </GridLayout>
        );
    }
  };

  const componentWidth = size?.width || style?.width;
  const componentHeight = size?.height || style?.height;

  return (
    <div
      ref={ref}
      id={id}
      style={{
        width: componentWidth,
        height: componentHeight,
      }}
    >
      {renderLayout()}
    </div>
  );
});

V2Layout.displayName = "V2Layout";

export default V2Layout;
