"use client";

import React, { useState, useEffect, useCallback } from "react";
import { DashboardElement, QueryResult } from "@/components/admin/dashboard/types";
import { ChartRenderer } from "@/components/admin/dashboard/charts/ChartRenderer";
import dynamic from "next/dynamic";

// 위젯 동적 import - 모든 위젯
const ListSummaryWidget = dynamic(() => import("./widgets/ListSummaryWidget"), { ssr: false });
const MapSummaryWidget = dynamic(() => import("./widgets/MapSummaryWidget"), { ssr: false });
const StatusSummaryWidget = dynamic(() => import("./widgets/StatusSummaryWidget"), { ssr: false });
const RiskAlertWidget = dynamic(() => import("./widgets/RiskAlertWidget"), { ssr: false });
const WeatherWidget = dynamic(() => import("./widgets/WeatherWidget"), { ssr: false });
const ExchangeWidget = dynamic(() => import("./widgets/ExchangeWidget"), { ssr: false });
const VehicleStatusWidget = dynamic(() => import("./widgets/VehicleStatusWidget"), { ssr: false });
const VehicleListWidget = dynamic(() => import("./widgets/VehicleListWidget"), { ssr: false });
const VehicleMapOnlyWidget = dynamic(() => import("./widgets/VehicleMapOnlyWidget"), { ssr: false });
const CargoListWidget = dynamic(() => import("./widgets/CargoListWidget"), { ssr: false });
const CustomerIssuesWidget = dynamic(() => import("./widgets/CustomerIssuesWidget"), { ssr: false });
const DeliveryStatusWidget = dynamic(() => import("./widgets/DeliveryStatusWidget"), { ssr: false });
const DeliveryStatusSummaryWidget = dynamic(() => import("./widgets/DeliveryStatusSummaryWidget"), { ssr: false });
const DeliveryTodayStatsWidget = dynamic(() => import("./widgets/DeliveryTodayStatsWidget"), { ssr: false });
const TodoWidget = dynamic(() => import("./widgets/TodoWidget"), { ssr: false });
const DocumentWidget = dynamic(() => import("./widgets/DocumentWidget"), { ssr: false });
const BookingAlertWidget = dynamic(() => import("./widgets/BookingAlertWidget"), { ssr: false });
const MaintenanceWidget = dynamic(() => import("./widgets/MaintenanceWidget"), { ssr: false });
const CalculatorWidget = dynamic(() => import("./widgets/CalculatorWidget"), { ssr: false });
const CalendarWidget = dynamic(() => import("@/components/admin/dashboard/widgets/CalendarWidget").then(mod => ({ default: mod.CalendarWidget })), { ssr: false });

/**
 * 위젯 렌더링 함수 - DashboardSidebar의 모든 subtype 처리
 * ViewerElement에서 사용하기 위해 컴포넌트 외부에 정의
 */
function renderWidget(element: DashboardElement) {
  switch (element.subtype) {
    // 차트는 ChartRenderer에서 처리됨 (이 함수 호출 안됨)
    
    // === 위젯 종류 ===
    case "exchange":
      return <ExchangeWidget />;
    case "weather":
      return <WeatherWidget />;
    case "calculator":
      return <CalculatorWidget />;
    case "clock":
      return (
        <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-blue-400 to-purple-600 p-4 text-white">
          <div className="text-center">
            <div className="mb-2 text-3xl">⏰</div>
            <div className="text-sm">시계 위젯 (개발 예정)</div>
          </div>
        </div>
      );
    case "map-summary":
      return <MapSummaryWidget element={element} />;
    case "list-summary":
      return <ListSummaryWidget element={element} />;
    case "risk-alert":
      return <RiskAlertWidget />;
    case "calendar":
      return <CalendarWidget element={element} />;
    case "status-summary":
      return <StatusSummaryWidget element={element} />;
    
    // === 운영/작업 지원 ===
    case "todo":
      return <TodoWidget />;
    case "booking-alert":
      return <BookingAlertWidget />;
    case "maintenance":
      return <MaintenanceWidget />;
    case "document":
      return <DocumentWidget />;
    case "list":
      return <ListSummaryWidget element={element} />;
    
    // === 차량 관련 (추가 위젯) ===
    case "vehicle-status":
      return <VehicleStatusWidget />;
    case "vehicle-list":
      return <VehicleListWidget />;
    case "vehicle-map":
      return <VehicleMapOnlyWidget element={element} />;
    
    // === 배송 관련 (추가 위젯) ===
    case "delivery-status":
      return <DeliveryStatusWidget />;
    case "delivery-status-summary":
      return <DeliveryStatusSummaryWidget />;
    case "delivery-today-stats":
      return <DeliveryTodayStatsWidget />;
    case "cargo-list":
      return <CargoListWidget />;
    case "customer-issues":
      return <CustomerIssuesWidget />;
    
    // === 기본 fallback ===
    default:
      return (
        <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-gray-400 to-gray-600 p-4 text-white">
          <div className="text-center">
            <div className="mb-2 text-3xl">❓</div>
            <div className="text-sm">알 수 없는 위젯 타입: {element.subtype}</div>
          </div>
        </div>
      );
  }
}

interface DashboardViewerProps {
  elements: DashboardElement[];
  dashboardId: string;
  refreshInterval?: number; // 전체 대시보드 새로고침 간격 (ms)
}

/**
 * 대시보드 뷰어 컴포넌트
 * - 저장된 대시보드를 읽기 전용으로 표시
 * - 실시간 데이터 업데이트
 * - 반응형 레이아웃
 */
export function DashboardViewer({ elements, dashboardId, refreshInterval }: DashboardViewerProps) {
  const [elementData, setElementData] = useState<Record<string, QueryResult>>({});
  const [loadingElements, setLoadingElements] = useState<Set<string>>(new Set());
  const [lastRefresh, setLastRefresh] = useState<Date>(new Date());

  // 개별 요소 데이터 로딩
  const loadElementData = useCallback(async (element: DashboardElement) => {
    if (!element.dataSource?.query || element.type !== "chart") {
      return;
    }

    setLoadingElements((prev) => new Set([...prev, element.id]));

    try {
      let result;

      // 외부 DB vs 현재 DB 분기
      if (element.dataSource.connectionType === "external" && element.dataSource.externalConnectionId) {
        // 외부 DB
        const { ExternalDbConnectionAPI } = await import("@/lib/api/externalDbConnection");
        const externalResult = await ExternalDbConnectionAPI.executeQuery(
          parseInt(element.dataSource.externalConnectionId),
          element.dataSource.query,
        );

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

        const data: QueryResult = {
          columns: externalResult.data?.[0] ? Object.keys(externalResult.data[0]) : [],
          rows: externalResult.data || [],
          totalRows: externalResult.data?.length || 0,
          executionTime: 0,
        };

        setElementData((prev) => ({
          ...prev,
          [element.id]: data,
        }));
      } else {
        // 현재 DB
        const { dashboardApi } = await import("@/lib/api/dashboard");
        result = await dashboardApi.executeQuery(element.dataSource.query);

        const data: QueryResult = {
          columns: result.columns || [],
          rows: result.rows || [],
          totalRows: result.rowCount || 0,
          executionTime: 0,
        };

        setElementData((prev) => ({
          ...prev,
          [element.id]: data,
        }));
      }
    } catch (error) {
      // 에러 발생 시 무시 (차트는 빈 상태로 표시됨)
    } finally {
      setLoadingElements((prev) => {
        const newSet = new Set(prev);
        newSet.delete(element.id);
        return newSet;
      });
    }
  }, []);

  // 모든 요소 데이터 로딩
  const loadAllData = useCallback(async () => {
    setLastRefresh(new Date());

    const chartElements = elements.filter((el) => el.type === "chart" && el.dataSource?.query);

    // 병렬로 모든 차트 데이터 로딩
    await Promise.all(chartElements.map((element) => loadElementData(element)));
  }, [elements, loadElementData]);

  // 초기 데이터 로딩
  useEffect(() => {
    loadAllData();
  }, [loadAllData]);

  // 전체 새로고침 간격 설정
  useEffect(() => {
    if (!refreshInterval || refreshInterval === 0) {
      return;
    }

    const interval = setInterval(loadAllData, refreshInterval);
    return () => clearInterval(interval);
  }, [refreshInterval, loadAllData]);

  // 요소가 없는 경우
  if (elements.length === 0) {
    return (
      <div className="flex h-full items-center justify-center bg-gray-50">
        <div className="text-center">
          <div className="mb-4 text-6xl">📊</div>
          <div className="mb-2 text-xl font-medium text-gray-700">표시할 요소가 없습니다</div>
          <div className="text-sm text-gray-500">대시보드 편집기에서 차트나 위젯을 추가해보세요</div>
        </div>
      </div>
    );
  }

  return (
    <div className="relative h-full w-full overflow-auto bg-gray-100">
      {/* 새로고침 상태 표시 */}
      <div className="text-muted-foreground absolute top-4 right-4 z-10 rounded-lg bg-white px-3 py-2 text-xs shadow-sm">
        마지막 업데이트: {lastRefresh.toLocaleTimeString()}
        {Array.from(loadingElements).length > 0 && (
          <span className="text-primary ml-2">({Array.from(loadingElements).length}개 로딩 중...)</span>
        )}
      </div>

      {/* 대시보드 요소들 */}
      <div className="relative" style={{ minHeight: "100%" }}>
        {elements.map((element) => (
          <ViewerElement
            key={element.id}
            element={element}
            data={elementData[element.id]}
            isLoading={loadingElements.has(element.id)}
            onRefresh={() => loadElementData(element)}
          />
        ))}
      </div>
    </div>
  );
}

interface ViewerElementProps {
  element: DashboardElement;
  data?: QueryResult;
  isLoading: boolean;
  onRefresh: () => void;
}

/**
 * 개별 뷰어 요소 컴포넌트
 */
function ViewerElement({ element, data, isLoading, onRefresh }: ViewerElementProps) {
  const [isHovered, setIsHovered] = useState(false);

  return (
    <div
      className="absolute overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm"
      style={{
        left: element.position.x,
        top: element.position.y,
        width: element.size.width,
        height: element.size.height,
      }}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      {/* 헤더 */}
      <div className="flex items-center justify-between border-b border-gray-200 bg-gray-50 px-4 py-3">
        <h3 className="text-sm font-semibold text-gray-800">{element.title}</h3>

        {/* 새로고침 버튼 (호버 시에만 표시) */}
        {isHovered && (
          <button
            onClick={onRefresh}
            disabled={isLoading}
            className="hover:text-muted-foreground text-gray-400 disabled:opacity-50"
            title="새로고침"
          >
            {isLoading ? (
              <div className="h-4 w-4 animate-spin rounded-full border border-gray-400 border-t-transparent" />
            ) : (
              "🔄"
            )}
          </button>
        )}
      </div>

      {/* 내용 */}
      <div className="h-[calc(100%-57px)]">
        {element.type === "chart" ? (
          <ChartRenderer element={element} data={data} width={element.size.width} height={element.size.height - 57} />
        ) : renderWidget(element)}
      </div>

      {/* 로딩 오버레이 */}
      {isLoading && (
        <div className="bg-opacity-75 absolute inset-0 flex items-center justify-center bg-white">
          <div className="text-center">
            <div className="border-primary mx-auto mb-2 h-6 w-6 animate-spin rounded-full border-2 border-t-transparent" />
            <div className="text-muted-foreground text-sm">업데이트 중...</div>
          </div>
        </div>
      )}
    </div>
  );
}

/**
 * 샘플 쿼리 결과 생성 함수 (뷰어용)
 */
function generateSampleQueryResult(query: string, chartType: string): QueryResult {
  // 시간에 따라 약간씩 다른 데이터 생성 (실시간 업데이트 시뮬레이션)
  const timeVariation = Math.sin(Date.now() / 10000) * 0.1 + 1;

  const isMonthly = query.toLowerCase().includes("month");
  const isSales = query.toLowerCase().includes("sales") || query.toLowerCase().includes("매출");
  const isUsers = query.toLowerCase().includes("users") || query.toLowerCase().includes("사용자");
  const isProducts = query.toLowerCase().includes("product") || query.toLowerCase().includes("상품");
  const isWeekly = query.toLowerCase().includes("week");

  let columns: string[];
  let rows: Record<string, any>[];

  if (isMonthly && isSales) {
    columns = ["month", "sales", "order_count"];
    rows = [
      { month: "2024-01", sales: Math.round(1200000 * timeVariation), order_count: Math.round(45 * timeVariation) },
      { month: "2024-02", sales: Math.round(1350000 * timeVariation), order_count: Math.round(52 * timeVariation) },
      { month: "2024-03", sales: Math.round(1180000 * timeVariation), order_count: Math.round(41 * timeVariation) },
      { month: "2024-04", sales: Math.round(1420000 * timeVariation), order_count: Math.round(58 * timeVariation) },
      { month: "2024-05", sales: Math.round(1680000 * timeVariation), order_count: Math.round(67 * timeVariation) },
      { month: "2024-06", sales: Math.round(1540000 * timeVariation), order_count: Math.round(61 * timeVariation) },
    ];
  } else if (isWeekly && isUsers) {
    columns = ["week", "new_users"];
    rows = [
      { week: "2024-W10", new_users: Math.round(23 * timeVariation) },
      { week: "2024-W11", new_users: Math.round(31 * timeVariation) },
      { week: "2024-W12", new_users: Math.round(28 * timeVariation) },
      { week: "2024-W13", new_users: Math.round(35 * timeVariation) },
      { week: "2024-W14", new_users: Math.round(42 * timeVariation) },
      { week: "2024-W15", new_users: Math.round(38 * timeVariation) },
    ];
  } else if (isProducts) {
    columns = ["product_name", "total_sold", "revenue"];
    rows = [
      {
        product_name: "스마트폰",
        total_sold: Math.round(156 * timeVariation),
        revenue: Math.round(234000000 * timeVariation),
      },
      {
        product_name: "노트북",
        total_sold: Math.round(89 * timeVariation),
        revenue: Math.round(178000000 * timeVariation),
      },
      {
        product_name: "태블릿",
        total_sold: Math.round(134 * timeVariation),
        revenue: Math.round(67000000 * timeVariation),
      },
      {
        product_name: "이어폰",
        total_sold: Math.round(267 * timeVariation),
        revenue: Math.round(26700000 * timeVariation),
      },
      {
        product_name: "스마트워치",
        total_sold: Math.round(98 * timeVariation),
        revenue: Math.round(49000000 * timeVariation),
      },
    ];
  } else {
    columns = ["category", "value", "count"];
    rows = [
      { category: "A", value: Math.round(100 * timeVariation), count: Math.round(10 * timeVariation) },
      { category: "B", value: Math.round(150 * timeVariation), count: Math.round(15 * timeVariation) },
      { category: "C", value: Math.round(120 * timeVariation), count: Math.round(12 * timeVariation) },
      { category: "D", value: Math.round(180 * timeVariation), count: Math.round(18 * timeVariation) },
      { category: "E", value: Math.round(90 * timeVariation), count: Math.round(9 * timeVariation) },
    ];
  }

  return {
    columns,
    rows,
    totalRows: rows.length,
    executionTime: Math.floor(Math.random() * 100) + 50,
  };
}
