"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { RefreshCw, AlertTriangle, Cloud, Construction, Database as DatabaseIcon } from "lucide-react";
import { DashboardElement, ChartDataSource } from "@/components/admin/dashboard/types";
import { getApiUrl } from "@/lib/utils/apiUrl";

type AlertType = "accident" | "weather" | "construction" | "system" | "security" | "other";

interface Alert {
  id: string;
  type: AlertType;
  severity: "high" | "medium" | "low";
  title: string;
  location?: string;
  description: string;
  timestamp: string;
  source?: string;
}

interface RiskAlertTestWidgetProps {
  element: DashboardElement;
}

export default function RiskAlertTestWidget({ element }: RiskAlertTestWidgetProps) {
  const [alerts, setAlerts] = useState<Alert[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [filter, setFilter] = useState<AlertType | "all">("all");
  const [lastRefreshTime, setLastRefreshTime] = useState<Date | null>(null);

  const dataSources = useMemo(() => {
    return element?.dataSources || element?.chartConfig?.dataSources;
  }, [element?.dataSources, element?.chartConfig?.dataSources]);

  const parseTextData = (text: string): any[] => {
    // XML 형식 감지
    if (text.trim().startsWith("<?xml") || text.trim().startsWith("<result>")) {
      // console.log("📄 XML 형식 데이터 감지");
      return parseXmlData(text);
    }

    // CSV 형식 (기상청 특보)
    // console.log("📄 CSV 형식 데이터 감지");
    const lines = text.split("\n").filter((line) => {
      const trimmed = line.trim();
      return trimmed && !trimmed.startsWith("#") && trimmed !== "=";
    });

    return lines.map((line) => {
      const values = line.split(",");
      const obj: any = {};

      if (values.length >= 11) {
        obj.code = values[0];
        obj.region = values[1];
        obj.subCode = values[2];
        obj.subRegion = values[3];
        obj.tmFc = values[4];
        obj.tmEf = values[5];
        obj.warning = values[6];
        obj.level = values[7];
        obj.status = values[8];
        obj.period = values[9];
        obj.name = obj.subRegion || obj.region || obj.code;
      } else {
        values.forEach((value, index) => {
          obj[`field_${index}`] = value;
        });
      }

      return obj;
    });
  };

  const parseXmlData = (xmlText: string): any[] => {
    try {
      // 간단한 XML 파싱 (DOMParser 사용)
      const parser = new DOMParser();
      const xmlDoc = parser.parseFromString(xmlText, "text/xml");
      
      const records = xmlDoc.getElementsByTagName("record");
      const results: any[] = [];

      for (let i = 0; i < records.length; i++) {
        const record = records[i];
        const obj: any = {};

        // 모든 자식 노드를 객체로 변환
        for (let j = 0; j < record.children.length; j++) {
          const child = record.children[j];
          obj[child.tagName] = child.textContent || "";
        }

        results.push(obj);
      }

      // console.log(`✅ XML 파싱 완료: ${results.length}개 레코드`);
      return results;
    } catch (error) {
      console.error("❌ XML 파싱 실패:", error);
      return [];
    }
  };

  const loadRestApiData = useCallback(async (source: ChartDataSource) => {
    // 🆕 외부 연결 ID가 있으면 먼저 외부 연결 정보를 가져옴
    let actualEndpoint = source.endpoint;
    let actualQueryParams = source.queryParams;
    let actualHeaders = source.headers;

    if (source.externalConnectionId) {
      // console.log("🔗 외부 연결 ID 감지:", source.externalConnectionId);
      try {
        const { ExternalDbConnectionAPI } = await import("@/lib/api/externalDbConnection");
        const connection = await ExternalDbConnectionAPI.getApiConnectionById(Number(source.externalConnectionId));
        
        if (connection) {
          // console.log("✅ 외부 연결 정보 가져옴:", connection);
          
          // 전체 엔드포인트 URL 생성
          actualEndpoint = connection.endpoint_path
            ? `${connection.base_url}${connection.endpoint_path}`
            : connection.base_url;
          
          // console.log("📍 실제 엔드포인트:", actualEndpoint);
          
          // 기본 헤더 적용
          const headers: any[] = [];
          if (connection.default_headers && Object.keys(connection.default_headers).length > 0) {
            Object.entries(connection.default_headers).forEach(([key, value]) => {
              headers.push({ key, value });
            });
          }
          
          // 인증 정보 적용
          const queryParams: any[] = [];
          if (connection.auth_type && connection.auth_type !== "none" && connection.auth_config) {
            const authConfig = connection.auth_config;
            
            if (connection.auth_type === "api-key") {
              if (authConfig.keyLocation === "header" && authConfig.keyName && authConfig.keyValue) {
                headers.push({ key: authConfig.keyName, value: authConfig.keyValue });
                // console.log("🔑 API Key 헤더 추가:", authConfig.keyName);
              } else if (authConfig.keyLocation === "query" && authConfig.keyName && authConfig.keyValue) {
                const actualKeyName = authConfig.keyName === "apiKey" ? "key" : authConfig.keyName;
                queryParams.push({ key: actualKeyName, value: authConfig.keyValue });
                // console.log("🔑 API Key 쿼리 파라미터 추가:", actualKeyName);
              }
            } else if (connection.auth_type === "bearer" && authConfig.token) {
              headers.push({ key: "Authorization", value: `Bearer ${authConfig.token}` });
              // console.log("🔑 Bearer Token 헤더 추가");
            } else if (connection.auth_type === "basic" && authConfig.username && authConfig.password) {
              const credentials = btoa(`${authConfig.username}:${authConfig.password}`);
              headers.push({ key: "Authorization", value: `Basic ${credentials}` });
              // console.log("🔑 Basic Auth 헤더 추가");
            }
          }
          
          actualHeaders = headers;
          actualQueryParams = queryParams;
          
          // console.log("✅ 최종 헤더:", actualHeaders);
          // console.log("✅ 최종 쿼리 파라미터:", actualQueryParams);
        }
      } catch (err) {
        console.error("❌ 외부 연결 정보 가져오기 실패:", err);
      }
    }

    if (!actualEndpoint) {
      throw new Error("API endpoint가 없습니다.");
    }

    // 쿼리 파라미터 처리
    const queryParamsObj: Record<string, string> = {};
    if (actualQueryParams && Array.isArray(actualQueryParams)) {
      actualQueryParams.forEach((param) => {
        if (param.key && param.value) {
          queryParamsObj[param.key] = param.value;
        }
      });
    }

    // 헤더 처리
    const headersObj: Record<string, string> = {};
    if (actualHeaders && Array.isArray(actualHeaders)) {
      actualHeaders.forEach((header) => {
        if (header.key && header.value) {
          headersObj[header.key] = header.value;
        }
      });
    }

    // console.log("🌐 API 호출 준비:", {
    //   endpoint: actualEndpoint,
    //   queryParams: queryParamsObj,
    //   headers: headersObj,
    // });

    const response = await fetch(getApiUrl("/api/dashboards/fetch-external-api"), {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include",
      body: JSON.stringify({
        url: actualEndpoint,
        method: "GET",
        headers: headersObj,
        queryParams: queryParamsObj,
      }),
    });

    // console.log("🌐 API 응답 상태:", response.status);

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

    const result = await response.json();
    if (!result.success) {
      throw new Error(result.message || "API 호출 실패");
    }

    let apiData = result.data;
    
    // console.log("🔍 API 응답 데이터 타입:", typeof apiData);
    // console.log("🔍 API 응답 데이터 (처음 500자):", typeof apiData === "string" ? apiData.substring(0, 500) : JSON.stringify(apiData).substring(0, 500));

    // 백엔드가 {text: "XML..."} 형태로 감싼 경우 처리
    if (apiData && typeof apiData === "object" && apiData.text && typeof apiData.text === "string") {
      // console.log("📦 백엔드가 text 필드로 감싼 데이터 감지");
      apiData = parseTextData(apiData.text);
      // console.log("✅ 파싱 성공:", apiData.length, "개 행");
    } else if (typeof apiData === "string") {
      // console.log("📄 텍스트 형식 데이터 감지, 파싱 시도");
      apiData = parseTextData(apiData);
      // console.log("✅ 파싱 성공:", apiData.length, "개 행");
    } else if (Array.isArray(apiData)) {
      // console.log("✅ 이미 배열 형태의 데이터입니다.");
    } else {
      // console.log("⚠️ 예상치 못한 데이터 형식입니다. 배열로 변환 시도.");
      apiData = [apiData];
    }

    // JSON Path 적용
    if (source.jsonPath && typeof apiData === "object" && !Array.isArray(apiData)) {
      const paths = source.jsonPath.split(".");
      for (const path of paths) {
        if (apiData && typeof apiData === "object" && path in apiData) {
          apiData = apiData[path];
        }
      }
    }

    const rows = Array.isArray(apiData) ? apiData : [apiData];
    return convertToAlerts(rows, source.name || source.id || "API");
  }, []);

  const loadDatabaseData = useCallback(async (source: ChartDataSource) => {
    if (!source.query) {
      throw new Error("SQL 쿼리가 없습니다.");
    }

    if (source.connectionType === "external" && source.externalConnectionId) {
      const { ExternalDbConnectionAPI } = await import("@/lib/api/externalDbConnection");
      const externalResult = await ExternalDbConnectionAPI.executeQuery(
        parseInt(source.externalConnectionId),
        source.query
      );
      if (!externalResult.success || !externalResult.data) {
        throw new Error(externalResult.message || "외부 DB 쿼리 실행 실패");
      }
      const resultData = externalResult.data as unknown as { rows: Record<string, unknown>[] };
      return convertToAlerts(resultData.rows, source.name || source.id || "Database");
    } else {
      const { dashboardApi } = await import("@/lib/api/dashboard");
      const result = await dashboardApi.executeQuery(source.query);
      return convertToAlerts(result.rows, source.name || source.id || "Database");
    }
  }, []);

  const convertToAlerts = useCallback((rows: any[], sourceName: string): Alert[] => {
    // console.log("🔄 convertToAlerts 호출:", rows.length, "개 행");
    
    return rows.map((row: any, index: number) => {
      // 타입 결정 (UTIC XML 기준)
      let type: AlertType = "other";
      
      // incidenteTypeCd: 1=사고, 2=공사, 3=행사, 4=기타
      if (row.incidenteTypeCd) {
        const typeCode = String(row.incidenteTypeCd);
        if (typeCode === "1") {
          type = "accident";
        } else if (typeCode === "2") {
          type = "construction";
        }
      }
      // 기상 특보 데이터 (warning 필드가 있으면 무조건 날씨)
      else if (row.warning) {
        type = "weather";
      } 
      // 일반 데이터
      else if (row.type || row.타입 || row.alert_type) {
        type = (row.type || row.타입 || row.alert_type) as AlertType;
      }

      // 심각도 결정
      let severity: "high" | "medium" | "low" = "medium";
      
      if (type === "accident") {
        severity = "high"; // 사고는 항상 높음
      } else if (type === "construction") {
        severity = "medium"; // 공사는 중간
      } else if (row.level === "경보") {
        severity = "high";
      } else if (row.level === "주의" || row.level === "주의보") {
        severity = "medium";
      } else if (row.severity || row.심각도 || row.priority) {
        severity = (row.severity || row.심각도 || row.priority) as "high" | "medium" | "low";
      }

      // 제목 생성 (UTIC XML 기준)
      let title = "";
      
      if (type === "accident") {
        // incidenteSubTypeCd: 1=추돌, 2=접촉, 3=전복, 4=추락, 5=화재, 6=침수, 7=기타
        const subType = row.incidenteSubTypeCd;
        const subTypeMap: { [key: string]: string } = {
          "1": "추돌사고", "2": "접촉사고", "3": "전복사고", 
          "4": "추락사고", "5": "화재사고", "6": "침수사고", "7": "기타사고"
        };
        title = subTypeMap[String(subType)] || "교통사고";
      } else if (type === "construction") {
        title = "도로공사";
      } else if (type === "weather" && row.warning && row.level) {
        // 날씨 특보: 공백 제거
        const warning = String(row.warning).trim();
        const level = String(row.level).trim();
        title = `${warning} ${level}`;
      } else {
        title = row.title || row.제목 || row.name || "알림";
      }

      // 위치 정보 (UTIC XML 기준) - 공백 제거
      let location = row.addressJibun || row.addressNew || 
        row.roadName || row.linkName || 
        row.subRegion || row.region || 
        row.location || row.위치 || undefined;
      
      if (location && typeof location === "string") {
        location = location.trim();
      }

      // 설명 생성 (간결하게)
      let description = "";
      
      if (row.incidentMsg) {
        description = row.incidentMsg;
      } else if (row.eventContent) {
        description = row.eventContent;
      } else if (row.period) {
        description = `발효 기간: ${row.period}`;
      } else if (row.description || row.설명 || row.content) {
        description = row.description || row.설명 || row.content;
      } else {
        // 설명이 없으면 위치 정보만 표시
        description = location || "상세 정보 없음";
      }

      // 타임스탬프
      const timestamp = row.startDate || row.eventDate || 
        row.tmFc || row.tmEf || 
        row.timestamp || row.created_at || 
        new Date().toISOString();

      const alert: Alert = {
        // 중복 방지를 위해 소스명과 인덱스를 포함하여 고유 ID 생성
        id: `${sourceName}-${index}-${row.id || row.alert_id || row.incidentId || row.eventId || row.code || row.subCode || Date.now()}`,
        type,
        severity,
        title,
        location,
        description,
        timestamp,
        source: sourceName,
      };

      // console.log(`  ✅ Alert ${index}:`, alert);
      return alert;
    });
  }, []);

  const loadMultipleDataSources = useCallback(async () => {
    if (!dataSources || dataSources.length === 0) {
      return;
    }

    setLoading(true);
    setError(null);

    // console.log("🔄 RiskAlertTestWidget 데이터 로딩 시작:", dataSources.length, "개 소스");

    try {
      const results = await Promise.allSettled(
        dataSources.map(async (source, index) => {
          // console.log(`📡 데이터 소스 ${index + 1} 로딩 중:`, source.name, source.type);
          if (source.type === "api") {
            const alerts = await loadRestApiData(source);
            // console.log(`✅ 데이터 소스 ${index + 1} 완료:`, alerts.length, "개 알림");
            return alerts;
          } else {
            const alerts = await loadDatabaseData(source);
            // console.log(`✅ 데이터 소스 ${index + 1} 완료:`, alerts.length, "개 알림");
            return alerts;
          }
        })
      );

      const allAlerts: Alert[] = [];
      results.forEach((result, index) => {
        if (result.status === "fulfilled") {
          // console.log(`✅ 결과 ${index + 1} 병합:`, result.value.length, "개 알림");
          allAlerts.push(...result.value);
        } else {
          console.error(`❌ 결과 ${index + 1} 실패:`, result.reason);
        }
      });

      // console.log("✅ 총", allAlerts.length, "개 알림 로딩 완료");
      allAlerts.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
      setAlerts(allAlerts);
      setLastRefreshTime(new Date());
    } catch (err: any) {
      console.error("❌ 데이터 로딩 실패:", err);
      setError(err.message || "데이터 로딩 실패");
    } finally {
      setLoading(false);
    }
  }, [dataSources, loadRestApiData, loadDatabaseData]);

  // 수동 새로고침 핸들러
  const handleManualRefresh = useCallback(() => {
    // console.log("🔄 수동 새로고침 버튼 클릭");
    loadMultipleDataSources();
  }, [loadMultipleDataSources]);

  // 초기 로드
  useEffect(() => {
    if (dataSources && dataSources.length > 0) {
      loadMultipleDataSources();
    }
  }, [dataSources, loadMultipleDataSources]);

  // 자동 새로고침
  useEffect(() => {
    if (!dataSources || dataSources.length === 0) return;

    // 모든 데이터 소스 중 가장 짧은 refreshInterval 찾기
    const intervals = dataSources
      .map((ds) => ds.refreshInterval)
      .filter((interval): interval is number => typeof interval === "number" && interval > 0);

    if (intervals.length === 0) return;

    const minInterval = Math.min(...intervals);
    // console.log(`⏱️ 자동 새로고침 설정: ${minInterval}초마다`);

    const intervalId = setInterval(() => {
      // console.log("🔄 자동 새로고침 실행");
      loadMultipleDataSources();
    }, minInterval * 1000);

    return () => {
      // console.log("⏹️ 자동 새로고침 정리");
      clearInterval(intervalId);
    };
  }, [dataSources, loadMultipleDataSources]);

  const getTypeIcon = (type: AlertType) => {
    switch (type) {
      case "accident": return <AlertTriangle className="h-4 w-4" />;
      case "weather": return <Cloud className="h-4 w-4" />;
      case "construction": return <Construction className="h-4 w-4" />;
      default: return <AlertTriangle className="h-4 w-4" />;
    }
  };

  const getSeverityColor = (severity: "high" | "medium" | "low") => {
    switch (severity) {
      case "high": return "bg-destructive";
      case "medium": return "bg-warning/100";
      case "low": return "bg-primary";
    }
  };

  const filteredAlerts = filter === "all" ? alerts : alerts.filter(a => a.type === filter);

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

  if (error) {
    return (
      <div className="flex h-full items-center justify-center">
        <div className="text-center text-destructive">
          <p className="text-sm">⚠️ {error}</p>
          <button
            onClick={loadMultipleDataSources}
            className="mt-2 rounded bg-destructive/10 px-3 py-1 text-xs text-destructive hover:bg-destructive/20"
          >
            다시 시도
          </button>
        </div>
      </div>
    );
  }

  if (!dataSources || dataSources.length === 0) {
    return (
      <div className="flex h-full items-center justify-center p-3">
        <div className="max-w-xs space-y-2 text-center">
          <div className="text-3xl">🚨</div>
          <h3 className="text-sm font-bold text-foreground">리스크/알림</h3>
          <div className="space-y-1.5 text-xs text-foreground">
            <p className="font-medium">다중 데이터 소스 지원</p>
            <ul className="space-y-0.5 text-left">
              <li>• 여러 REST API 동시 연결</li>
              <li>• 여러 Database 동시 연결</li>
              <li>• REST API + Database 혼합 가능</li>
              <li>• 알림 타입별 필터링</li>
            </ul>
          </div>
          <div className="mt-2 rounded-lg bg-primary/10 p-2 text-[10px] text-primary">
            <p className="font-medium">⚙️ 설정 방법</p>
            <p>데이터 소스를 추가하고 저장하세요</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="flex h-full w-full flex-col overflow-hidden bg-background">
      {/* 헤더 */}
      <div className="flex items-center justify-between border-b bg-background/80 p-3">
        <div>
          <h3 className="text-base font-semibold">
            {element?.customTitle || "리스크/알림"}
          </h3>
          <p className="text-xs text-muted-foreground">
            {dataSources?.length || 0}개 데이터 소스 • {alerts.length}개 알림
            {lastRefreshTime && (
              <span className="ml-2">
                • {lastRefreshTime.toLocaleTimeString("ko-KR")}
              </span>
            )}
          </p>
        </div>
        <Button
          variant="outline"
          size="sm"
          onClick={handleManualRefresh}
          disabled={loading}
          className="h-8 gap-2 text-xs"
        >
          <RefreshCw className={`h-3 w-3 ${loading ? "animate-spin" : ""}`} />
          새로고침
        </Button>
      </div>

      {/* 컨텐츠 */}
      <div className="flex flex-1 flex-col overflow-hidden p-2">
        <div className="mb-2 flex gap-1 overflow-x-auto">
        <Button
          variant={filter === "all" ? "default" : "outline"}
          size="sm"
          onClick={() => setFilter("all")}
          className="h-7 text-xs"
        >
          전체 ({alerts.length})
        </Button>
        {["accident", "weather", "construction"].map((type) => {
          const count = alerts.filter(a => a.type === type).length;
          return (
            <Button
              key={type}
              variant={filter === type ? "default" : "outline"}
              size="sm"
              onClick={() => setFilter(type as AlertType)}
              className="h-7 text-xs"
            >
              {type === "accident" && "사고"}
              {type === "weather" && "날씨"}
              {type === "construction" && "공사"}
              {" "}({count})
            </Button>
          );
        })}
      </div>

      <div className="flex-1 space-y-1.5 overflow-y-auto pr-1">
        {filteredAlerts.length === 0 ? (
          <div className="flex h-full items-center justify-center text-muted-foreground">
            <p className="text-sm">알림이 없습니다</p>
          </div>
        ) : (
          filteredAlerts.map((alert, idx) => (
            // key 중복 방지를 위해 인덱스 추가
            <Card key={`${alert.id}-${idx}`} className="p-2">
              <div className="flex items-start gap-2">
                <div className={`mt-0.5 rounded-full p-1 ${alert.severity === "high" ? "bg-destructive/10 text-destructive" : alert.severity === "medium" ? "bg-warning/10 text-warning" : "bg-primary/10 text-primary"}`}>
                  {getTypeIcon(alert.type)}
                </div>
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-1.5">
                    <h4 className="text-xs font-semibold truncate">{alert.title}</h4>
                    <Badge variant={alert.severity === "high" ? "destructive" : "secondary"} className="h-4 text-[10px]">
                      {alert.severity === "high" && "긴급"}
                      {alert.severity === "medium" && "주의"}
                      {alert.severity === "low" && "정보"}
                    </Badge>
                  </div>
                  {alert.location && (
                    <p className="text-[10px] text-muted-foreground mt-0.5">📍 {alert.location}</p>
                  )}
                  <p className="text-[10px] text-foreground mt-0.5 line-clamp-2">{alert.description}</p>
                  <div className="mt-1 flex items-center gap-2 text-[9px] text-muted-foreground">
                    <span>
                      {(() => {
                        const original = String(alert.timestamp);
                        const ts = original.replace(/\s+/g, ""); // 공백 제거
                        
                        // yyyyMMddHHmm 형식 감지 (12자리 숫자)
                        if (/^\d{12}$/.test(ts)) {
                          const year = ts.substring(0, 4);
                          const month = ts.substring(4, 6);
                          const day = ts.substring(6, 8);
                          const hour = ts.substring(8, 10);
                          const minute = ts.substring(10, 12);
                          const date = new Date(`${year}-${month}-${day}T${hour}:${minute}:00`);
                          return isNaN(date.getTime()) ? original : date.toLocaleString("ko-KR");
                        }
                        
                        // "2025년 11월 14일 13시 20분" 형식
                        const koreanMatch = original.match(/(\d{4})년\s*(\d{1,2})월\s*(\d{1,2})일\s*(\d{1,2})시\s*(\d{1,2})분/);
                        if (koreanMatch) {
                          const [, year, month, day, hour, minute] = koreanMatch;
                          const date = new Date(`${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}T${hour.padStart(2, '0')}:${minute.padStart(2, '0')}:00`);
                          return isNaN(date.getTime()) ? original : date.toLocaleString("ko-KR");
                        }
                        
                        // ISO 형식 또는 일반 날짜 형식
                        const date = new Date(original);
                        return isNaN(date.getTime()) ? original : date.toLocaleString("ko-KR");
                      })()}
                    </span>
                    {alert.source && <span>· {alert.source}</span>}
                  </div>
                </div>
              </div>
            </Card>
          ))
        )}
      </div>
      </div>
    </div>
  );
}

