"use client";

import React from "react";
import { ComponentData } from "@/types/screen";
import { DynamicLayoutRenderer } from "./DynamicLayoutRenderer";
import { ComponentRegistry } from "./ComponentRegistry";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";

// 컴포넌트 렌더러 인터페이스
export interface ComponentRenderer {
  (props: {
    component: ComponentData;
    isSelected?: boolean;
    isInteractive?: boolean;
    formData?: Record<string, any>;
    originalData?: Record<string, any>; // 부분 업데이트용 원본 데이터
    onFormDataChange?: (fieldName: string, value: any) => void;
    onClick?: (e?: React.MouseEvent) => void;
    onDragStart?: (e: React.DragEvent) => void;
    onDragEnd?: () => void;
    children?: React.ReactNode;
    onZoneComponentDrop?: (e: React.DragEvent, zoneId: string, layoutId: string) => void;
    onZoneClick?: (zoneId: string) => void;
    // 버튼 액션을 위한 추가 props
    screenId?: number;
    tableName?: string;
    onRefresh?: () => void;
    onClose?: () => void;
    // 테이블 선택된 행 정보 (다중 선택 액션용)
    selectedRows?: any[];
    selectedRowsData?: any[];
    onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
    // 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
    flowSelectedData?: any[];
    flowSelectedStepId?: number | null;
    onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
    // 테이블 새로고침 키
    refreshKey?: number;
    // 편집 모드
    mode?: "view" | "edit";
    // 설정 변경 핸들러 (상세설정과 연동)
    onConfigChange?: (config: any) => void;
    [key: string]: any;
  }): React.ReactElement;
}

// 레거시 렌더러 레지스트리 (기존 컴포넌트들용)
class LegacyComponentRegistry {
  private renderers: Map<string, ComponentRenderer> = new Map();

  // 컴포넌트 렌더러 등록
  register(componentType: string, renderer: ComponentRenderer) {
    this.renderers.set(componentType, renderer);
  }

  // 컴포넌트 렌더러 조회
  get(componentType: string): ComponentRenderer | undefined {
    return this.renderers.get(componentType);
  }

  // 등록된 모든 컴포넌트 타입 조회
  getRegisteredTypes(): string[] {
    return Array.from(this.renderers.keys());
  }

  // 컴포넌트 타입이 등록되어 있는지 확인
  has(componentType: string): boolean {
    const result = this.renderers.has(componentType);
    return result;
  }
}

// 전역 레거시 레지스트리 인스턴스
export const legacyComponentRegistry = new LegacyComponentRegistry();

// 하위 호환성을 위한 기존 이름 유지
export const componentRegistry = legacyComponentRegistry;

// 동적 컴포넌트 렌더러 컴포넌트
export interface DynamicComponentRendererProps {
  component: ComponentData;
  isSelected?: boolean;
  isPreview?: boolean; // 반응형 모드 플래그
  isDesignMode?: boolean; // 디자인 모드 여부 (false일 때 데이터 로드)
  onClick?: (e?: React.MouseEvent) => void;
  onDragStart?: (e: React.DragEvent) => void;
  onDragEnd?: () => void;
  children?: React.ReactNode;
  // 폼 데이터 관련
  formData?: Record<string, any>;
  originalData?: Record<string, any>; // 부분 업데이트용 원본 데이터
  onFormDataChange?: (fieldName: string, value: any) => void;
  // 버튼 액션을 위한 추가 props
  screenId?: number;
  tableName?: string;
  onRefresh?: () => void;
  onClose?: () => void;
  // 테이블 선택된 행 정보 (다중 선택 액션용)
  selectedRows?: any[];
  selectedRowsData?: any[];
  onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
  // 플로우 선택된 데이터 정보 (플로우 위젯 선택 액션용)
  flowSelectedData?: any[];
  flowSelectedStepId?: number | null;
  onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
  // 테이블 새로고침 키
  refreshKey?: number;
  // 플로우 새로고침 키
  flowRefreshKey?: number;
  onFlowRefresh?: () => void;
  // 편집 모드
  mode?: "view" | "edit";
  // 모달 내에서 렌더링 여부
  isInModal?: boolean;
  [key: string]: any;
}

export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> = ({
  component,
  isSelected = false,
  isPreview = false,
  onClick,
  onDragStart,
  onDragEnd,
  children,
  ...props
}) => {
  // 컴포넌트 타입 추출 - 새 시스템에서는 componentType 속성 사용, 레거시는 type 사용
  const componentType = (component as any).componentType || component.type;

  // 레이아웃 컴포넌트 처리
  if (componentType === "layout") {
    // DOM 안전한 props만 전달
    const safeLayoutProps = filterDOMProps(props);

    return (
      <DynamicLayoutRenderer
        layout={component as any}
        allComponents={props.allComponents || []}
        isSelected={isSelected}
        onClick={onClick}
        onDragStart={onDragStart}
        onDragEnd={onDragEnd}
        onUpdateLayout={props.onUpdateLayout}
        // onComponentDrop 제거 - 일반 캔버스 드롭만 사용
        onZoneClick={props.onZoneClick}
        isInteractive={props.isInteractive}
        formData={props.formData}
        onFormDataChange={props.onFormDataChange}
        screenId={props.screenId}
        tableName={props.tableName}
        onRefresh={props.onRefresh}
        onClose={props.onClose}
        mode={props.mode}
        isInModal={props.isInModal}
        originalData={props.originalData}
        {...safeLayoutProps}
      />
    );
  }

  // 1. 새 컴포넌트 시스템에서 먼저 조회
  const newComponent = ComponentRegistry.getComponent(componentType);

  if (newComponent) {
    // 새 컴포넌트 시스템으로 렌더링
    try {
      const NewComponentRenderer = newComponent.component;
      if (NewComponentRenderer) {
        // React 전용 props들을 명시적으로 분리하고 DOM 안전한 props만 전달
        const {
          isInteractive,
          formData,
          onFormDataChange,
          tableName,
          onRefresh,
          onClose,
          screenId,
          mode,
          isInModal,
          originalData,
          allComponents,
          onUpdateLayout,
          onZoneClick,
          selectedRows,
          selectedRowsData,
          onSelectedRowsChange,
          flowSelectedData,
          flowSelectedStepId,
          onFlowSelectedDataChange,
          refreshKey,
          flowRefreshKey, // Added this
          onFlowRefresh, // Added this
          onConfigChange,
          isPreview,
          autoGeneration,
          ...restProps
        } = props;
        
        // DOM 안전한 props만 필터링
        const safeProps = filterDOMProps(restProps);

        // 컴포넌트의 columnName에 해당하는 formData 값 추출
        const fieldName = (component as any).columnName || component.id;
        const currentValue = formData?.[fieldName] || "";

        console.log("🔍 DynamicComponentRenderer - 새 컴포넌트 시스템:", {
          componentType,
          componentId: component.id,
          columnName: (component as any).columnName,
          fieldName,
          currentValue,
          hasFormData: !!formData,
          formDataKeys: formData ? Object.keys(formData) : [],
          autoGeneration: component.autoGeneration,
          hidden: component.hidden,
          isInteractive,
          isPreview, // 반응형 모드 플래그
          isDesignMode: props.isDesignMode, // 디자인 모드 플래그
        });

        // onChange 핸들러 - 컴포넌트 타입에 따라 다르게 처리
        const handleChange = (value: any) => {
          // React 이벤트 객체인 경우 값 추출
          let actualValue = value;
          if (value && typeof value === "object" && value.nativeEvent && value.target) {
            // SyntheticEvent인 경우 target.value 추출
            actualValue = value.target.value;
            console.log("⚠️ DynamicComponentRenderer: 이벤트 객체 감지, value 추출:", actualValue);
          }

          console.log("🔄 DynamicComponentRenderer handleChange 호출:", {
            componentType,
            fieldName,
            originalValue: value,
            actualValue,
            valueType: typeof actualValue,
            isArray: Array.isArray(actualValue),
          });

          if (onFormDataChange) {
            // RepeaterInput 같은 복합 컴포넌트는 전체 데이터를 전달
            // 단순 input 컴포넌트는 (fieldName, value) 형태로 전달받음
            if (componentType === "repeater-field-group" || componentType === "repeater") {
              // fieldName과 함께 전달
              console.log("💾 RepeaterInput 데이터 저장:", fieldName, actualValue);
              onFormDataChange(fieldName, actualValue);
            } else {
              // 이미 fieldName이 포함된 경우는 그대로 전달
              onFormDataChange(fieldName, actualValue);
            }
          }
        };

        // 렌더러 props 구성
        // component.style에서 height 제거 (RealtimePreviewDynamic에서 size.height로 처리)
        const { height: _height, ...styleWithoutHeight } = component.style || {};
        
        // 숨김 값 추출 (디버깅)
        const hiddenValue = component.hidden || component.componentConfig?.hidden;
        if (hiddenValue) {
          console.log("🔍 DynamicComponentRenderer hidden 체크:", {
            componentId: component.id,
            componentType,
            componentHidden: component.hidden,
            componentConfigHidden: component.componentConfig?.hidden,
            finalHiddenValue: hiddenValue,
            isDesignMode: props.isDesignMode,
          });
        }
        
        const rendererProps = {
          component,
          isSelected,
          onClick,
          onDragStart,
          onDragEnd,
          size: component.size || newComponent.defaultSize,
          position: component.position,
          style: styleWithoutHeight,
          config: component.componentConfig,
          componentConfig: component.componentConfig,
          value: currentValue, // formData에서 추출한 현재 값 전달
          // 새로운 기능들 전달
          autoGeneration: component.autoGeneration || component.componentConfig?.autoGeneration,
          hidden: hiddenValue,
          // React 전용 props들은 직접 전달 (DOM에 전달되지 않음)
          isInteractive,
          formData,
          onFormDataChange,
          onChange: handleChange, // 개선된 onChange 핸들러 전달
          tableName,
          onRefresh,
          onClose,
          screenId,
          mode,
          isInModal,
          readonly: component.readonly,
          disabled: component.readonly,
          originalData,
          allComponents,
          onUpdateLayout,
          onZoneClick,
          // 테이블 선택된 행 정보 전달
          selectedRows,
          selectedRowsData,
          onSelectedRowsChange,
          // 플로우 선택된 데이터 정보 전달
          flowSelectedData,
          flowSelectedStepId,
          onFlowSelectedDataChange,
          // 설정 변경 핸들러 전달
          onConfigChange,
          refreshKey,
          // 플로우 새로고침 키
          flowRefreshKey,
          onFlowRefresh,
          // 반응형 모드 플래그 전달
          isPreview,
          // 디자인 모드 플래그 전달 - isPreview와 명확히 구분
          isDesignMode: props.isDesignMode !== undefined ? props.isDesignMode : false,
        };

        // 렌더러가 클래스인지 함수인지 확인
        console.log("🔍🔍 DynamicComponentRenderer - 렌더러 타입 확인:", {
          componentType,
          isFunction: typeof NewComponentRenderer === "function",
          hasPrototype: !!NewComponentRenderer.prototype,
          hasRenderMethod: !!NewComponentRenderer.prototype?.render,
          rendererName: NewComponentRenderer.name,
        });

        if (
          typeof NewComponentRenderer === "function" &&
          NewComponentRenderer.prototype &&
          NewComponentRenderer.prototype.render
        ) {
          // 클래스 기반 렌더러 (AutoRegisteringComponentRenderer 상속)
          console.log("✅ 클래스 기반 렌더러로 렌더링:", componentType);
          const rendererInstance = new NewComponentRenderer(rendererProps);
          return rendererInstance.render();
        } else {
          // 함수형 컴포넌트
          console.log("✅ 함수형 컴포넌트로 렌더링:", componentType);
          return <NewComponentRenderer {...rendererProps} />;
        }
      }
    } catch (error) {
      console.error(`❌ 새 컴포넌트 렌더링 실패 (${componentType}):`, error);
    }
  }

  // 2. 레거시 시스템에서 조회
  const renderer = legacyComponentRegistry.get(componentType);

  if (!renderer) {
    console.error(`⚠️ 등록되지 않은 컴포넌트 타입: ${componentType}`, {
      component: component,
      componentType: componentType,
      componentConfig: component.componentConfig,
      availableNewComponents: ComponentRegistry.getAllComponents().map((c) => c.id),
      availableLegacyComponents: legacyComponentRegistry.getRegisteredTypes(),
    });

    // 폴백 렌더링 - 기본 플레이스홀더
    return (
      <div className="flex h-full w-full items-center justify-center rounded border-2 border-dashed border-gray-300 bg-gray-50 p-4">
        <div className="text-center">
          <div className="mb-2 text-sm font-medium text-gray-600">{component.label || component.id}</div>
          <div className="text-xs text-gray-400">미구현 컴포넌트: {componentType}</div>
        </div>
      </div>
    );
  }

  // 동적 렌더링 실행
  try {
    // 레거시 시스템에서도 DOM 안전한 props만 전달
    const safeLegacyProps = filterDOMProps(props);

    return renderer({
      component,
      isSelected,
      onClick,
      onDragStart,
      onDragEnd,
      children,
      // React 전용 props들은 명시적으로 전달 (레거시 컴포넌트가 필요한 경우)
      isInteractive: props.isInteractive,
      formData: props.formData,
      onFormDataChange: props.onFormDataChange,
      screenId: props.screenId,
      tableName: props.tableName,
      onRefresh: props.onRefresh,
      onClose: props.onClose,
      mode: props.mode,
      isInModal: props.isInModal,
      originalData: props.originalData,
      onUpdateLayout: props.onUpdateLayout,
      onZoneClick: props.onZoneClick,
      onZoneComponentDrop: props.onZoneComponentDrop,
      allComponents: props.allComponents,
      // 테이블 선택된 행 정보 전달
      selectedRows: props.selectedRows,
      selectedRowsData: props.selectedRowsData,
      onSelectedRowsChange: props.onSelectedRowsChange,
      // 플로우 선택된 데이터 정보 전달
      flowSelectedData: props.flowSelectedData,
      flowSelectedStepId: props.flowSelectedStepId,
      onFlowSelectedDataChange: props.onFlowSelectedDataChange,
      refreshKey: props.refreshKey,
      // DOM 안전한 props들
      ...safeLegacyProps,
    });
  } catch (error) {
    console.error(`❌ 컴포넌트 렌더링 실패 (${componentType}):`, error);

    // 오류 발생 시 폴백 렌더링
    return (
      <div className="flex h-full w-full items-center justify-center rounded border-2 border-red-300 bg-red-50 p-4">
        <div className="text-center">
          <div className="mb-2 text-sm font-medium text-red-600">렌더링 오류</div>
          <div className="text-xs text-red-400">
            {componentType}: {error instanceof Error ? error.message : "알 수 없는 오류"}
          </div>
        </div>
      </div>
    );
  }
};

export default DynamicComponentRenderer;
