"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컬럼 그리드 클래스 매핑 (모바일 단일 컬럼 → sm: 실제 컬럼 수)
  const gridColsClass: Record<number, string> = {
    1: "grid-cols-1",
    2: "grid-cols-1 sm:grid-cols-2",
    3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
    4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
    5: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-5",
    6: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-6",
    7: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-7",
    8: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-8",
    9: "grid-cols-1 sm:grid-cols-3 lg:grid-cols-9",
    10: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-10",
    11: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-11",
    12: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-12",
  };

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

  // 기존 방식 (동적 컬럼 수) - 모바일에서 단일 컬럼으로 전환
  return (
    <div
      ref={ref}
      className={cn("grid grid-cols-1", 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-col sm:flex-row" : "flex-col",
        className
      )}
      style={{ gap }}
    >
      {/* 첫 번째 패널 - 모바일에서 전체 너비 */}
      <div
        className="overflow-auto w-full sm:w-auto"
        style={{
          [isHorizontal ? "width" : "height"]: `${ratio[0]}%`,
          flexShrink: 0,
        }}
      >
        {childArray[0]}
      </div>

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

      {/* 두 번째 패널 - 모바일에서 전체 너비 */}
      <div
        className="overflow-auto flex-1 w-full sm:w-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" ? "h-px w-full my-4" : "w-px h-full mx-4",
        className
      )}
    />
  );
});
DividerLayout.displayName = "DividerLayout";

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

  // TODO: 실제 화면 임베딩 로직 구현
  // InteractiveScreenViewer와 연동 필요
  return (
    <div
      ref={ref}
      className={cn(
        "border rounded-lg p-4",
        className
      )}
    >
      <div className="text-sm text-muted-foreground mb-2">
        임베딩된 화면 (ID: {screenId})
      </div>
      <div className="h-48 bg-muted/30 rounded flex items-center justify-center">
        {/* 여기에 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;

