"use client";

import React, { useState, useEffect, useMemo, useCallback, useRef } from "react";
import { ComponentRendererProps } from "@/types/component";
import {
  AggregationWidgetConfig,
  AggregationItem,
  AggregationResult,
  AggregationType,
  FilterCondition,
  DataSourceType,
} from "./types";
import { Calculator, TrendingUp, Hash, ArrowUp, ArrowDown, Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { useScreenMultiLang } from "@/contexts/ScreenMultiLangContext";
import { apiClient } from "@/lib/api/client";
import { v2EventBus, V2_EVENTS, V2ErrorBoundary } from "@/lib/v2-core";

interface AggregationWidgetComponentProps extends ComponentRendererProps {
  config?: AggregationWidgetConfig;
  // 외부에서 데이터를 직접 전달받을 수 있음
  externalData?: any[];
  // 폼 데이터 (필터 조건용)
  formData?: Record<string, any>;
  // 선택된 행 데이터
  selectedRows?: any[];
  // 선택된 행 전체 데이터 (표준 Props)
  selectedRowsData?: any[];
  // 멀티테넌시용 회사 코드
  companyCode?: string;
  // 새로고침 트리거 키
  refreshKey?: number;
  // 새로고침 콜백
  onRefresh?: () => void;
}

/**
 * 필터 조건을 적용하여 데이터 필터링
 */
function applyFilters(
  data: any[],
  filters: FilterCondition[],
  filterLogic: "AND" | "OR",
  formData: Record<string, any>,
  selectedRows: any[],
): any[] {
  if (!filters || filters.length === 0) {
    return data;
  }

  const enabledFilters = filters.filter((f) => f.enabled && f.columnName);

  if (enabledFilters.length === 0) {
    return data;
  }

  return data.filter((row) => {
    const results = enabledFilters.map((filter) => {
      const rowValue = row[filter.columnName];

      // 값 소스에 따라 비교 값 결정
      let compareValue: any;
      switch (filter.valueSourceType) {
        case "static":
          compareValue = filter.staticValue;
          break;
        case "formField":
          compareValue = formData?.[filter.formFieldName || ""];
          break;
        case "selection":
          // 선택된 행에서 값 가져오기 (첫 번째 선택 행 기준)
          compareValue = selectedRows?.[0]?.[filter.sourceColumnName || ""];
          break;
        case "urlParam":
          if (typeof window !== "undefined") {
            const urlParams = new URLSearchParams(window.location.search);
            compareValue = urlParams.get(filter.urlParamName || "");
          }
          break;
      }

      // 연산자에 따른 비교
      switch (filter.operator) {
        case "eq":
          return rowValue == compareValue;
        case "neq":
          return rowValue != compareValue;
        case "gt":
          return Number(rowValue) > Number(compareValue);
        case "gte":
          return Number(rowValue) >= Number(compareValue);
        case "lt":
          return Number(rowValue) < Number(compareValue);
        case "lte":
          return Number(rowValue) <= Number(compareValue);
        case "like":
          return String(rowValue || "")
            .toLowerCase()
            .includes(String(compareValue || "").toLowerCase());
        case "in":
          const inValues = String(compareValue || "")
            .split(",")
            .map((v) => v.trim());
          return inValues.includes(String(rowValue));
        case "isNull":
          return rowValue === null || rowValue === undefined || rowValue === "";
        case "isNotNull":
          return rowValue !== null && rowValue !== undefined && rowValue !== "";
        default:
          return true;
      }
    });

    // AND/OR 논리 적용
    return filterLogic === "AND" ? results.every((r) => r) : results.some((r) => r);
  });
}

/**
 * 집계 위젯 컴포넌트
 * 연결된 테이블 리스트나 리피터의 데이터를 집계하여 표시
 */
export function AggregationWidgetComponent({
  component,
  isDesignMode = false,
  config: propsConfig,
  externalData,
  formData = {},
  selectedRows = [],
  selectedRowsData = [],
  companyCode,
  refreshKey,
  onRefresh,
}: AggregationWidgetComponentProps) {
  // 다국어 지원
  const { getText } = useScreenMultiLang();

  // useMemo로 config 병합 (매 렌더링마다 새 객체 생성 방지)
  const componentConfig = useMemo<AggregationWidgetConfig>(
    () => ({
      dataSourceType: "table",
      items: [],
      layout: "horizontal",
      showLabels: true,
      showIcons: true,
      gap: "16px",
      ...propsConfig,
      ...component?.config,
    }),
    [propsConfig, component?.config],
  );

  // 다국어 라벨 가져오기
  const getItemLabel = (item: AggregationItem): string => {
    if (item.labelLangKey) {
      const translated = getText(item.labelLangKey);
      if (translated && translated !== item.labelLangKey) {
        return translated;
      }
    }
    return item.columnLabel || item.columnName || "컬럼";
  };

  const {
    dataSourceType,
    dataSourceComponentId,
    tableName,
    customTableName,
    useCustomTable,
    filters,
    filterLogic = "AND",
    items,
    layout,
    showLabels,
    showIcons,
    gap,
    backgroundColor,
    borderRadius,
    padding,
    fontSize,
    labelFontSize,
    valueFontSize,
    labelColor,
    valueColor,
    autoRefresh,
    refreshInterval,
    refreshOnFormChange,
  } = componentConfig;

  // 데이터 상태
  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 사용할 테이블명 결정
  const effectiveTableName = useCustomTable && customTableName ? customTableName : tableName;

  // Refs로 최신 값 참조 (의존성 배열에서 제외하여 무한 루프 방지)
  const filtersRef = React.useRef(filters);
  const formDataRef = React.useRef(formData);
  const selectedRowsRef = React.useRef(selectedRows);

  // 값이 변경될 때마다 ref 업데이트
  React.useEffect(() => {
    filtersRef.current = filters;
  }, [filters]);

  React.useEffect(() => {
    formDataRef.current = formData;
  }, [formData]);

  React.useEffect(() => {
    selectedRowsRef.current = selectedRows;
  }, [selectedRows]);

  // 테이블에서 데이터 조회 (dataSourceType === "table"일 때)
  const fetchTableData = useCallback(async () => {
    if (isDesignMode || !effectiveTableName || dataSourceType !== "table") {
      return;
    }

    try {
      setLoading(true);
      setError(null);

      // 테이블 데이터 조회 API 호출
      // 멀티테넌시: company_code 자동 필터링 활성화
      const response = await apiClient.post(`/table-management/tables/${effectiveTableName}/data`, {
        size: 10000, // 집계용이므로 충분한 데이터 조회
        page: 1,
        autoFilter: {
          enabled: true,
          filterColumn: "company_code",
          userField: "companyCode",
        },
      });

      // 응답 구조: { success: true, data: { data: [...], total: ... } }
      const raw = response.data?.data || response.data;
      const rows = raw?.data || raw || [];

      if (Array.isArray(rows)) {
        // 필터 적용
        const filteredData = applyFilters(
          rows,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    } catch (err: any) {
      console.error("집계 위젯 데이터 조회 오류:", err);
      setError(err.message || "데이터 조회 실패");
    } finally {
      setLoading(false);
    }
  }, [effectiveTableName, dataSourceType, isDesignMode, filterLogic]);

  // 테이블 데이터 조회 (초기 로드 + refreshKey 변경 시)
  useEffect(() => {
    if (dataSourceType === "table" && effectiveTableName && !isDesignMode) {
      fetchTableData();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dataSourceType, effectiveTableName, isDesignMode, refreshKey]);

  // 폼 데이터 변경 시 재조회 (refreshOnFormChange가 true일 때)
  const formDataKey = JSON.stringify(formData);
  useEffect(() => {
    if (dataSourceType === "table" && refreshOnFormChange && !isDesignMode && effectiveTableName) {
      // 초기 로드 후에만 재조회
      const timeoutId = setTimeout(() => {
        fetchTableData();
      }, 100);
      return () => clearTimeout(timeoutId);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [formDataKey, refreshOnFormChange]);

  // 자동 새로고침
  useEffect(() => {
    if (dataSourceType === "table" && autoRefresh && refreshInterval && !isDesignMode) {
      const interval = setInterval(fetchTableData, refreshInterval * 1000);
      return () => clearInterval(interval);
    }
  }, [dataSourceType, autoRefresh, refreshInterval, isDesignMode, fetchTableData]);

  // 선택된 행 집계 (dataSourceType === "selection"일 때)
  // props로 전달된 selectedRows 또는 selectedRowsData 사용
  // 길이 정보를 포함하여 전체 데이터 변경 감지 개선
  const selectedRowsKey = `${selectedRows?.length || 0}:${JSON.stringify(selectedRows?.slice(0, 5))}`;
  const selectedRowsDataKey = `${selectedRowsData?.length || 0}:${JSON.stringify(selectedRowsData?.slice(0, 5))}`;
  useEffect(() => {
    // selectedRowsData가 있으면 우선 사용 (표준 Props)
    const rowsToUse = selectedRowsData?.length > 0 ? selectedRowsData : selectedRows;
    if (dataSourceType === "selection") {
      if (Array.isArray(rowsToUse) && rowsToUse.length > 0) {
        const filteredData = applyFilters(
          rowsToUse,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      } else {
        // 선택 해제 시 빈 배열로 초기화
        setData([]);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dataSourceType, selectedRowsKey, selectedRowsDataKey, filterLogic]);

  // V2 이벤트 버스 구독 (selection 또는 component 타입일 때)
  useEffect(() => {
    if (isDesignMode) return;
    if (dataSourceType !== "selection" && dataSourceType !== "component") return;

    // 핸들러 함수 정의
    const handleV2TableDataChange = (payload: any) => {
      // component 타입: source가 dataSourceComponentId와 일치할 때만
      // selection 타입: 모든 테이블 데이터 변경 수신
      if (dataSourceType === "component" && payload.source !== dataSourceComponentId) {
        return;
      }

      if (Array.isArray(payload.data)) {
        const filteredData = applyFilters(
          payload.data,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    const handleV2TableSelectionChange = (payload: any) => {
      // component 타입: source가 dataSourceComponentId와 일치할 때만
      // selection 타입: 모든 선택 변경 수신
      if (dataSourceType === "component" && payload.source !== dataSourceComponentId) {
        return;
      }

      if (Array.isArray(payload.selectedRows)) {
        const filteredData = applyFilters(
          payload.selectedRows,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    const handleV2RepeaterDataChange = (payload: any) => {
      if (dataSourceType === "component" && payload.repeaterId !== dataSourceComponentId) {
        return;
      }

      if (Array.isArray(payload.data)) {
        const filteredData = applyFilters(
          payload.data,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // V2 이벤트 버스 구독
    const unsubscribeTableData = v2EventBus.subscribe(V2_EVENTS.TABLE_DATA_CHANGE, handleV2TableDataChange);
    const unsubscribeTableSelection = v2EventBus.subscribe(
      V2_EVENTS.TABLE_SELECTION_CHANGE,
      handleV2TableSelectionChange,
    );
    const unsubscribeRepeaterData = v2EventBus.subscribe(V2_EVENTS.REPEATER_DATA_CHANGE, handleV2RepeaterDataChange);

    return () => {
      unsubscribeTableData();
      unsubscribeTableSelection();
      unsubscribeRepeaterData();
    };
  }, [dataSourceType, dataSourceComponentId, isDesignMode, filterLogic]);

  // 전역 선택 이벤트 수신 - 레거시 지원 (dataSourceType === "selection"일 때)
  useEffect(() => {
    if (dataSourceType !== "selection" || isDesignMode) return;

    // 테이블리스트에서 발생하는 선택 이벤트 수신
    // tableListDataChange 이벤트의 data가 선택된 행들임
    const handleTableListDataChange = (event: CustomEvent) => {
      const { data: eventData, selectedRows: eventSelectedRows } = event.detail || {};
      // data가 선택된 행 데이터 배열
      const rows = eventData || [];

      if (Array.isArray(rows)) {
        // 필터 적용
        const filteredData = applyFilters(
          rows,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // 리피터에서 발생하는 이벤트
    const handleRepeaterDataChange = (event: CustomEvent) => {
      const { data: eventData, selectedData } = event.detail || {};
      const rows = selectedData || eventData || [];

      if (Array.isArray(rows)) {
        const filteredData = applyFilters(
          rows,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // 일반 선택 이벤트
    const handleSelectionChange = (event: CustomEvent) => {
      const { selectedRows: eventSelectedRows, selectedData, checkedRows, selectedItems } = event.detail || {};
      const rows = selectedData || eventSelectedRows || checkedRows || selectedItems || [];

      if (Array.isArray(rows)) {
        const filteredData = applyFilters(
          rows,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // 다양한 선택 이벤트 수신
    window.addEventListener("tableListDataChange" as any, handleTableListDataChange);
    window.addEventListener("repeaterDataChange" as any, handleRepeaterDataChange);
    window.addEventListener("selectionChange" as any, handleSelectionChange);
    window.addEventListener("tableSelectionChange" as any, handleSelectionChange);
    window.addEventListener("rowSelectionChange" as any, handleSelectionChange);
    window.addEventListener("checkboxSelectionChange" as any, handleSelectionChange);

    return () => {
      window.removeEventListener("tableListDataChange" as any, handleTableListDataChange);
      window.removeEventListener("repeaterDataChange" as any, handleRepeaterDataChange);
      window.removeEventListener("selectionChange" as any, handleSelectionChange);
      window.removeEventListener("tableSelectionChange" as any, handleSelectionChange);
      window.removeEventListener("rowSelectionChange" as any, handleSelectionChange);
      window.removeEventListener("checkboxSelectionChange" as any, handleSelectionChange);
    };
  }, [dataSourceType, isDesignMode, filterLogic]);

  // 외부 데이터가 있으면 사용
  // 길이 정보를 포함하여 전체 데이터 변경 감지 개선
  const externalDataKey = externalData ? `${externalData.length}:${JSON.stringify(externalData.slice(0, 5))}` : null;
  useEffect(() => {
    if (externalData && Array.isArray(externalData)) {
      // 필터 적용
      const filteredData = applyFilters(
        externalData,
        filtersRef.current || [],
        filterLogic,
        formDataRef.current,
        selectedRowsRef.current,
      );
      setData(filteredData);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [externalDataKey, filterLogic]);

  // 컴포넌트 데이터 변경 이벤트 리스닝 (dataSourceType === "component"일 때)
  useEffect(() => {
    if (dataSourceType !== "component" || !dataSourceComponentId || isDesignMode) return;

    const handleDataChange = (event: CustomEvent) => {
      const { componentId, data: eventData } = event.detail || {};
      if (componentId === dataSourceComponentId && Array.isArray(eventData)) {
        // 필터 적용
        const filteredData = applyFilters(
          eventData,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // 선택 변경 이벤트 (체크박스 선택 등)
    const handleSelectionChange = (event: CustomEvent) => {
      const { componentId, selectedData } = event.detail || {};
      if (componentId === dataSourceComponentId && Array.isArray(selectedData)) {
        // 선택된 데이터만 집계
        const filteredData = applyFilters(
          selectedData,
          filtersRef.current || [],
          filterLogic,
          formDataRef.current,
          selectedRowsRef.current,
        );
        setData(filteredData);
      }
    };

    // 리피터 데이터 변경 이벤트
    window.addEventListener("repeaterDataChange" as any, handleDataChange);
    // 테이블 리스트 데이터 변경 이벤트
    window.addEventListener("tableListDataChange" as any, handleDataChange);
    // 선택 변경 이벤트
    window.addEventListener("selectionChange" as any, handleSelectionChange);

    return () => {
      window.removeEventListener("repeaterDataChange" as any, handleDataChange);
      window.removeEventListener("tableListDataChange" as any, handleDataChange);
      window.removeEventListener("selectionChange" as any, handleSelectionChange);
    };
  }, [dataSourceType, dataSourceComponentId, isDesignMode, filterLogic]);

  // 집계 계산
  const aggregationResults = useMemo((): AggregationResult[] => {
    if (!items || items.length === 0) {
      return [];
    }

    return items.map((item) => {
      const values = data
        .map((row) => {
          const val = row[item.columnName];
          const parsed = typeof val === "number" ? val : parseFloat(val) || 0;
          return parsed;
        })
        .filter((v) => !isNaN(v));

      let value: number = 0;

      switch (item.type) {
        case "sum":
          value = values.reduce((acc, v) => acc + v, 0);
          break;
        case "avg":
          value = values.length > 0 ? values.reduce((acc, v) => acc + v, 0) / values.length : 0;
          break;
        case "count":
          value = data.length;
          break;
        case "max":
          value = values.length > 0 ? Math.max(...values) : 0;
          break;
        case "min":
          value = values.length > 0 ? Math.min(...values) : 0;
          break;
      }

      // 포맷팅
      let formattedValue = value.toFixed(item.decimalPlaces ?? 0);

      if (item.format === "currency") {
        formattedValue = new Intl.NumberFormat("ko-KR").format(value);
      } else if (item.format === "percent") {
        formattedValue = `${(value * 100).toFixed(item.decimalPlaces ?? 1)}%`;
      } else if (item.format === "number") {
        formattedValue = new Intl.NumberFormat("ko-KR").format(value);
      }

      if (item.prefix) {
        formattedValue = `${item.prefix}${formattedValue}`;
      }
      if (item.suffix) {
        formattedValue = `${formattedValue}${item.suffix}`;
      }

      return {
        id: item.id,
        label: getItemLabel(item),
        value,
        formattedValue,
        type: item.type,
      };
    });
  }, [data, items, getText]);

  // aggregationResults를 ref로 유지 (이벤트 핸들러에서 최신 값 참조)
  const aggregationResultsRef = useRef(aggregationResults);
  aggregationResultsRef.current = aggregationResults;

  // beforeFormSave 이벤트 리스너 (저장 시 집계 결과를 폼 데이터에 포함)
  useEffect(() => {
    if (isDesignMode) return;

    const handleBeforeFormSave = (event: CustomEvent) => {
      const componentKey = component?.id || "aggregation_data";
      if (event.detail) {
        // 집계 결과를 객체 형태로 저장
        const aggregationData: Record<string, any> = {};
        aggregationResultsRef.current.forEach((result) => {
          aggregationData[result.id] = {
            label: result.label,
            value: result.value,
            formattedValue: result.formattedValue,
            type: result.type,
          };
        });
        event.detail.formData[componentKey] = aggregationData;
      }
    };

    // V2 이벤트 버스 구독
    const unsubscribe = v2EventBus.subscribe(V2_EVENTS.FORM_SAVE_COLLECT, (payload) => {
      const componentKey = component?.id || "aggregation_data";
      const aggregationData: Record<string, any> = {};
      aggregationResultsRef.current.forEach((result) => {
        aggregationData[result.id] = {
          label: result.label,
          value: result.value,
          formattedValue: result.formattedValue,
          type: result.type,
        };
      });
      // V2 이벤트로 응답
      if (payload.formData) {
        payload.formData[componentKey] = aggregationData;
      }
    });

    // 레거시 이벤트도 지원
    window.addEventListener("beforeFormSave", handleBeforeFormSave as EventListener);

    return () => {
      unsubscribe();
      window.removeEventListener("beforeFormSave", handleBeforeFormSave as EventListener);
    };
  }, [isDesignMode, component?.id]);

  // 집계 타입에 따른 아이콘
  const getIcon = (type: AggregationType) => {
    switch (type) {
      case "sum":
        return <Calculator className="h-4 w-4" />;
      case "avg":
        return <TrendingUp className="h-4 w-4" />;
      case "count":
        return <Hash className="h-4 w-4" />;
      case "max":
        return <ArrowUp className="h-4 w-4" />;
      case "min":
        return <ArrowDown className="h-4 w-4" />;
    }
  };

  // 집계 타입 라벨
  const getTypeLabel = (type: AggregationType) => {
    switch (type) {
      case "sum":
        return "합계";
      case "avg":
        return "평균";
      case "count":
        return "개수";
      case "max":
        return "최대";
      case "min":
        return "최소";
    }
  };

  // 데이터 소스 타입 라벨
  const getDataSourceLabel = (type: DataSourceType) => {
    switch (type) {
      case "table":
        return "테이블";
      case "component":
        return "컴포넌트";
      case "selection":
        return "선택 데이터";
      default:
        return "수동";
    }
  };

  // 디자인 모드 미리보기
  if (isDesignMode) {
    const previewItems: AggregationResult[] =
      items.length > 0
        ? items.map((item) => ({
            id: item.id,
            label: getItemLabel(item),
            value: 0,
            formattedValue: item.prefix ? `${item.prefix}0${item.suffix || ""}` : `0${item.suffix || ""}`,
            type: item.type,
          }))
        : [
            { id: "1", label: "총 수량", value: 150, formattedValue: "150", type: "sum" },
            { id: "2", label: "총 금액", value: 1500000, formattedValue: "₩1,500,000", type: "sum" },
            { id: "3", label: "건수", value: 5, formattedValue: "5건", type: "count" },
          ];

    return (
      <div className="space-y-1">
        {/* 디자인 모드에서 데이터 소스 표시 */}
        <div className="text-muted-foreground flex items-center gap-2 text-[10px]">
          <span>[{getDataSourceLabel(dataSourceType)}]</span>
          {dataSourceType === "table" && effectiveTableName && <span>{effectiveTableName}</span>}
          {dataSourceType === "component" && dataSourceComponentId && <span>{dataSourceComponentId}</span>}
          {(filters || []).length > 0 && <span className="text-blue-500">필터 {filters?.length}개</span>}
        </div>
        <div
          className={cn(
            "flex items-center rounded-md border bg-slate-50 p-3",
            layout === "vertical" ? "flex-col items-stretch" : "flex-row flex-wrap",
          )}
          style={{
            gap: gap || "12px",
            backgroundColor: backgroundColor || undefined,
            borderRadius: borderRadius || undefined,
            padding: padding || undefined,
            fontSize: fontSize || undefined,
          }}
        >
          {previewItems.map((result, index) => (
            <div
              key={result.id || index}
              className={cn(
                "flex items-center gap-2 rounded-md border bg-white px-3 py-2 shadow-sm",
                layout === "vertical" ? "w-full justify-between" : "",
              )}
            >
              {showIcons && <span className="text-muted-foreground">{getIcon(result.type)}</span>}
              {showLabels && (
                <span className="text-muted-foreground text-xs" style={{ fontSize: labelFontSize, color: labelColor }}>
                  {result.label} ({getTypeLabel(result.type)}):
                </span>
              )}
              <span className="font-semibold" style={{ fontSize: valueFontSize, color: valueColor }}>
                {result.formattedValue}
              </span>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // 로딩 상태
  if (loading) {
    return (
      <div className="flex items-center justify-center rounded-md border bg-slate-50 p-4">
        <Loader2 className="text-muted-foreground h-5 w-5 animate-spin" />
        <span className="text-muted-foreground ml-2 text-sm">데이터 집계 중...</span>
      </div>
    );
  }

  // 에러 상태
  if (error) {
    return (
      <div className="border-destructive bg-destructive/10 text-destructive flex items-center justify-center rounded-md border p-4 text-sm">
        {error}
      </div>
    );
  }

  // 실제 렌더링
  if (aggregationResults.length === 0) {
    return (
      <div className="text-muted-foreground flex items-center justify-center rounded-md border border-dashed bg-slate-50 p-4 text-sm">
        집계 항목을 설정해주세요
      </div>
    );
  }

  return (
    <V2ErrorBoundary componentId={component?.id || "aggregation-widget"} componentType="v2-aggregation-widget">
      <div
        className={cn(
          "flex items-center rounded-md border bg-slate-50 p-3",
          layout === "vertical" ? "flex-col items-stretch" : "flex-row flex-wrap",
        )}
        style={{
          gap: gap || "12px",
          backgroundColor: backgroundColor || undefined,
          borderRadius: borderRadius || undefined,
          padding: padding || undefined,
          fontSize: fontSize || undefined,
        }}
      >
        {aggregationResults.map((result, index) => (
          <div
            key={result.id || index}
            className={cn(
              "flex items-center gap-2 rounded-md border bg-white px-3 py-2 shadow-sm",
              layout === "vertical" ? "w-full justify-between" : "",
            )}
          >
            {showIcons && <span className="text-muted-foreground">{getIcon(result.type)}</span>}
            {showLabels && (
              <span className="text-muted-foreground text-xs" style={{ fontSize: labelFontSize, color: labelColor }}>
                {result.label} ({getTypeLabel(result.type)}):
              </span>
            )}
            <span className="font-semibold" style={{ fontSize: valueFontSize, color: valueColor }}>
              {result.formattedValue}
            </span>
          </div>
        ))}
      </div>
    </V2ErrorBoundary>
  );
}

export const AggregationWidgetWrapper = AggregationWidgetComponent;
