"use client";

import React, { useMemo } from "react";
import { ComponentData } from "@/types/screen";
import { useResponsive } from "@/lib/hooks/useResponsive";

interface ResponsiveGridRendererProps {
  components: ComponentData[];
  canvasWidth: number;
  canvasHeight: number;
  renderComponent: (component: ComponentData) => React.ReactNode;
}

// 전체 행을 차지해야 하는 컴포넌트 타입
const FULL_WIDTH_TYPES = new Set([
  "table-list",
  "v2-table-list",
  "table-search-widget",
  "v2-table-search-widget",
  "conditional-container",
  "split-panel-layout",
  "split-panel-layout2",
  "v2-split-line",
  "flow-widget",
  "v2-tab-container",
  "tab-container",
]);

// 높이를 auto로 처리해야 하는 컴포넌트 타입
const AUTO_HEIGHT_TYPES = new Set([
  "table-list",
  "v2-table-list",
  "table-search-widget",
  "v2-table-search-widget",
  "conditional-container",
  "flow-widget",
  "v2-tab-container",
  "tab-container",
  "split-panel-layout",
  "split-panel-layout2",
]);

/**
 * Y좌표 기준으로 컴포넌트를 행(row) 단위로 그룹핑
 * - Y값 차이가 threshold 이내면 같은 행으로 판정
 * - 같은 행 안에서는 X좌표 순으로 정렬
 */
function groupComponentsIntoRows(
  components: ComponentData[],
  threshold: number = 30
): ComponentData[][] {
  if (components.length === 0) return [];

  const sorted = [...components].sort((a, b) => a.position.y - b.position.y);

  const rows: ComponentData[][] = [];
  let currentRow: ComponentData[] = [];
  let currentRowY = -Infinity;

  for (const comp of sorted) {
    if (comp.position.y - currentRowY > threshold) {
      if (currentRow.length > 0) rows.push(currentRow);
      currentRow = [comp];
      currentRowY = comp.position.y;
    } else {
      currentRow.push(comp);
    }
  }
  if (currentRow.length > 0) rows.push(currentRow);

  return rows.map((row) =>
    row.sort((a, b) => a.position.x - b.position.x)
  );
}

/**
 * 컴포넌트의 유형 식별 (componentType, componentId, widgetType 등)
 */
function getComponentTypeId(component: ComponentData): string {
  return (
    (component as any).componentType ||
    (component as any).componentId ||
    (component as any).widgetType ||
    component.type ||
    ""
  );
}

/**
 * 전체 행을 차지해야 하는 컴포넌트인지 판정
 */
function isFullWidthComponent(component: ComponentData): boolean {
  const typeId = getComponentTypeId(component);
  return FULL_WIDTH_TYPES.has(typeId);
}

/**
 * 높이를 auto로 처리해야 하는 컴포넌트인지 판정
 */
function shouldAutoHeight(component: ComponentData): boolean {
  const typeId = getComponentTypeId(component);
  return AUTO_HEIGHT_TYPES.has(typeId);
}

/**
 * 컴포넌트 너비를 캔버스 대비 비율(%)로 변환
 */
function getPercentageWidth(
  componentWidth: number,
  canvasWidth: number
): number {
  const percentage = (componentWidth / canvasWidth) * 100;
  if (percentage >= 95) return 100;
  return percentage;
}

/**
 * 행 내 컴포넌트 사이의 수평 갭(px)을 비율 기반으로 추정
 */
function getRowGap(row: ComponentData[], canvasWidth: number): number {
  if (row.length < 2) return 0;
  const totalComponentWidth = row.reduce(
    (sum, c) => sum + (c.size?.width || 100),
    0
  );
  const totalGap = canvasWidth - totalComponentWidth;
  const gapCount = row.length - 1;
  if (totalGap <= 0 || gapCount <= 0) return 8;
  const gapPx = totalGap / gapCount;
  return Math.min(Math.max(Math.round(gapPx), 4), 24);
}

export function ResponsiveGridRenderer({
  components,
  canvasWidth,
  canvasHeight,
  renderComponent,
}: ResponsiveGridRendererProps) {
  const { isMobile } = useResponsive();

  // 전체 행을 차지하는 컴포넌트는 별도 행으로 분리
  const processedRows = useMemo(() => {
    const topLevel = components.filter((c) => !c.parentId);
    const rows = groupComponentsIntoRows(topLevel);

    const result: ComponentData[][] = [];
    for (const row of rows) {
      // 전체 너비 컴포넌트는 독립 행으로 분리
      const fullWidthComps: ComponentData[] = [];
      const normalComps: ComponentData[] = [];

      for (const comp of row) {
        if (isFullWidthComponent(comp)) {
          fullWidthComps.push(comp);
        } else {
          normalComps.push(comp);
        }
      }

      // 일반 컴포넌트 행 먼저
      if (normalComps.length > 0) {
        result.push(normalComps);
      }
      // 전체 너비 컴포넌트는 각각 독립 행
      for (const comp of fullWidthComps) {
        result.push([comp]);
      }
    }

    return result;
  }, [components]);

  return (
    <div
      data-screen-runtime="true"
      className="bg-background flex w-full flex-col"
      style={{ minHeight: "200px" }}
    >
      {processedRows.map((row, rowIndex) => {
        const isSingleFullWidth =
          row.length === 1 && isFullWidthComponent(row[0]);
        const gap = isMobile ? 8 : getRowGap(row, canvasWidth);

        return (
          <div
            key={`row-${rowIndex}`}
            className="flex w-full flex-wrap"
            style={{ gap: isSingleFullWidth ? 0 : `${gap}px` }}
          >
            {row.map((component) => {
              const typeId = getComponentTypeId(component);
              const isFullWidth =
                isMobile || isFullWidthComponent(component);
              const percentWidth = isFullWidth
                ? 100
                : getPercentageWidth(
                    component.size?.width || 100,
                    canvasWidth
                  );

              const autoHeight = shouldAutoHeight(component);
              const height = autoHeight
                ? "auto"
                : component.size?.height
                  ? `${component.size.height}px`
                  : "auto";

              // 모바일에서는 100%, 데스크톱에서는 비율 기반
              // gap을 고려한 flex-basis 계산
              const flexBasis = isFullWidth
                ? "100%"
                : `calc(${percentWidth}% - ${gap}px)`;

              return (
                <div
                  key={component.id}
                  data-component-id={component.id}
                  data-component-type={typeId}
                  className="flex-shrink-0"
                  style={{
                    width: isFullWidth ? "100%" : undefined,
                    flexBasis: isFullWidth ? "100%" : flexBasis,
                    flexGrow: isFullWidth ? 1 : 0,
                    minWidth: isMobile ? "100%" : undefined,
                    height,
                    minHeight: autoHeight ? undefined : height,
                  }}
                >
                  {renderComponent(component)}
                </div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}

export default ResponsiveGridRenderer;
