"use client";

import React, { useState, useCallback, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Globe, Settings, TestTube, History, Info } from "lucide-react";

// 타입 import
import {
  ExternalCallConfig,
  ExternalCallPanelProps,
  RestApiSettings as RestApiSettingsType,
  ApiTestResult,
} from "@/types/external-call/ExternalCallTypes";
import { DataMappingConfig, TableInfo } from "@/types/external-call/DataMappingTypes";

// API import
import { DataFlowAPI } from "@/lib/api/dataflow";
import { toast } from "sonner";

// 하위 컴포넌트 import
import RestApiSettings from "./RestApiSettings";
import ExternalCallTestPanel from "./ExternalCallTestPanel";
import { DataMappingSettings } from "./DataMappingSettings";

/**
 * 🌐 외부호출 메인 패널 컴포넌트
 *
 * 데이터 저장 기능과 완전히 분리된 독립적인 외부호출 전용 패널
 * REST API 설정, 테스트, 실행 이력 등을 통합 관리
 */
const ExternalCallPanel: React.FC<ExternalCallPanelProps> = ({
  relationshipId,
  onSettingsChange,
  initialSettings,
  readonly = false,
}) => {
  console.log("🌐 [ExternalCallPanel] Component mounted with props:", {
    relationshipId,
    initialSettings,
    readonly,
  });
  // 상태 관리
  const [config, setConfig] = useState<ExternalCallConfig>(
    () => {
      if (initialSettings) {
        console.log("🔄 [ExternalCallPanel] 기존 설정 로드:", initialSettings);
        return initialSettings;
      }
      
      console.log("🔄 [ExternalCallPanel] 기본 설정 사용");
      return {
        callType: "rest-api",
        restApiSettings: {
          apiUrl: "",
          httpMethod: "POST",
          headers: {
            "Content-Type": "application/json",
            Accept: "application/json",
          },
          bodyTemplate: `{
  "message": "데이터가 업데이트되었습니다",
  "data": {{sourceData}},
  "timestamp": "{{timestamp}}",
  "relationshipId": "{{relationshipId}}"
}`,
          authentication: {
            type: "none",
          },
          timeout: 30000, // 30초
          retryCount: 3,
        },
      };
    },
  );

  const [activeTab, setActiveTab] = useState<string>("settings");
  const [lastTestResult, setLastTestResult] = useState<ApiTestResult | null>(null);
  const [isConfigValid, setIsConfigValid] = useState<boolean>(false);

  // 데이터 매핑 상태
  const [dataMappingConfig, setDataMappingConfig] = useState<DataMappingConfig>(() => {
    // initialSettings에서 데이터 매핑 정보 불러오기
    if (initialSettings?.dataMappingConfig) {
      console.log("🔄 [ExternalCallPanel] 기존 데이터 매핑 설정 로드:", initialSettings.dataMappingConfig);
      return initialSettings.dataMappingConfig;
    }
    
    console.log("🔄 [ExternalCallPanel] 기본 데이터 매핑 설정 사용");
    return {
      direction: "none",
    };
  });

  // 사용 가능한 테이블 목록 (실제 API에서 로드)
  const [availableTables, setAvailableTables] = useState<TableInfo[]>([]);
  const [tablesLoading, setTablesLoading] = useState(false);

  // 테이블 목록 로드
  useEffect(() => {
    const loadTables = async () => {
      try {
        setTablesLoading(true);
        const tables = await DataFlowAPI.getTables();
        
        // 테이블 정보를 TableInfo 형식으로 변환
        const tableInfos: TableInfo[] = await Promise.all(
          tables.map(async (table) => {
            try {
              const columns = await DataFlowAPI.getTableColumns(table.tableName);
              return {
                name: table.tableName,
                displayName: table.displayName || table.tableName,
                fields: columns.map((col) => ({
                  name: col.columnName,
                  dataType: col.dataType,
                  nullable: col.nullable,
                  isPrimaryKey: col.isPrimaryKey || false,
                })),
              };
            } catch (error) {
              console.warn(`테이블 ${table.tableName} 컬럼 정보 로드 실패:`, error);
              return {
                name: table.tableName,
                displayName: table.displayName || table.tableName,
                fields: [],
              };
            }
          })
        );
        
        setAvailableTables(tableInfos);
      } catch (error) {
        console.error("테이블 목록 로드 실패:", error);
        toast.error("테이블 목록을 불러오는데 실패했습니다.");
        // 실패 시 빈 배열로 설정
        setAvailableTables([]);
      } finally {
        setTablesLoading(false);
      }
    };

    loadTables();
  }, []);

  // 설정 변경 핸들러
  const handleRestApiSettingsChange = useCallback(
    (newSettings: RestApiSettingsType) => {
      const updatedConfig: ExternalCallConfig = {
        ...config,
        restApiSettings: newSettings,
        metadata: {
          ...config.metadata,
          updatedAt: new Date().toISOString(),
          version: "1.0",
        },
      };

      setConfig(updatedConfig);
      onSettingsChange({
        ...updatedConfig,
        dataMappingConfig,
      });
    },
    [config, onSettingsChange, dataMappingConfig],
  );

  // 데이터 매핑 설정 변경 핸들러
  const handleDataMappingConfigChange = useCallback(
    (newMappingConfig: DataMappingConfig) => {
      console.log("🔄 [ExternalCallPanel] 데이터 매핑 설정 변경:", newMappingConfig);
      
      setDataMappingConfig(newMappingConfig);
      
      // 전체 설정에 데이터 매핑 정보 포함하여 상위로 전달
      onSettingsChange({
        ...config,
        dataMappingConfig: newMappingConfig,
      });
    },
    [config, onSettingsChange],
  );

  // 테스트 결과 핸들러
  const handleTestResult = useCallback((result: ApiTestResult) => {
    setLastTestResult(result);

    // 테스트 탭에 머물러서 응답 정보를 바로 확인할 수 있도록 함
    // (이전에는 성공 시 자동으로 history 탭으로 이동했음)
  }, []);

  // 설정 유효성 검사
  const validateConfig = useCallback(() => {
    const { restApiSettings } = config;

    // HTTP 메서드에 따라 바디 필요 여부 결정
    const methodNeedsBody = !["GET", "HEAD", "DELETE"].includes(restApiSettings.httpMethod?.toUpperCase());

    const isValid = !!(
      restApiSettings.apiUrl &&
      restApiSettings.apiUrl.startsWith("http") &&
      restApiSettings.httpMethod &&
      (methodNeedsBody ? restApiSettings.bodyTemplate : true) // GET/HEAD/DELETE는 바디 불필요
    );

    setIsConfigValid(isValid);
    return isValid;
  }, [config]);

  // 설정 변경 시 유효성 검사 실행
  useEffect(() => {
    validateConfig();
  }, [validateConfig]);

  return (
    <div className="flex h-full max-h-full flex-col space-y-2">
      {/* 헤더 */}
      <Card>
        <CardHeader className="pt-3 pb-2">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <Globe className="h-5 w-5 text-primary" />
              <CardTitle className="text-lg">외부 호출 설정</CardTitle>
              <Badge variant={isConfigValid ? "default" : "secondary"}>
                {isConfigValid ? "설정 완료" : "설정 필요"}
              </Badge>
            </div>
          </div>

          <div className="text-muted-foreground text-sm">
            관계 실행 시 외부 API를 호출하여 데이터를 전송하거나 알림을 보낼 수 있습니다.
          </div>
        </CardHeader>
      </Card>

      {/* 메인 탭 컨텐츠 */}
      <Tabs value={activeTab} onValueChange={setActiveTab} className="flex w-full flex-1 flex-col overflow-hidden">
        <TabsList className="grid w-full grid-cols-5">
          <TabsTrigger value="settings" className="flex items-center gap-2">
            <Settings className="h-4 w-4" />
            API 설정
          </TabsTrigger>
          <TabsTrigger value="mapping" className="flex items-center gap-2">
            🔄 데이터 매핑
          </TabsTrigger>
          <TabsTrigger value="test" className="flex items-center gap-2">
            <TestTube className="h-4 w-4" />
            테스트
          </TabsTrigger>
          <TabsTrigger value="history" className="flex items-center gap-2">
            <History className="h-4 w-4" />
            이력
          </TabsTrigger>
          <TabsTrigger value="info" className="flex items-center gap-2">
            <Info className="h-4 w-4" />
            정보
          </TabsTrigger>
        </TabsList>

        {/* API 설정 탭 */}
        <TabsContent value="settings" className="flex-1 space-y-2 overflow-y-auto">
          <RestApiSettings
            settings={config.restApiSettings}
            onSettingsChange={handleRestApiSettingsChange}
            readonly={readonly}
          />
        </TabsContent>

        {/* 데이터 매핑 탭 */}
        <TabsContent value="mapping" className="flex-1 space-y-2 overflow-y-auto">
          <DataMappingSettings
            config={dataMappingConfig}
            onConfigChange={handleDataMappingConfigChange}
            httpMethod={config.restApiSettings?.httpMethod || "GET"}
            availableTables={availableTables}
            readonly={readonly}
            tablesLoading={tablesLoading}
          />
        </TabsContent>

        {/* 테스트 탭 */}
        <TabsContent value="test" className="flex-1 space-y-4 overflow-y-auto">
          {isConfigValid ? (
            <ExternalCallTestPanel
              settings={config.restApiSettings}
              context={{
                relationshipId,
                diagramId: "test-diagram",
                userId: "current-user",
                executionId: "test-execution",
                sourceData: { test: "data" },
                timestamp: new Date().toISOString(),
              }}
              onTestResult={handleTestResult}
              disabled={readonly}
            />
          ) : (
            <Alert>
              <Info className="h-4 w-4" />
              <AlertDescription>API 테스트를 실행하려면 먼저 설정 탭에서 필수 정보를 입력해주세요.</AlertDescription>
            </Alert>
          )}
        </TabsContent>

        {/* 이력 탭 */}
        <TabsContent value="history" className="flex-1 space-y-4 overflow-y-auto">
          <Card>
            <CardHeader>
              <CardTitle className="text-base">실행 이력</CardTitle>
            </CardHeader>
            <CardContent>
              {lastTestResult ? (
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <span className="text-sm font-medium">최근 테스트 결과</span>
                    <Badge variant={lastTestResult.success ? "default" : "destructive"}>
                      {lastTestResult.success ? "성공" : "실패"}
                    </Badge>
                  </div>

                  <div className="grid grid-cols-2 gap-4 text-sm">
                    <div>
                      <span className="text-muted-foreground">상태 코드:</span>
                      <span className="ml-2 font-mono">{lastTestResult.statusCode || "N/A"}</span>
                    </div>
                    <div>
                      <span className="text-muted-foreground">응답 시간:</span>
                      <span className="ml-2 font-mono">{lastTestResult.responseTime}ms</span>
                    </div>
                  </div>

                  {lastTestResult.error && (
                    <Alert variant="destructive">
                      <AlertDescription className="text-sm">{lastTestResult.error}</AlertDescription>
                    </Alert>
                  )}

                  {lastTestResult.responseData && (
                    <div>
                      <span className="text-muted-foreground text-sm">응답 데이터:</span>
                      <pre className="bg-muted mt-1 max-h-32 overflow-auto rounded p-2 text-xs">
                        {JSON.stringify(lastTestResult.responseData, null, 2)}
                      </pre>
                    </div>
                  )}
                </div>
              ) : (
                <div className="text-muted-foreground py-8 text-center">
                  <TestTube className="mx-auto mb-2 h-8 w-8 opacity-50" />
                  <p>아직 실행 이력이 없습니다.</p>
                  <p className="text-sm">테스트 탭에서 API 호출을 테스트해보세요.</p>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        {/* 정보 탭 */}
        <TabsContent value="info" className="flex-1 space-y-4 overflow-y-auto">
          <Card>
            <CardHeader>
              <CardTitle className="text-base">템플릿 변수 가이드</CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              <div className="text-muted-foreground text-sm">요청 바디에서 사용할 수 있는 템플릿 변수들입니다:</div>

              <div className="space-y-2 text-sm">
                <div className="flex justify-between">
                  <code className="bg-muted rounded px-2 py-1">{"{{sourceData}}"}</code>
                  <span className="text-muted-foreground">소스 노드의 전체 데이터</span>
                </div>
                <div className="flex justify-between">
                  <code className="bg-muted rounded px-2 py-1">{"{{timestamp}}"}</code>
                  <span className="text-muted-foreground">현재 타임스탬프</span>
                </div>
                <div className="flex justify-between">
                  <code className="bg-muted rounded px-2 py-1">{"{{relationshipId}}"}</code>
                  <span className="text-muted-foreground">관계 ID</span>
                </div>
                <div className="flex justify-between">
                  <code className="bg-muted rounded px-2 py-1">{"{{userId}}"}</code>
                  <span className="text-muted-foreground">현재 사용자 ID</span>
                </div>
                <div className="flex justify-between">
                  <code className="bg-muted rounded px-2 py-1">{"{{executionId}}"}</code>
                  <span className="text-muted-foreground">실행 ID</span>
                </div>
              </div>

              <Alert>
                <Info className="h-4 w-4" />
                <AlertDescription className="text-sm">
                  템플릿 변수는 실제 실행 시 해당 값으로 자동 치환됩니다. JSON 형식의 데이터는 따옴표 없이 사용하세요.
                  (예: {"{{sourceData}}"})
                </AlertDescription>
              </Alert>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle className="text-base">설정 정보</CardTitle>
            </CardHeader>
            <CardContent className="space-y-2 text-sm">
              <div className="flex justify-between">
                <span className="text-muted-foreground">관계 ID:</span>
                <code className="bg-muted rounded px-2 py-1 text-xs">{relationshipId}</code>
              </div>
              <div className="flex justify-between">
                <span className="text-muted-foreground">호출 타입:</span>
                <Badge variant="outline">{config.callType.toUpperCase()}</Badge>
              </div>
              <div className="flex justify-between">
                <span className="text-muted-foreground">설정 상태:</span>
                <Badge variant={isConfigValid ? "default" : "secondary"}>{isConfigValid ? "완료" : "미완료"}</Badge>
              </div>
              {config.metadata?.updatedAt && (
                <div className="flex justify-between">
                  <span className="text-muted-foreground">마지막 수정:</span>
                  <span className="text-xs">{new Date(config.metadata.updatedAt).toLocaleString()}</span>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
};

export default ExternalCallPanel;
