"use client";

import React, { useState, useEffect } from "react";
import { X, Save, TestTube, ChevronDown, ChevronUp } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
import {
  ExternalRestApiConnectionAPI,
  ExternalRestApiConnection,
  AuthType,
  RestApiTestResult,
  RestApiTestRequest,
} from "@/lib/api/externalRestApiConnection";
import { HeadersManager } from "./HeadersManager";
import { AuthenticationConfig } from "./AuthenticationConfig";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

interface RestApiConnectionModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSave: () => void;
  connection?: ExternalRestApiConnection;
}

export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: RestApiConnectionModalProps) {
  const { toast } = useToast();

  // 폼 상태
  const [connectionName, setConnectionName] = useState("");
  const [description, setDescription] = useState("");
  const [baseUrl, setBaseUrl] = useState("");
  const [endpointPath, setEndpointPath] = useState("");
  const [defaultHeaders, setDefaultHeaders] = useState<Record<string, string>>({});
  const [defaultMethod, setDefaultMethod] = useState("GET");
  const [defaultBody, setDefaultBody] = useState("");
  const [authType, setAuthType] = useState<AuthType>("none");
  const [authConfig, setAuthConfig] = useState<any>({});
  const [timeout, setTimeout] = useState(30000);
  const [retryCount, setRetryCount] = useState(0);
  const [retryDelay, setRetryDelay] = useState(1000);
  const [isActive, setIsActive] = useState(true);
  const [saveToHistory, setSaveToHistory] = useState(false); // 위치 이력 저장 설정

  // UI 상태
  const [showAdvanced, setShowAdvanced] = useState(false);
  const [testEndpoint, setTestEndpoint] = useState("");
  const [testMethod, setTestMethod] = useState("GET");
  const [testBody, setTestBody] = useState("");
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState<RestApiTestResult | null>(null);
  const [testRequestUrl, setTestRequestUrl] = useState<string>("");
  const [saving, setSaving] = useState(false);

  // 기존 연결 데이터 로드
  useEffect(() => {
    if (connection) {
      setConnectionName(connection.connection_name);
      setDescription(connection.description || "");
      setBaseUrl(connection.base_url);
      setEndpointPath(connection.endpoint_path || "");
      setDefaultHeaders(connection.default_headers || {});
      setDefaultMethod(connection.default_method || "GET");
      setDefaultBody(connection.default_body || "");
      setAuthType(connection.auth_type);
      setAuthConfig(connection.auth_config || {});
      setTimeout(connection.timeout || 30000);
      setRetryCount(connection.retry_count || 0);
      setRetryDelay(connection.retry_delay || 1000);
      setIsActive(connection.is_active === "Y");
      setSaveToHistory(connection.save_to_history === "Y");

      // 테스트 초기값 설정
      setTestEndpoint("");
      setTestMethod(connection.default_method || "GET");
      setTestBody(connection.default_body || "");
    } else {
      // 초기화
      setConnectionName("");
      setDescription("");
      setBaseUrl("");
      setEndpointPath("");
      setDefaultHeaders({ "Content-Type": "application/json" });
      setDefaultMethod("GET");
      setDefaultBody("");
      setAuthType("none");
      setAuthConfig({});
      setTimeout(30000);
      setRetryCount(0);
      setRetryDelay(1000);
      setIsActive(true);
      setSaveToHistory(false);

      // 테스트 초기값 설정
      setTestEndpoint("");
      setTestMethod("GET");
      setTestBody("");
    }

    setTestResult(null);
    setTestRequestUrl("");
  }, [connection, isOpen]);

  // 연결 테스트
  const handleTest = async () => {
    // 유효성 검증
    if (!baseUrl.trim()) {
      toast({
        title: "입력 오류",
        description: "기본 URL을 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    setTesting(true);
    setTestResult(null);

    // 사용자가 테스트하려는 실제 외부 API URL 설정
    const fullUrl = testEndpoint ? `${baseUrl}${testEndpoint}` : baseUrl;
    setTestRequestUrl(fullUrl);

    try {
      const testRequest: RestApiTestRequest = {
        base_url: baseUrl,
        endpoint: testEndpoint || undefined,
        method: testMethod as any,
        headers: defaultHeaders,
        body: testBody ? JSON.parse(testBody) : undefined,
        auth_type: authType,
        auth_config: authConfig,
        timeout,
      };

      const result = await ExternalRestApiConnectionAPI.testConnection(testRequest);

      setTestResult(result);

      if (result.success) {
        toast({
          title: "연결 성공",
          description: `응답 시간: ${result.response_time}ms`,
        });
      } else {
        toast({
          title: "연결 실패",
          description: result.message,
          variant: "destructive",
        });
      }
    } catch (error) {
      toast({
        title: "테스트 오류",
        description: error instanceof Error ? error.message : "알 수 없는 오류",
        variant: "destructive",
      });
    } finally {
      setTesting(false);
    }
  };

  // 저장
  const handleSave = async () => {
    // 유효성 검증
    if (!connectionName.trim()) {
      toast({
        title: "입력 오류",
        description: "연결명을 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    if (!baseUrl.trim()) {
      toast({
        title: "입력 오류",
        description: "기본 URL을 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    // URL 형식 검증
    try {
      new URL(baseUrl);
    } catch {
      toast({
        title: "입력 오류",
        description: "올바른 URL 형식이 아닙니다.",
        variant: "destructive",
      });
      return;
    }

    // JSON 유효성 검증
    if (defaultBody && defaultMethod !== "GET" && defaultMethod !== "DELETE") {
      try {
        JSON.parse(defaultBody);
      } catch {
        toast({
          title: "입력 오류",
          description: "기본 Body가 올바른 JSON 형식이 아닙니다.",
          variant: "destructive",
        });
        return;
      }
    }

    setSaving(true);

    try {
      const data: ExternalRestApiConnection = {
        connection_name: connectionName,
        description: description || undefined,
        base_url: baseUrl,
        endpoint_path: endpointPath || undefined,
        default_headers: defaultHeaders,
        default_method: defaultMethod,
        default_body: defaultBody.trim() || null, // 빈 문자열이면 null로 전송하여 DB 업데이트
        auth_type: authType,
        auth_config: authType === "none" ? undefined : authConfig,
        timeout,
        retry_count: retryCount,
        retry_delay: retryDelay,
        // company_code는 백엔드에서 로그인 사용자의 company_code로 자동 설정
        is_active: isActive ? "Y" : "N",
        save_to_history: saveToHistory ? "Y" : "N",
      };

      console.log("저장하려는 데이터:", {
        connection_name: connectionName,
        default_method: defaultMethod,
        endpoint_path: endpointPath,
        base_url: baseUrl,
      });

      if (connection?.id) {
        await ExternalRestApiConnectionAPI.updateConnection(connection.id, data);
        toast({
          title: "수정 완료",
          description: "연결이 수정되었습니다.",
        });
      } else {
        await ExternalRestApiConnectionAPI.createConnection(data);
        toast({
          title: "생성 완료",
          description: "연결이 생성되었습니다.",
        });
      }

      onSave();
      onClose();
    } catch (error) {
      toast({
        title: "저장 실패",
        description: error instanceof Error ? error.message : "알 수 없는 오류",
        variant: "destructive",
      });
    } finally {
      setSaving(false);
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="flex max-h-[90vh] max-w-3xl flex-col">
        <DialogHeader className="flex-shrink-0">
          <DialogTitle>{connection ? "REST API 연결 수정" : "새 REST API 연결 추가"}</DialogTitle>
        </DialogHeader>

        <div className="flex-1 space-y-6 overflow-y-auto py-4 pr-2">
          {/* 기본 정보 */}
          <div className="space-y-4">
            <h3 className="text-sm font-semibold">기본 정보</h3>

            <div className="space-y-2">
              <Label htmlFor="connection-name">
                연결명 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="connection-name"
                value={connectionName}
                onChange={(e) => setConnectionName(e.target.value)}
                placeholder="예: 날씨 API"
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="description">설명</Label>
              <Textarea
                id="description"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="연결에 대한 설명을 입력하세요"
                rows={2}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="base-url">
                기본 URL <span className="text-destructive">*</span>
              </Label>
              <div className="flex gap-2">
                <Select 
                  value={defaultMethod} 
                  onValueChange={(val) => { 
                    setDefaultMethod(val);
                    setTestMethod(val); // 테스트 Method도 동기화
                  }}
                >
                  <SelectTrigger className="w-[100px]">
                    <SelectValue placeholder="Method" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="GET">GET</SelectItem>
                    <SelectItem value="POST">POST</SelectItem>
                    <SelectItem value="PUT">PUT</SelectItem>
                    <SelectItem value="DELETE">DELETE</SelectItem>
                    <SelectItem value="PATCH">PATCH</SelectItem>
                  </SelectContent>
                </Select>
                <div className="flex-1">
                  <Input
                    id="base-url"
                    value={baseUrl}
                    onChange={(e) => setBaseUrl(e.target.value)}
                    placeholder="https://api.example.com"
                  />
                </div>
              </div>
              <p className="text-muted-foreground text-xs">
                도메인 부분만 입력하세요 (예: https://apihub.kma.go.kr)
              </p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="endpoint-path">엔드포인트 경로</Label>
              <Input
                id="endpoint-path"
                value={endpointPath}
                onChange={(e) => setEndpointPath(e.target.value)}
                placeholder="/api/typ01/url/wrn_now_data.php"
              />
              <p className="text-muted-foreground text-xs">
                API 엔드포인트 경로를 입력하세요 (선택사항)
              </p>
            </div>

            {/* 기본 Body (POST, PUT, PATCH일 때만 표시) */}
            {(defaultMethod === "POST" || defaultMethod === "PUT" || defaultMethod === "PATCH") && (
              <div className="space-y-2">
                <Label htmlFor="default-body">기본 Request Body (JSON)</Label>
                <Textarea
                  id="default-body"
                  value={defaultBody}
                  onChange={(e) => setDefaultBody(e.target.value)}
                  placeholder='{"key": "value"}'
                  className="font-mono text-xs"
                  rows={5}
                />
              </div>
            )}

            <div className="flex items-center space-x-2">
              <Switch id="is-active" checked={isActive} onCheckedChange={setIsActive} />
              <Label htmlFor="is-active" className="cursor-pointer">
                활성 상태
              </Label>
            </div>

          </div>

          {/* 헤더 관리 */}
          <div className="space-y-4">
            <h3 className="text-sm font-semibold">헤더 설정</h3>
            <HeadersManager headers={defaultHeaders} onChange={setDefaultHeaders} />
          </div>

          {/* 인증 설정 */}
          <div className="space-y-4">
            <h3 className="text-sm font-semibold">인증 설정</h3>
            <AuthenticationConfig
              authType={authType}
              authConfig={authConfig}
              onAuthTypeChange={setAuthType}
              onAuthConfigChange={setAuthConfig}
            />
          </div>

          {/* 고급 설정 */}
          <div className="space-y-4">
            <button
              type="button"
              onClick={() => setShowAdvanced(!showAdvanced)}
              className="hover:text-primary flex items-center space-x-2 text-sm font-semibold transition-colors"
            >
              <span>고급 설정</span>
              {showAdvanced ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
            </button>

            {showAdvanced && (
              <div className="bg-muted space-y-4 rounded-md border p-4">
                <div className="grid grid-cols-3 gap-4">
                  <div className="space-y-2">
                    <Label htmlFor="timeout">타임아웃 (ms)</Label>
                    <Input
                      id="timeout"
                      type="number"
                      value={timeout}
                      onChange={(e) => setTimeout(parseInt(e.target.value) || 30000)}
                      min={1000}
                      max={120000}
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor="retry-count">재시도 횟수</Label>
                    <Input
                      id="retry-count"
                      type="number"
                      value={retryCount}
                      onChange={(e) => setRetryCount(parseInt(e.target.value) || 0)}
                      min={0}
                      max={5}
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor="retry-delay">재시도 간격 (ms)</Label>
                    <Input
                      id="retry-delay"
                      type="number"
                      value={retryDelay}
                      onChange={(e) => setRetryDelay(parseInt(e.target.value) || 1000)}
                      min={100}
                      max={10000}
                    />
                  </div>
                </div>
              </div>
            )}
          </div>

          {/* 연결 테스트 */}
          <div className="space-y-4">
            <h3 className="text-sm font-semibold">연결 테스트</h3>

            <div className="space-y-2">
              <Label htmlFor="test-endpoint">테스트 설정</Label>
              <div className="flex gap-2 mb-2">
                <Select value={testMethod} onValueChange={setTestMethod}>
                  <SelectTrigger className="w-[100px]">
                    <SelectValue placeholder="Method" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="GET">GET</SelectItem>
                    <SelectItem value="POST">POST</SelectItem>
                    <SelectItem value="PUT">PUT</SelectItem>
                    <SelectItem value="DELETE">DELETE</SelectItem>
                    <SelectItem value="PATCH">PATCH</SelectItem>
                  </SelectContent>
                </Select>
                <div className="flex-1">
                  <Input
                    id="test-endpoint"
                    value={testEndpoint}
                    onChange={(e) => setTestEndpoint(e.target.value)}
                    placeholder="엔드포인트 (예: /users/1)"
                  />
                </div>
              </div>

              {(testMethod === "POST" || testMethod === "PUT" || testMethod === "PATCH") && (
                <div className="mt-2">
                  <Label htmlFor="test-body" className="text-xs text-muted-foreground mb-1 block">
                    Test Request Body (JSON)
                  </Label>
                  <Textarea
                    id="test-body"
                    value={testBody}
                    onChange={(e) => setTestBody(e.target.value)}
                    placeholder='{"test": "data"}'
                    className="font-mono text-xs"
                    rows={3}
                  />
                </div>
              )}
            </div>

            <Button type="button" variant="outline" onClick={handleTest} disabled={testing}>
              <TestTube className="mr-2 h-4 w-4" />
              {testing ? "테스트 중..." : "연결 테스트"}
            </Button>

            {/* 테스트 요청 정보 표시 */}
            {testRequestUrl && (
              <div className="bg-muted/30 space-y-3 rounded-md border p-3">
                <div>
                  <div className="text-muted-foreground mb-1 text-xs font-medium">테스트 요청</div>
                  <div className="flex items-center gap-2 mb-1">
                    <Badge variant="outline">{testMethod}</Badge>
                    <code className="text-foreground text-xs break-all">{testRequestUrl}</code>
                  </div>
                </div>

                {testBody && (testMethod === "POST" || testMethod === "PUT" || testMethod === "PATCH") && (
                   <div>
                    <div className="text-muted-foreground mb-1 text-xs font-medium">Request Body</div>
                    <pre className="bg-muted p-2 rounded text-xs overflow-auto max-h-[100px]">
                      {testBody}
                    </pre>
                  </div>
                )}

                {Object.keys(defaultHeaders).length > 0 && (
                  <div>
                    <div className="text-muted-foreground mb-1 text-xs font-medium">요청 헤더</div>
                    <div className="space-y-1">
                      {Object.entries(defaultHeaders).map(([key, value]) => (
                        <code key={key} className="text-foreground block text-xs">
                          {key}: {value}
                        </code>
                      ))}
                    </div>
                  </div>
                )}

                {authType !== "none" && (
                  <div>
                    <div className="text-muted-foreground mb-1 text-xs font-medium">인증 방식</div>
                    <code className="text-foreground block text-xs">
                      {authType === "api-key" && "API Key"}
                      {authType === "bearer" && "Bearer Token"}
                      {authType === "basic" && "Basic Auth"}
                      {authType === "oauth2" && "OAuth 2.0"}
                    </code>
                  </div>
                )}
              </div>
            )}

            {testResult && (
              <div
                className={`rounded-md border p-4 ${
                  testResult.success ? "border-emerald-200 bg-emerald-50" : "border-destructive/20 bg-destructive/10"
                }`}
              >
                <div className="mb-2 flex items-center justify-between">
                  <Badge variant={testResult.success ? "default" : "destructive"}>
                    {testResult.success ? "성공" : "실패"}
                  </Badge>
                  {testResult.response_time && (
                    <span className="text-sm text-muted-foreground">응답 시간: {testResult.response_time}ms</span>
                  )}
                </div>

                <p className="text-sm">{testResult.message}</p>

                {testResult.status_code && (
                  <p className="mt-1 text-xs text-muted-foreground">상태 코드: {testResult.status_code}</p>
                )}

                {testResult.error_details && <p className="mt-2 text-xs text-destructive">{testResult.error_details}</p>}
              </div>
            )}
          </div>
        </div>

        <DialogFooter className="flex-shrink-0 border-t pt-4">
          <Button type="button" variant="outline" onClick={onClose}>
            <X className="mr-2 h-4 w-4" />
            취소
          </Button>
          <Button type="button" onClick={handleSave} disabled={saving}>
            <Save className="mr-2 h-4 w-4" />
            {saving ? "저장 중..." : connection ? "수정" : "생성"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
