/**
 * 반응형 레이아웃 엔진
 *
 * 절대 위치로 배치된 컴포넌트들을 반응형 그리드로 변환
 */

import React, { useMemo } from "react";
import { ComponentData } from "@/types/screen-management";
import { Breakpoint, BREAKPOINTS } from "@/types/responsive";
import { generateSmartDefaults, ensureResponsiveConfig } from "@/lib/utils/responsiveDefaults";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";

export interface ResponsiveLayoutEngineProps {
  components: ComponentData[];
  breakpoint: Breakpoint;
  containerWidth: number;
  screenWidth?: number;
  preserveYPosition?: boolean; // true: Y좌표 유지 (하이브리드), false: 16px 간격 (반응형)
  formData?: Record<string, unknown>;
  onFormDataChange?: (fieldName: string, value: unknown) => void;
  screenInfo?: { id: number; tableName?: string };
}

/**
 * 반응형 레이아웃 엔진
 *
 * 변환 로직:
 * 1. Y 위치 기준으로 행(row)으로 그룹화
 * 2. 각 행 내에서 X 위치 기준으로 정렬
 * 3. 반응형 설정 적용 (order, gridColumns, hide)
 * 4. CSS Grid로 렌더링
 */
export const ResponsiveLayoutEngine: React.FC<ResponsiveLayoutEngineProps> = ({
  components,
  breakpoint,
  containerWidth,
  screenWidth = 1920,
  preserveYPosition = false, // 기본값: 반응형 모드 (16px 간격)
  formData,
  onFormDataChange,
  screenInfo,
}) => {
  // 1단계: 컴포넌트들을 Y 위치 기준으로 행(row)으로 그룹화
  const rows = useMemo(() => {
    const sortedComponents = [...components].sort((a, b) => a.position.y - b.position.y);

    const rows: ComponentData[][] = [];
    let currentRow: ComponentData[] = [];
    let currentRowY = 0;
    const ROW_THRESHOLD = 150; // 같은 행으로 간주할 Y 오차 범위 (px) - 여유있게 설정

    sortedComponents.forEach((comp) => {
      if (currentRow.length === 0) {
        currentRow.push(comp);
        currentRowY = comp.position.y;
      } else if (Math.abs(comp.position.y - currentRowY) < ROW_THRESHOLD) {
        currentRow.push(comp);
      } else {
        rows.push(currentRow);
        currentRow = [comp];
        currentRowY = comp.position.y;
      }
    });

    if (currentRow.length > 0) {
      rows.push(currentRow);
    }

    return rows;
  }, [components]);

  // 2단계: 각 행 내에서 X 위치 기준으로 정렬
  const sortedRows = useMemo(() => {
    return rows.map((row) => [...row].sort((a, b) => a.position.x - b.position.x));
  }, [rows]);

  // 3단계: 반응형 설정 적용
  const responsiveComponents = useMemo(() => {
    const result = sortedRows.flatMap((row, rowIndex) =>
      row.map((comp, compIndex) => {
        // 컴포넌트에 gridColumns가 이미 설정되어 있으면 그 값 사용
        if ((comp as any).gridColumns !== undefined) {
          return {
            ...comp,
            responsiveDisplay: {
              gridColumns: (comp as any).gridColumns,
              order: compIndex + 1,
              hide: false,
            },
          };
        }

        // 반응형 설정이 없으면 자동 생성
        const compWithConfig = ensureResponsiveConfig(comp, screenWidth);

        // 현재 브레이크포인트의 설정 가져오기 (같은 행의 컴포넌트 개수 전달)
        const config = compWithConfig.responsiveConfig!.useSmartDefaults
          ? generateSmartDefaults(comp, screenWidth, row.length)[breakpoint]
          : compWithConfig.responsiveConfig!.responsive?.[breakpoint];

        const finalConfig = config || generateSmartDefaults(comp, screenWidth, row.length)[breakpoint];

        return {
          ...compWithConfig,
          responsiveDisplay: finalConfig,
        };
      }),
    );

    return result;
  }, [sortedRows, breakpoint, screenWidth]);

  // 4단계: 필터링 및 정렬
  const visibleComponents = useMemo(() => {
    return responsiveComponents
      .filter((comp) => !comp.responsiveDisplay?.hide)
      .sort((a, b) => (a.responsiveDisplay?.order || 0) - (b.responsiveDisplay?.order || 0));
  }, [responsiveComponents]);

  const gridColumns = BREAKPOINTS[breakpoint].columns;

  // 각 행의 Y 위치를 추적
  const rowsWithYPosition = useMemo(() => {
    return sortedRows.map((row) => ({
      components: row,
      yPosition: Math.min(...row.map((c) => c.position.y)), // 행의 최소 Y 위치
    }));
  }, [sortedRows]);

  return (
    <div className="responsive-container w-full" style={{ position: "relative" }}>
      {rowsWithYPosition.map((row, rowIndex) => {
        const rowComponents = visibleComponents.filter((vc) => row.components.some((rc) => rc.id === vc.id));

        // Y 좌표 계산: preserveYPosition에 따라 다르게 처리
        let marginTop: string;
        if (preserveYPosition) {
          // 하이브리드 모드: 원래 Y 좌표 간격 유지
          if (rowIndex === 0) {
            marginTop = `${row.yPosition}px`;
          } else {
            const prevRowY = rowsWithYPosition[rowIndex - 1].yPosition;
            const actualGap = row.yPosition - prevRowY;
            marginTop = `${actualGap}px`;
          }
        } else {
          // 반응형 모드: 첫 번째는 맨 위부터 시작 (0px), 나머지는 16px 고정 간격
          marginTop = rowIndex === 0 ? "0px" : "16px";
        }

        return (
          <div
            key={`row-${rowIndex}`}
            className="responsive-grid w-full"
            style={{
              display: "grid",
              gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,
              gap: "16px",
              padding: "0 16px",
              marginTop,
              alignItems: "start", // 각 아이템이 원래 높이 유지
            }}
          >
            {rowComponents.map((comp) => (
              <div
                key={comp.id}
                className="responsive-grid-item"
                style={{
                  gridColumn: `span ${comp.responsiveDisplay?.gridColumns || gridColumns}`,
                  height: "auto", // 자동 높이
                }}
              >
                <DynamicComponentRenderer
                  component={comp}
                  isPreview={true}
                  isDesignMode={false}
                  isInteractive={true}
                  formData={formData}
                  onFormDataChange={onFormDataChange}
                  screenId={screenInfo?.id}
                  tableName={screenInfo?.tableName}
                />
              </div>
            ))}
          </div>
        );
      })}
    </div>
  );
};
