"use client";

import React, { useState, useEffect, useMemo, useCallback } from "react";
import { ComponentRendererProps } from "@/types/component";
import { RepeatContainerConfig, RepeatItemContext, SlotComponentConfig } from "./types";
import { Repeat, Package, ChevronLeft, ChevronRight, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import DynamicComponentRenderer from "@/lib/registry/DynamicComponentRenderer";

// V2 이벤트 시스템
import { V2_EVENTS, subscribeV2Event, type TableListDataChangeDetail, type RepeaterDataChangeDetail } from "@/types/component-events";

interface RepeatContainerComponentProps extends ComponentRendererProps {
  config?: RepeatContainerConfig;
  // 외부에서 데이터를 직접 전달받을 수 있음
  externalData?: any[];
  // 내부 컴포넌트를 렌더링하는 슬롯 (children 대용)
  renderItem?: (context: RepeatItemContext) => React.ReactNode;
  // formData 접근
  formData?: Record<string, any>;
  // formData 변경 콜백
  onFormDataChange?: (key: string, value: any) => void;
  // 선택 변경 콜백
  onSelectionChange?: (selectedData: any[]) => void;
  // 사용자 정보
  userId?: string;
  userName?: string;
  companyCode?: string;
  // 화면 정보
  screenId?: number;
  screenTableName?: string;
  // 컴포넌트 업데이트 콜백 (디자인 모드에서 드래그앤드롭용)
  onUpdateComponent?: (updates: Partial<RepeatContainerConfig>) => void;
}

/**
 * 리피터 컨테이너 컴포넌트
 * 데이터 수만큼 내부 컨텐츠를 반복 렌더링하는 컨테이너
 */
export function RepeatContainerComponent({
  component,
  isDesignMode = false,
  config: propsConfig,
  externalData,
  renderItem,
  formData = {},
  onFormDataChange,
  onSelectionChange,
  userId,
  userName,
  companyCode,
  screenId,
  screenTableName,
  onUpdateComponent,
}: RepeatContainerComponentProps) {
  const componentConfig: RepeatContainerConfig = {
    dataSourceType: "manual",
    layout: "vertical",
    gridColumns: 2,
    gap: "16px",
    showBorder: true,
    showShadow: false,
    borderRadius: "8px",
    backgroundColor: "#ffffff",
    padding: "16px",
    showItemTitle: false,
    itemTitleTemplate: "",
    titleColumn: "",
    descriptionColumn: "",
    titleFontSize: "14px",
    titleColor: "#374151",
    titleFontWeight: "600",
    descriptionFontSize: "12px",
    descriptionColor: "#6b7280",
    emptyMessage: "데이터가 없습니다",
    usePaging: false,
    pageSize: 10,
    clickable: false,
    showSelectedState: true,
    selectionMode: "single",
    ...propsConfig,
    ...component?.config,
    ...component?.componentConfig,
  };

  const {
    dataSourceType,
    dataSourceComponentId,
    tableName,
    customTableName,
    useCustomTable,
    layout,
    gridColumns,
    gap,
    itemMinWidth,
    itemMaxWidth,
    itemHeight,
    showBorder,
    showShadow,
    borderRadius,
    backgroundColor,
    padding,
    showItemTitle,
    itemTitleTemplate,
    titleColumn,
    descriptionColumn,
    titleFontSize,
    titleColor,
    titleFontWeight,
    descriptionFontSize,
    descriptionColor,
    filterField,
    filterColumn,
    useGrouping,
    groupByField,
    children: slotChildren,
    emptyMessage,
    usePaging,
    pageSize,
    clickable,
    showSelectedState,
    selectionMode,
  } = componentConfig;

  // 데이터 상태
  const [data, setData] = useState<any[]>([]);
  const [selectedIndices, setSelectedIndices] = useState<number[]>([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);

  // 실제 사용할 테이블명
  const effectiveTableName = useCustomTable ? customTableName : tableName;

  // 외부 데이터가 있으면 사용
  useEffect(() => {
    if (externalData && Array.isArray(externalData)) {
      setData(externalData);
    }
  }, [externalData]);

  // ============================================================
  // 컴포넌트 데이터 변경 이벤트 리스닝 (V2 표준 이벤트)
  // componentId 또는 tableName으로 매칭
  // ============================================================
  useEffect(() => {
    if (isDesignMode) return;

    console.log("🔄 리피터 컨테이너 이벤트 리스너 등록:", {
      componentId: component?.id,
      dataSourceType,
      dataSourceComponentId,
      effectiveTableName,
    });

    // 공통 데이터 처리 함수
    const processIncomingData = (
      componentId: string | undefined,
      eventTableName: string | undefined,
      eventData: any[]
    ) => {
      // 1. 명시적으로 dataSourceComponentId가 설정된 경우 해당 컴포넌트만 매칭
      if (dataSourceComponentId) {
        if (componentId === dataSourceComponentId && Array.isArray(eventData)) {
          console.log("✅ 리피터: 컴포넌트 ID로 데이터 수신 성공", { componentId, count: eventData.length });
          setData(eventData);
          setCurrentPage(1);
          setSelectedIndices([]);
        }
        return;
      }

      // 2. dataSourceComponentId가 없으면 테이블명으로 매칭
      if (effectiveTableName && eventTableName === effectiveTableName && Array.isArray(eventData)) {
        console.log("✅ 리피터: 테이블명으로 데이터 수신 성공", { tableName: eventTableName, count: eventData.length });
        setData(eventData);
        setCurrentPage(1);
        setSelectedIndices([]);
      }
    };

    // 테이블 리스트 데이터 변경 이벤트 (V2 표준)
    const handleTableListDataChange = (event: CustomEvent<TableListDataChangeDetail>) => {
      const { componentId, tableName: eventTableName, data: eventData } = event.detail || {};
      processIncomingData(componentId, eventTableName, eventData);
    };

    // 리피터 데이터 변경 이벤트 (V2 표준)
    const handleRepeaterDataChange = (event: CustomEvent<RepeaterDataChangeDetail>) => {
      const { componentId, tableName: eventTableName, data: eventData } = event.detail || {};
      processIncomingData(componentId, eventTableName, eventData);
    };

    // V2 표준 이벤트 구독
    const unsubscribeTableList = subscribeV2Event(V2_EVENTS.TABLE_LIST_DATA_CHANGE, handleTableListDataChange);
    const unsubscribeRepeater = subscribeV2Event(V2_EVENTS.REPEATER_DATA_CHANGE, handleRepeaterDataChange);

    return () => {
      unsubscribeTableList();
      unsubscribeRepeater();
    };
  }, [component?.id, dataSourceType, dataSourceComponentId, effectiveTableName, isDesignMode]);

  // 필터링된 데이터
  const filteredData = useMemo(() => {
    if (!filterField || !filterColumn) return data;

    const filterValue = formData[filterField];
    if (filterValue === undefined || filterValue === null) return data;

    if (Array.isArray(filterValue)) {
      return data.filter((row) => filterValue.includes(row[filterColumn]));
    }

    return data.filter((row) => row[filterColumn] === filterValue);
  }, [data, filterField, filterColumn, formData]);

  // 그룹핑된 데이터
  const groupedData = useMemo(() => {
    if (!useGrouping || !groupByField) return null;

    const groups: Record<string, any[]> = {};
    filteredData.forEach((row) => {
      const key = String(row[groupByField] ?? "기타");
      if (!groups[key]) {
        groups[key] = [];
      }
      groups[key].push(row);
    });

    return groups;
  }, [filteredData, useGrouping, groupByField]);

  // 페이징된 데이터
  const paginatedData = useMemo(() => {
    if (!usePaging || !pageSize) return filteredData;

    const startIndex = (currentPage - 1) * pageSize;
    return filteredData.slice(startIndex, startIndex + pageSize);
  }, [filteredData, usePaging, pageSize, currentPage]);

  // 총 페이지 수
  const totalPages = useMemo(() => {
    if (!usePaging || !pageSize || filteredData.length === 0) return 1;
    return Math.ceil(filteredData.length / pageSize);
  }, [filteredData.length, usePaging, pageSize]);

  // 아이템 제목 생성 (titleColumn 우선, 없으면 itemTitleTemplate 사용)
  const generateTitle = useCallback(
    (rowData: Record<string, any>, index: number): string => {
      if (!showItemTitle) return "";

      // titleColumn이 설정된 경우 해당 컬럼 값 사용
      if (titleColumn) {
        return String(rowData[titleColumn] ?? "");
      }

      // 레거시: itemTitleTemplate 사용
      if (itemTitleTemplate) {
        return itemTitleTemplate.replace(/\{([^}]+)\}/g, (match, field) => {
          return String(rowData[field] ?? "");
        });
      }

      return `아이템 ${index + 1}`;
    },
    [showItemTitle, titleColumn, itemTitleTemplate]
  );

  // 아이템 설명 생성
  const generateDescription = useCallback(
    (rowData: Record<string, any>): string => {
      if (!showItemTitle || !descriptionColumn) return "";
      return String(rowData[descriptionColumn] ?? "");
    },
    [showItemTitle, descriptionColumn]
  );

  // 아이템 클릭 핸들러
  const handleItemClick = useCallback(
    (index: number, rowData: any) => {
      if (!clickable) return;

      let newSelectedIndices: number[];

      if (selectionMode === "multiple") {
        if (selectedIndices.includes(index)) {
          newSelectedIndices = selectedIndices.filter((i) => i !== index);
        } else {
          newSelectedIndices = [...selectedIndices, index];
        }
      } else {
        newSelectedIndices = selectedIndices.includes(index) ? [] : [index];
      }

      setSelectedIndices(newSelectedIndices);

      if (onSelectionChange) {
        const selectedData = newSelectedIndices.map((i) => paginatedData[i]);
        onSelectionChange(selectedData);
      }
    },
    [clickable, selectionMode, selectedIndices, paginatedData, onSelectionChange]
  );

  // 레이아웃 스타일 계산
  const layoutStyle = useMemo(() => {
    const baseStyle: React.CSSProperties = {
      gap: gap || "16px",
    };

    switch (layout) {
      case "horizontal":
        return {
          ...baseStyle,
          display: "flex",
          flexDirection: "row" as const,
          flexWrap: "wrap" as const,
        };
      case "grid":
        return {
          ...baseStyle,
          display: "grid",
          gridTemplateColumns: `repeat(${gridColumns || 2}, 1fr)`,
        };
      case "vertical":
      default:
        return {
          ...baseStyle,
          display: "flex",
          flexDirection: "column" as const,
        };
    }
  }, [layout, gap, gridColumns]);

  // 아이템 스타일 계산
  const itemStyle = useMemo((): React.CSSProperties => {
    return {
      minWidth: itemMinWidth,
      maxWidth: itemMaxWidth,
      // height 대신 minHeight 사용 - 내부 컨텐츠가 커지면 자동으로 높이 확장
      minHeight: itemHeight || "auto",
      height: "auto", // 고정 높이 대신 auto로 변경
      backgroundColor: backgroundColor || "#ffffff",
      borderRadius: borderRadius || "8px",
      padding: padding || "16px",
      border: showBorder ? "1px solid #e5e7eb" : "none",
      boxShadow: showShadow ? "0 1px 3px rgba(0,0,0,0.1)" : "none",
      overflow: "visible", // 내부 컨텐츠가 튀어나가지 않도록
    };
  }, [itemMinWidth, itemMaxWidth, itemHeight, backgroundColor, borderRadius, padding, showBorder, showShadow]);

  // 슬롯 자식 컴포넌트들을 렌더링
  const renderSlotChildren = useCallback(
    (context: RepeatItemContext) => {
      // renderItem prop이 있으면 우선 사용
      if (renderItem) {
        return renderItem(context);
      }

      // 슬롯에 배치된 자식 컴포넌트가 없으면 기본 메시지
      if (!slotChildren || slotChildren.length === 0) {
        return (
          <div className="text-sm text-muted-foreground">
            반복 아이템 #{context.index + 1}
          </div>
        );
      }

      // 현재 아이템 데이터를 formData로 전달
      const itemFormData = {
        ...formData,
        ...context.data,
        _repeatIndex: context.index,
        _repeatTotal: context.totalCount,
        _isFirst: context.isFirst,
        _isLast: context.isLast,
      };

      // 슬롯에 배치된 컴포넌트들을 렌더링 (Flow 레이아웃으로 변경)
      return (
        <div className="flex flex-col gap-3">
          {slotChildren.map((childComp: SlotComponentConfig) => {
            const { size = { width: "100%", height: "auto" } } = childComp;

            // DynamicComponentRenderer가 기대하는 형식으로 변환
            const componentData = {
              id: `${childComp.id}_${context.index}`,
              componentType: childComp.componentType,
              label: childComp.label,
              columnName: childComp.fieldName,
              position: { x: 0, y: 0, z: 1 },
              size: {
                width: typeof size.width === "number" ? size.width : undefined,
                height: typeof size.height === "number" ? size.height : undefined,
              },
              componentConfig: childComp.componentConfig,
              style: childComp.style,
            };

            return (
              <div
                key={componentData.id}
                className="w-full"
                style={{
                  // 너비는 100%로, 높이는 자동으로
                  minHeight: typeof size.height === "number" ? size.height : "auto",
                }}
              >
                <DynamicComponentRenderer
                  component={componentData}
                  isInteractive={true}
                  screenId={screenId}
                  tableName={screenTableName || effectiveTableName}
                  userId={userId}
                  userName={userName}
                  companyCode={companyCode}
                  formData={itemFormData}
                  onFormDataChange={(key, value) => {
                    if (onFormDataChange) {
                      onFormDataChange(`_repeat_${context.index}_${key}`, value);
                    }
                  }}
                />
              </div>
            );
          })}
        </div>
      );
    },
    [
      renderItem,
      slotChildren,
      formData,
      screenId,
      screenTableName,
      effectiveTableName,
      userId,
      userName,
      companyCode,
      onFormDataChange,
    ]
  );

  // 드래그앤드롭 상태 (시각적 피드백용)
  const [isDragOver, setIsDragOver] = useState(false);

  // 드래그 오버 핸들러 (시각적 피드백만)
  // 중요: preventDefault()를 호출해야 드롭 가능 영역으로 인식됨
  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragOver(true);
  }, []);

  // 드래그 리브 핸들러
  const handleDragLeave = useCallback((e: React.DragEvent) => {
    // 자식 요소로 이동할 때 false가 되지 않도록 체크
    const relatedTarget = e.relatedTarget as HTMLElement;
    if (relatedTarget && (e.currentTarget as HTMLElement).contains(relatedTarget)) {
      return;
    }
    setIsDragOver(false);
  }, []);

  // 디자인 모드 미리보기
  if (isDesignMode) {
    const previewData = [
      { id: 1, name: "아이템 1", value: 100 },
      { id: 2, name: "아이템 2", value: 200 },
      { id: 3, name: "아이템 3", value: 300 },
    ];

    const hasChildren = slotChildren && slotChildren.length > 0;

    return (
      <div
        data-repeat-container="true"
        data-component-id={component?.id}
        className={cn(
          "rounded-md border border-dashed p-3 transition-colors",
          isDragOver
            ? "border-green-500 bg-green-50/70"
            : "border-blue-300 bg-blue-50/50"
        )}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={(e) => {
          // 시각적 상태만 리셋, 드롭 로직은 ScreenDesigner에서 처리
          setIsDragOver(false);
          // 중요: preventDefault()를 호출하지 않아야 이벤트가 버블링됨
          // 하지만 필요하다면 호출해도 됨 - 버블링과 무관
        }}
      >
        <div className="mb-3 flex items-center justify-between">
          <div className="flex items-center gap-2 text-sm text-blue-700">
            <Repeat className="h-4 w-4" />
            <span className="font-medium">리피터 컨테이너</span>
            <span className="text-blue-500">({previewData.length}개 미리보기)</span>
          </div>
          {isDragOver ? (
            <div className="flex items-center gap-1 rounded bg-green-100 px-2 py-1 text-xs text-green-700">
              <Plus className="h-3 w-3" />
              여기에 놓으세요
            </div>
          ) : !hasChildren ? (
            <div className="flex items-center gap-1 rounded bg-amber-100 px-2 py-1 text-xs text-amber-700">
              <Plus className="h-3 w-3" />
              컴포넌트를 드래그하세요
            </div>
          ) : null}
        </div>

        <div style={layoutStyle}>
          {previewData.map((row, index) => {
            const context: RepeatItemContext = {
              index,
              data: row,
              totalCount: previewData.length,
              isFirst: index === 0,
              isLast: index === previewData.length - 1,
            };

            return (
              <div
                key={row.id || index}
                style={itemStyle}
                className={cn(
                  "relative transition-all",
                  clickable && "cursor-pointer hover:shadow-md",
                  showSelectedState &&
                    selectedIndices.includes(index) &&
                    "ring-2 ring-blue-500"
                )}
              >
                {showItemTitle && (titleColumn || itemTitleTemplate) && (
                  <div className="mb-2 border-b pb-2">
                    <div
                      className="font-medium"
                      style={{
                        fontSize: titleFontSize,
                        color: titleColor,
                        fontWeight: titleFontWeight,
                      }}
                    >
                      {generateTitle(row, index)}
                    </div>
                    {descriptionColumn && generateDescription(row) && (
                      <div
                        className="mt-1"
                        style={{
                          fontSize: descriptionFontSize,
                          color: descriptionColor,
                        }}
                      >
                        {generateDescription(row)}
                      </div>
                    )}
                  </div>
                )}

                {hasChildren ? (
                  <div className="space-y-2">
                    {/* 디자인 모드: 배치된 자식 컴포넌트들을 시각적으로 표시 */}
                    {slotChildren!.map((child: SlotComponentConfig, childIdx: number) => (
                      <div
                        key={child.id}
                        className="flex items-center gap-2 rounded border border-dashed border-green-300 bg-green-50/50 px-2 py-1.5"
                      >
                        <div className="flex h-5 w-5 items-center justify-center rounded bg-green-100 text-xs font-medium text-green-700">
                          {childIdx + 1}
                        </div>
                        <div className="min-w-0 flex-1">
                          <div className="truncate text-xs font-medium text-green-700">
                            {child.label || child.componentType}
                          </div>
                          {child.fieldName && (
                            <div className="truncate text-[10px] text-green-500">
                              {child.fieldName}
                            </div>
                          )}
                        </div>
                        <div className="text-[10px] text-green-400">
                          {child.componentType}
                        </div>
                      </div>
                    ))}
                    <div className="text-center text-[10px] text-slate-400">
                      아이템 #{index + 1} - 실행 시 데이터 바인딩
                    </div>
                  </div>
                ) : (
                  <div className="text-sm text-muted-foreground">
                    <div className="text-xs text-slate-500">
                      반복 아이템 #{index + 1}
                    </div>
                    <div className="mt-1 text-slate-400">
                      컴포넌트를 드래그하여 배치하세요
                    </div>
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // 빈 상태
  if (paginatedData.length === 0 && !isLoading) {
    return (
      <div className="flex flex-col items-center justify-center rounded-md border border-dashed bg-slate-50 py-8 text-center">
        <Package className="mb-2 h-8 w-8 text-slate-400" />
        <p className="text-sm text-muted-foreground">{emptyMessage}</p>
      </div>
    );
  }

  // 로딩 상태
  if (isLoading) {
    return (
      <div className="flex items-center justify-center rounded-md border bg-slate-50 py-8">
        <div className="h-6 w-6 animate-spin rounded-full border-2 border-blue-500 border-t-transparent" />
        <span className="ml-2 text-sm text-muted-foreground">로딩 중...</span>
      </div>
    );
  }

  // 실제 렌더링
  return (
    <div className="repeat-container">
      <div style={layoutStyle}>
        {paginatedData.map((row, index) => {
          const context: RepeatItemContext = {
            index,
            data: row,
            totalCount: filteredData.length,
            isFirst: index === 0,
            isLast: index === paginatedData.length - 1,
          };

          return (
            <div
              key={row.id || row._id || index}
              style={itemStyle}
              className={cn(
                "repeat-container-item relative transition-all",
                clickable && "cursor-pointer hover:shadow-md",
                showSelectedState &&
                  selectedIndices.includes(index) &&
                  "ring-2 ring-blue-500"
              )}
              onClick={() => handleItemClick(index, row)}
            >
              {showItemTitle && (titleColumn || itemTitleTemplate) && (
                <div className="mb-2 border-b pb-2">
                  <div
                    className="font-medium"
                    style={{
                      fontSize: titleFontSize,
                      color: titleColor,
                      fontWeight: titleFontWeight,
                    }}
                  >
                    {generateTitle(row, index)}
                  </div>
                  {descriptionColumn && generateDescription(row) && (
                    <div
                      className="mt-1"
                      style={{
                        fontSize: descriptionFontSize,
                        color: descriptionColor,
                      }}
                    >
                      {generateDescription(row)}
                    </div>
                  )}
                </div>
              )}

              {renderSlotChildren(context)}
            </div>
          );
        })}
      </div>

      {/* 페이징 */}
      {usePaging && totalPages > 1 && (
        <div className="mt-4 flex items-center justify-center gap-2">
          <Button
            variant="outline"
            size="sm"
            disabled={currentPage <= 1}
            onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
          >
            <ChevronLeft className="h-4 w-4" />
          </Button>

          <span className="px-3 text-sm text-muted-foreground">
            {currentPage} / {totalPages}
          </span>

          <Button
            variant="outline"
            size="sm"
            disabled={currentPage >= totalPages}
            onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
          >
            <ChevronRight className="h-4 w-4" />
          </Button>
        </div>
      )}
    </div>
  );
}

export const RepeatContainerWrapper = RepeatContainerComponent;
