"use client";

import React, { useEffect, useRef, useCallback, useMemo, useState } from "react";
import { Layers } from "lucide-react";
import { AutoRegisteringComponentRenderer } from "../../AutoRegisteringComponentRenderer";
import { ComponentDefinition, ComponentCategory, ComponentRendererProps } from "@/types/component";
import { RepeaterInput } from "@/components/webtypes/RepeaterInput";
import { RepeaterConfigPanel } from "@/components/webtypes/config/RepeaterConfigPanel";
import { useScreenContextOptional, DataReceivable } from "@/contexts/ScreenContext";
import { useSplitPanelContext } from "@/contexts/SplitPanelContext";
import { applyMappingRules } from "@/lib/utils/dataMapping";
import { toast } from "sonner";
import { apiClient } from "@/lib/api/client";

/**
 * Repeater Field Group 컴포넌트
 */
const RepeaterFieldGroupComponent: React.FC<ComponentRendererProps> = (props) => {
  const { component, value, onChange, readonly, disabled, formData, onFormDataChange, menuObjid } = props;
  const screenContext = useScreenContextOptional();
  const splitPanelContext = useSplitPanelContext();
  const receiverRef = useRef<DataReceivable | null>(null);
  
  // 🆕 그룹화된 데이터를 저장하는 상태
  const [groupedData, setGroupedData] = useState<any[] | null>(null);
  const [isLoadingGroupData, setIsLoadingGroupData] = useState(false);
  const groupDataLoadedRef = useRef(false);
  
  // 🆕 원본 데이터 ID 목록 (삭제 추적용)
  const [originalItemIds, setOriginalItemIds] = useState<string[]>([]);

  // 컴포넌트의 필드명 (formData 키)
  const fieldName = (component as any).columnName || component.id;

  // repeaterConfig 또는 componentConfig에서 설정 가져오기
  const config = (component as any).repeaterConfig || component.componentConfig || { fields: [] };
  
  // 🆕 그룹화 설정 (예: groupByColumn: "inbound_number")
  const groupByColumn = config.groupByColumn;
  const targetTable = config.targetTable;

  // formData에서 값 가져오기 (value prop보다 우선)
  const rawValue = formData?.[fieldName] ?? value;

  // 🆕 수정 모드 감지: formData에 id가 있고, fieldName으로 값을 찾지 못한 경우
  // formData 자체를 배열의 첫 번째 항목으로 사용 (단일 행 수정 시)
  const isEditMode = formData?.id && !rawValue && !value;
  
  // 🆕 반복 필드 그룹의 필드들이 formData에 있는지 확인
  const configFields = config.fields || [];
  const hasRepeaterFieldsInFormData = configFields.length > 0 && 
    configFields.some((field: any) => formData?.[field.name] !== undefined);

  // 🆕 formData와 config.fields의 필드 이름 매칭 확인
  const matchingFields = configFields.filter((field: any) => formData?.[field.name] !== undefined);
  
  // 🆕 그룹 키 값 (예: formData.inbound_number)
  const groupKeyValue = groupByColumn ? formData?.[groupByColumn] : null;
  
  console.log("🔄 [RepeaterFieldGroup] 렌더링:", { 
    fieldName, 
    hasFormData: !!formData, 
    formDataId: formData?.id,
    formDataValue: formData?.[fieldName],
    propsValue: value,
    rawValue,
    isEditMode,
    hasRepeaterFieldsInFormData,
    configFieldNames: configFields.map((f: any) => f.name),
    formDataKeys: formData ? Object.keys(formData) : [],
    matchingFieldNames: matchingFields.map((f: any) => f.name),
    groupByColumn,
    groupKeyValue,
    targetTable,
    hasGroupedData: groupedData !== null,
    groupedDataLength: groupedData?.length,
  });

  // 🆕 수정 모드에서 그룹화된 데이터 로드
  useEffect(() => {
    const loadGroupedData = async () => {
      // 이미 로드했거나 조건이 맞지 않으면 스킵
      if (groupDataLoadedRef.current) return;
      if (!isEditMode || !groupByColumn || !groupKeyValue || !targetTable) return;
      
      console.log("📥 [RepeaterFieldGroup] 그룹 데이터 로드 시작:", {
        groupByColumn,
        groupKeyValue,
        targetTable,
      });
      
      setIsLoadingGroupData(true);
      groupDataLoadedRef.current = true;
      
      try {
        // API 호출: 같은 그룹 키를 가진 모든 데이터 조회
        // search 파라미터 사용 (filters가 아닌 search)
        const response = await apiClient.post(`/table-management/tables/${targetTable}/data`, {
          page: 1,
          size: 100, // 충분히 큰 값
          search: { [groupByColumn]: groupKeyValue },
        });
        
        console.log("🔍 [RepeaterFieldGroup] API 응답 구조:", {
          success: response.data?.success,
          hasData: !!response.data?.data,
          dataType: typeof response.data?.data,
          dataKeys: response.data?.data ? Object.keys(response.data.data) : [],
        });
        
        // 응답 구조: { success, data: { data: [...], total, page, totalPages } }
        if (response.data?.success && response.data?.data?.data) {
          const items = response.data.data.data; // 실제 데이터 배열
          console.log("✅ [RepeaterFieldGroup] 그룹 데이터 로드 완료:", {
            count: items.length,
            groupByColumn,
            groupKeyValue,
            firstItem: items[0],
          });
          setGroupedData(items);
          
          // 🆕 원본 데이터 ID 목록 저장 (삭제 추적용)
          const itemIds = items.map((item: any) => item.id).filter(Boolean);
          setOriginalItemIds(itemIds);
          console.log("📋 [RepeaterFieldGroup] 원본 데이터 ID 목록 저장:", itemIds);
          
          // onChange 호출하여 부모에게 알림
          if (onChange && items.length > 0) {
            const dataWithMeta = items.map((item: any) => ({
              ...item,
              _targetTable: targetTable,
              _originalItemIds: itemIds, // 🆕 원본 ID 목록도 함께 전달
            }));
            onChange(dataWithMeta);
          }
        } else {
          console.warn("⚠️ [RepeaterFieldGroup] 그룹 데이터 로드 실패:", response.data);
          setGroupedData([]);
        }
      } catch (error) {
        console.error("❌ [RepeaterFieldGroup] 그룹 데이터 로드 오류:", error);
        setGroupedData([]);
      } finally {
        setIsLoadingGroupData(false);
      }
    };
    
    loadGroupedData();
  }, [isEditMode, groupByColumn, groupKeyValue, targetTable, onChange]);

  // 값이 JSON 문자열인 경우 파싱
  let parsedValue: any[] = [];
  
  // 🆕 그룹화된 데이터가 있으면 우선 사용
  if (groupedData !== null && groupedData.length > 0) {
    parsedValue = groupedData;
  } else if (isEditMode && hasRepeaterFieldsInFormData && !groupByColumn) {
    // 그룹화 설정이 없는 경우에만 단일 행 사용
    console.log("📝 [RepeaterFieldGroup] 수정 모드 - formData를 초기 데이터로 사용", {
      formDataId: formData?.id,
      matchingFieldsCount: matchingFields.length,
    });
    parsedValue = [{ ...formData }];
  } else if (typeof rawValue === "string" && rawValue.trim() !== "") {
    // 빈 문자열이 아닌 경우에만 JSON 파싱 시도
    try {
      parsedValue = JSON.parse(rawValue);
    } catch {
      parsedValue = [];
    }
  } else if (Array.isArray(rawValue)) {
    parsedValue = rawValue;
  }

  // parsedValue를 ref로 관리하여 최신 값 유지
  const parsedValueRef = useRef(parsedValue);
  parsedValueRef.current = parsedValue;

  // onChange를 ref로 관리
  const onChangeRef = useRef(onChange);
  onChangeRef.current = onChange;

  // onFormDataChange를 ref로 관리
  const onFormDataChangeRef = useRef(onFormDataChange);
  onFormDataChangeRef.current = onFormDataChange;

  // fieldName을 ref로 관리
  const fieldNameRef = useRef(fieldName);
  fieldNameRef.current = fieldName;

  // config를 ref로 관리
  const configRef = useRef(config);
  configRef.current = config;

  // 데이터 수신 핸들러
  const handleReceiveData = useCallback((data: any[], mappingRulesOrMode?: any[] | string) => {
    console.log("📥 [RepeaterFieldGroup] 데이터 수신:", { data, mappingRulesOrMode });
    
    if (!data || data.length === 0) {
      toast.warning("전달할 데이터가 없습니다");
      return;
    }

    // 매핑 규칙이 배열인 경우에만 적용
    let processedData = data;
    if (Array.isArray(mappingRulesOrMode) && mappingRulesOrMode.length > 0) {
      processedData = applyMappingRules(data, mappingRulesOrMode);
    }

    // 데이터 정규화: 각 항목에서 실제 데이터 추출
    // 데이터가 {0: {...}, inbound_type: "..."} 형태인 경우 처리
    const normalizedData = processedData.map((item: any) => {
      // item이 {0: {...실제데이터...}, 추가필드: 값} 형태인 경우
      if (item && typeof item === "object" && item[0] && typeof item[0] === "object") {
        // 0번 인덱스의 데이터와 나머지 필드를 병합
        const { 0: originalData, ...additionalFields } = item;
        return { ...originalData, ...additionalFields };
      }
      return item;
    });

    // 🆕 정의된 필드만 필터링 (불필요한 필드 제거)
    // 반복 필드 그룹에 정의된 필드 + 시스템 필드만 유지
    const definedFields = configRef.current.fields || [];
    const definedFieldNames = new Set(definedFields.map((f: any) => f.name));
    // 시스템 필드 및 필수 필드 추가
    const systemFields = new Set(['id', '_targetTable', 'created_date', 'updated_date', 'writer', 'company_code']);
    
    const filteredData = normalizedData.map((item: any) => {
      const filteredItem: Record<string, any> = {};
      Object.keys(item).forEach(key => {
        // 정의된 필드이거나 시스템 필드인 경우만 포함
        if (definedFieldNames.has(key) || systemFields.has(key)) {
          filteredItem[key] = item[key];
        }
      });
      return filteredItem;
    });

    console.log("📥 [RepeaterFieldGroup] 정규화된 데이터:", normalizedData);
    console.log("📥 [RepeaterFieldGroup] 필터링된 데이터:", filteredData);

    // 기존 데이터에 새 데이터 추가 (기본 모드: append)
    const currentValue = parsedValueRef.current;
    
    // mode가 "replace"인 경우 기존 데이터 대체, 그 외에는 추가
    // 🆕 필터링된 데이터 사용
    const mode = typeof mappingRulesOrMode === "string" ? mappingRulesOrMode : "append";
    const newItems = mode === "replace" ? filteredData : [...currentValue, ...filteredData];

    console.log("📥 [RepeaterFieldGroup] 최종 데이터:", { currentValue, newItems, mode });

    // JSON 문자열로 변환하여 저장
    const jsonValue = JSON.stringify(newItems);
    console.log("📥 [RepeaterFieldGroup] onChange/onFormDataChange 호출:", { 
      jsonValue, 
      hasOnChange: !!onChangeRef.current,
      hasOnFormDataChange: !!onFormDataChangeRef.current,
      fieldName: fieldNameRef.current,
    });
    
    // onFormDataChange가 있으면 우선 사용 (EmbeddedScreen의 formData 상태 업데이트)
    if (onFormDataChangeRef.current) {
      onFormDataChangeRef.current(fieldNameRef.current, jsonValue);
    }
    // 그렇지 않으면 onChange 사용
    else if (onChangeRef.current) {
      onChangeRef.current(jsonValue);
    }

    toast.success(`${filteredData.length}개 항목이 추가되었습니다`);
  }, []);

  // DataReceivable 인터페이스 구현
  const dataReceiver = useMemo<DataReceivable>(() => ({
    componentId: component.id,
    componentType: "repeater-field-group",
    receiveData: handleReceiveData,
  }), [component.id, handleReceiveData]);

  // ScreenContext에 데이터 수신자로 등록
  useEffect(() => {
    if (screenContext && component.id) {
      console.log("📋 [RepeaterFieldGroup] ScreenContext에 데이터 수신자 등록:", component.id);
      screenContext.registerDataReceiver(component.id, dataReceiver);
      
      return () => {
        screenContext.unregisterDataReceiver(component.id);
      };
    }
  }, [screenContext, component.id, dataReceiver]);

  // SplitPanelContext에 데이터 수신자로 등록 (분할 패널 내에서만)
  useEffect(() => {
    const splitPanelPosition = screenContext?.splitPanelPosition;
    
    if (splitPanelContext?.isInSplitPanel && splitPanelPosition && component.id) {
      console.log("🔗 [RepeaterFieldGroup] SplitPanelContext에 데이터 수신자 등록:", {
        componentId: component.id,
        position: splitPanelPosition,
      });
      
      splitPanelContext.registerReceiver(splitPanelPosition, component.id, dataReceiver);
      receiverRef.current = dataReceiver;
      
      return () => {
        console.log("🔗 [RepeaterFieldGroup] SplitPanelContext에서 데이터 수신자 해제:", component.id);
        splitPanelContext.unregisterReceiver(splitPanelPosition, component.id);
        receiverRef.current = null;
      };
    }
  }, [splitPanelContext, screenContext?.splitPanelPosition, component.id, dataReceiver]);

  return (
    <RepeaterInput
      value={parsedValue}
      onChange={(newValue) => {
        // 배열을 JSON 문자열로 변환하여 저장
        const jsonValue = JSON.stringify(newValue);
        onChange?.(jsonValue);
      }}
      config={config}
      disabled={disabled}
      readonly={readonly}
      menuObjid={menuObjid}
      className="w-full"
    />
  );
};

/**
 * Repeater Field Group 렌더러
 * 여러 필드를 가진 항목들을 동적으로 추가/제거할 수 있는 컴포넌트
 */
export class RepeaterFieldGroupRenderer extends AutoRegisteringComponentRenderer {
  /**
   * 컴포넌트 정의
   */
  static componentDefinition: ComponentDefinition = {
    id: "repeater-field-group",
    name: "반복 필드 그룹",
    nameEng: "Repeater Field Group",
    description: "여러 필드를 가진 항목들을 동적으로 추가/제거할 수 있는 반복 가능한 필드 그룹",
    category: ComponentCategory.INPUT,
    webType: "array", // 배열 데이터를 다룸
    icon: Layers,
    component: RepeaterFieldGroupRenderer,
    configPanel: RepeaterConfigPanel,
    defaultSize: {
      width: 600,
      height: 200, // 기본 높이 조정
    },
    defaultConfig: {
      fields: [], // 빈 배열로 시작 - 사용자가 직접 필드 추가
      minItems: 1, // 기본 1개 항목
      maxItems: 20,
      addButtonText: "항목 추가",
      allowReorder: true,
      showIndex: true,
      collapsible: false,
      layout: "grid",
      showDivider: true,
      emptyMessage: "필드를 먼저 정의하세요.",
    },
    tags: ["repeater", "fieldgroup", "dynamic", "multi", "form", "array", "fields"],
    author: "System",
    version: "1.0.0",
  };

  /**
   * 컴포넌트 렌더링
   */
  render(): React.ReactElement {
    return <RepeaterFieldGroupComponent {...this.props} />;
  }
}

// 컴포넌트 자동 등록
RepeaterFieldGroupRenderer.registerSelf();

// Hot Reload 지원 (개발 모드)
if (process.env.NODE_ENV === "development") {
  RepeaterFieldGroupRenderer.enableHotReload();
}
