"use client";

import React, { useEffect, useState, useRef } from "react";
import { DashboardElement, QueryResult, ChartData } from "../types";
import { Chart } from "./Chart";
import { transformQueryResultToChartData } from "../utils/chartDataTransform";
import { ExternalDbConnectionAPI } from "@/lib/api/externalDbConnection";
import { dashboardApi } from "@/lib/api/dashboard";
import { applyQueryFilters } from "../utils/queryHelpers";
import { getApiUrl } from "@/lib/utils/apiUrl";

interface ChartRendererProps {
  element: DashboardElement;
  data?: QueryResult;
  width?: number;
  height?: number;
}

/**
 * 차트 렌더러 컴포넌트 (D3 기반)
 * - 데이터 소스에서 데이터 페칭
 * - QueryResult를 ChartData로 변환
 * - D3 Chart 컴포넌트에 전달
 */
export function ChartRenderer({ element, data, width, height = 200 }: ChartRendererProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [containerWidth, setContainerWidth] = useState(width || 250);
  const [chartData, setChartData] = useState<ChartData | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // 컨테이너 너비 측정 (width가 undefined일 때)
  useEffect(() => {
    if (width !== undefined) {
      setContainerWidth(width);
      return;
    }

    const updateWidth = () => {
      if (containerRef.current) {
        const measuredWidth = containerRef.current.offsetWidth;
        console.log("📏 컨테이너 너비 측정:", measuredWidth);
        setContainerWidth(measuredWidth || 500); // 기본값 500
      }
    };

    // 약간의 지연을 두고 측정 (DOM 렌더링 완료 후)
    const timer = setTimeout(updateWidth, 100);
    updateWidth();

    window.addEventListener("resize", updateWidth);
    return () => {
      clearTimeout(timer);
      window.removeEventListener("resize", updateWidth);
    };
  }, [width]);

  // 데이터 페칭
  useEffect(() => {
    const fetchData = async () => {
      // 이미 data가 전달된 경우 사용
      if (data) {
        const transformed = transformQueryResultToChartData(data, element.chartConfig || {});
        setChartData(transformed);
        return;
      }

      // 데이터 소스가 설정되어 있으면 페칭
      if (element.dataSource && element.chartConfig) {
        setIsLoading(true);
        setError(null);

        try {
          let queryResult: QueryResult;

          // REST API vs Database 분기
          if (element.dataSource.type === "api" && element.dataSource.endpoint) {
            // REST API - 백엔드 프록시를 통한 호출 (CORS 우회)
            const params = new URLSearchParams();
            if (element.dataSource.queryParams) {
              Object.entries(element.dataSource.queryParams).forEach(([key, value]) => {
                if (key && value) {
                  params.append(key, String(value));
                }
              });
            }

            const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                url: element.dataSource.endpoint,
                method: "GET",
                headers: element.dataSource.headers || {},
                queryParams: Object.fromEntries(params),
              }),
            });

            if (!response.ok) {
              throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }

            const result = await response.json();

            if (!result.success) {
              throw new Error(result.message || "외부 API 호출 실패");
            }

            const apiData = result.data;

            // JSON Path 처리
            let processedData = apiData;
            if (element.dataSource.jsonPath) {
              const paths = element.dataSource.jsonPath.split(".");
              for (const path of paths) {
                if (processedData && typeof processedData === "object" && path in processedData) {
                  processedData = processedData[path];
                } else {
                  throw new Error(`JSON Path "${element.dataSource.jsonPath}"에서 데이터를 찾을 수 없습니다`);
                }
              }
            }

            const rows = Array.isArray(processedData) ? processedData : [processedData];
            const columns = rows.length > 0 ? Object.keys(rows[0]) : [];

            queryResult = {
              columns,
              rows,
              totalRows: rows.length,
              executionTime: 0,
            };
          } else if (element.dataSource.query) {
            // Database (현재 DB 또는 외부 DB)
            if (element.dataSource.connectionType === "external" && element.dataSource.externalConnectionId) {
              // 외부 DB - 필터 적용
              const filteredQuery = applyQueryFilters(element.dataSource.query, element.chartConfig);
              const result = await ExternalDbConnectionAPI.executeQuery(
                parseInt(element.dataSource.externalConnectionId),
                filteredQuery,
              );

              if (!result.success) {
                throw new Error(result.message || "외부 DB 쿼리 실행 실패");
              }

              queryResult = {
                columns: result.data?.[0] ? Object.keys(result.data[0]) : [],
                rows: result.data || [],
                totalRows: result.data?.length || 0,
                executionTime: 0,
              };
            } else {
              // 현재 DB - 필터 적용
              const filteredQuery = applyQueryFilters(element.dataSource.query, element.chartConfig);
              const result = await dashboardApi.executeQuery(filteredQuery);
              queryResult = {
                columns: result.columns,
                rows: result.rows,
                totalRows: result.rowCount,
                executionTime: 0,
              };
            }
          } else {
            throw new Error("데이터 소스가 올바르게 설정되지 않았습니다");
          }

          // ChartData로 변환
          const transformed = transformQueryResultToChartData(queryResult, element.chartConfig);
          setChartData(transformed);
        } catch (err) {
          const errorMessage = err instanceof Error ? err.message : "데이터 로딩 실패";
          setError(errorMessage);
        } finally {
          setIsLoading(false);
        }
      }
    };

    fetchData();

    // 자동 새로고침 설정 (0이면 수동이므로 interval 설정 안 함)
    const refreshInterval = element.dataSource?.refreshInterval;
    if (refreshInterval && refreshInterval > 0) {
      const interval = setInterval(fetchData, refreshInterval);
      return () => clearInterval(interval);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    element.dataSource?.query,
    element.dataSource?.connectionType,
    element.dataSource?.externalConnectionId,
    element.dataSource?.refreshInterval,
    element.dataSource?.type,
    element.dataSource?.endpoint,
    element.dataSource?.jsonPath,
    element.chartConfig,
    data,
  ]);

  // 로딩 중
  if (isLoading) {
    return (
      <div className="flex h-full w-full items-center justify-center text-muted-foreground">
        <div className="text-center">
          <div className="mx-auto mb-2 h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent" />
          <div className="text-sm">데이터 로딩 중...</div>
        </div>
      </div>
    );
  }

  // 에러
  if (error) {
    return (
      <div className="flex h-full w-full items-center justify-center text-destructive">
        <div className="text-center">
          <div className="mb-2 text-2xl">⚠️</div>
          <div className="text-sm font-medium">오류 발생</div>
          <div className="mt-1 text-xs">{error}</div>
        </div>
      </div>
    );
  }

  // 데이터나 설정이 없으면
  const isPieChart = element.subtype === "pie" || element.subtype === "donut";
  const isApiSource = element.dataSource?.type === "api";
  const needsYAxis = !(isPieChart || isApiSource) || (!element.chartConfig?.aggregation && !element.chartConfig?.yAxis);

  if (!chartData || !element.chartConfig?.xAxis || (needsYAxis && !element.chartConfig?.yAxis)) {
    return (
      <div className="flex h-full w-full items-center justify-center text-muted-foreground">
        <div className="text-center">
          <div className="text-sm">데이터를 설정해주세요</div>
        </div>
      </div>
    );
  }

  // D3 차트 렌더링
  const actualWidth = width !== undefined ? width : containerWidth;

  // 최소 크기 제약 완화 (1x1 위젯 지원)
  const isCircularChart = element.subtype === "pie" || element.subtype === "donut";
  const minWidth = 35; // 최소 너비 35px
  const finalWidth = Math.max(actualWidth - 4, minWidth);
  // 최소 높이도 35px로 설정
  const finalHeight = Math.max(height - (isCircularChart ? 10 : 4), 35);

  console.log("🎨 ChartRenderer:", {
    elementSubtype: element.subtype,
    propWidth: width,
    containerWidth,
    actualWidth,
    finalWidth,
    finalHeight,
    hasChartData: !!chartData,
    chartDataLabels: chartData?.labels,
    chartDataDatasets: chartData?.datasets?.length,
    isCircularChart,
  });

  return (
    <div ref={containerRef} className="flex h-full w-full items-center justify-center bg-background p-0.5">
      <div className="flex items-center justify-center">
        <Chart
          chartType={element.subtype}
          data={chartData}
          config={element.chartConfig}
          width={finalWidth}
          height={finalHeight}
        />
      </div>
    </div>
  );
}
