"use client";

import React, { useState, useCallback, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import {
  Globe,
  Key,
  Clock,
  RefreshCw,
  ChevronDown,
  ChevronRight,
  Plus,
  Trash2,
  Copy,
  Eye,
  EyeOff,
  AlertCircle,
  CheckCircle,
} from "lucide-react";

// 타입 import
import { RestApiSettings as RestApiSettingsType, RestApiSettingsProps } from "@/types/external-call/ExternalCallTypes";
import {
  HttpMethod,
  AuthenticationType,
  COMMON_HEADER_PRESETS,
  JSON_BODY_TEMPLATES,
  DEFAULT_RETRY_POLICY,
  DEFAULT_TIMEOUT_CONFIG,
} from "@/types/external-call/RestApiTypes";

/**
 * 🔧 REST API 전용 설정 컴포넌트
 *
 * URL, HTTP 메서드, 헤더, 인증, 바디 템플릿 등
 * REST API 호출에 필요한 모든 설정을 관리
 */
const RestApiSettings: React.FC<RestApiSettingsProps> = ({ settings, onSettingsChange, readonly = false }) => {
  // 상태 관리
  const [activeTab, setActiveTab] = useState<string>("basic");
  const [showPassword, setShowPassword] = useState<boolean>(false);
  const [isAdvancedOpen, setIsAdvancedOpen] = useState<boolean>(false);
  const [validationErrors, setValidationErrors] = useState<string[]>([]);
  const [newHeaderKey, setNewHeaderKey] = useState<string>("");
  const [newHeaderValue, setNewHeaderValue] = useState<string>("");

  // URL 변경 핸들러
  const handleUrlChange = useCallback(
    (url: string) => {
      onSettingsChange({
        ...settings,
        apiUrl: url,
      });
    },
    [settings, onSettingsChange],
  );

  // HTTP 메서드 변경 핸들러
  const handleMethodChange = useCallback(
    (method: HttpMethod) => {
      onSettingsChange({
        ...settings,
        httpMethod: method,
      });
    },
    [settings, onSettingsChange],
  );

  // 헤더 추가 핸들러
  const handleAddHeader = useCallback(() => {
    if (newHeaderKey && newHeaderValue) {
      onSettingsChange({
        ...settings,
        headers: {
          ...settings.headers,
          [newHeaderKey]: newHeaderValue,
        },
      });
      setNewHeaderKey("");
      setNewHeaderValue("");
    }
  }, [settings, onSettingsChange, newHeaderKey, newHeaderValue]);

  // 헤더 삭제 핸들러
  const handleRemoveHeader = useCallback(
    (key: string) => {
      const newHeaders = { ...settings.headers };
      delete newHeaders[key];
      onSettingsChange({
        ...settings,
        headers: newHeaders,
      });
    },
    [settings, onSettingsChange],
  );

  // 헤더 프리셋 적용 핸들러
  const handleApplyHeaderPreset = useCallback(
    (presetName: string) => {
      const preset = COMMON_HEADER_PRESETS.find((p) => p.name === presetName);
      if (preset) {
        onSettingsChange({
          ...settings,
          headers: {
            ...settings.headers,
            ...preset.headers,
          },
        });
      }
    },
    [settings, onSettingsChange],
  );

  // 바디 템플릿 변경 핸들러
  const handleBodyTemplateChange = useCallback(
    (template: string) => {
      onSettingsChange({
        ...settings,
        bodyTemplate: template,
      });
    },
    [settings, onSettingsChange],
  );

  // 바디 템플릿 프리셋 적용 핸들러
  const handleApplyBodyPreset = useCallback(
    (presetKey: string) => {
      const preset = JSON_BODY_TEMPLATES[presetKey as keyof typeof JSON_BODY_TEMPLATES];
      if (preset) {
        onSettingsChange({
          ...settings,
          bodyTemplate: preset.template,
        });
      }
    },
    [settings, onSettingsChange],
  );

  // 인증 설정 변경 핸들러
  const handleAuthChange = useCallback(
    (auth: Partial<AuthenticationType>) => {
      onSettingsChange({
        ...settings,
        authentication: {
          ...settings.authentication,
          ...auth,
        } as AuthenticationType,
      });
    },
    [settings, onSettingsChange],
  );

  // 타임아웃 변경 핸들러 (초 단위를 밀리초로 변환)
  const handleTimeoutChange = useCallback(
    (timeoutInSeconds: number) => {
      onSettingsChange({
        ...settings,
        timeout: timeoutInSeconds * 1000, // 초를 밀리초로 변환
      });
    },
    [settings, onSettingsChange],
  );

  // 재시도 횟수 변경 핸들러
  const handleRetryCountChange = useCallback(
    (retryCount: number) => {
      onSettingsChange({
        ...settings,
        retryCount,
      });
    },
    [settings, onSettingsChange],
  );

  // 설정 유효성 검사
  const validateSettings = useCallback(() => {
    const errors: string[] = [];

    // URL 검증
    if (!settings.apiUrl) {
      errors.push("API URL은 필수입니다.");
    } else if (!settings.apiUrl.startsWith("http")) {
      errors.push("API URL은 http:// 또는 https://로 시작해야 합니다.");
    }

    // 바디 템플릿 JSON 검증 (POST/PUT/PATCH 메서드인 경우)
    if (["POST", "PUT", "PATCH"].includes(settings.httpMethod) && settings.bodyTemplate) {
      try {
        // 템플릿 변수를 임시 값으로 치환하여 JSON 유효성 검사
        const testTemplate = settings.bodyTemplate.replace(/\{\{[^}]+\}\}/g, '"test_value"');
        JSON.parse(testTemplate);
      } catch {
        errors.push("요청 바디 템플릿이 유효한 JSON 형식이 아닙니다.");
      }
    }

    // 인증 설정 검증
    if (settings.authentication?.type === "bearer" && !settings.authentication.token) {
      errors.push("Bearer 토큰이 필요합니다.");
    }
    if (
      settings.authentication?.type === "basic" &&
      (!settings.authentication.username || !settings.authentication.password)
    ) {
      errors.push("Basic 인증에는 사용자명과 비밀번호가 필요합니다.");
    }
    if (settings.authentication?.type === "api-key" && !settings.authentication.apiKey) {
      errors.push("API 키가 필요합니다.");
    }

    setValidationErrors(errors);
    return errors.length === 0;
  }, [settings]);

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

  return (
    <div className="space-y-4">
      {/* 유효성 검사 오류 표시 */}
      {validationErrors.length > 0 && (
        <Alert variant="destructive">
          <AlertCircle className="h-4 w-4" />
          <AlertDescription>
            <div className="space-y-1">
              {validationErrors.map((error, index) => (
                <div key={index} className="text-sm">
                  • {error}
                </div>
              ))}
            </div>
          </AlertDescription>
        </Alert>
      )}

      <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="basic">기본 설정</TabsTrigger>
          <TabsTrigger value="headers">헤더</TabsTrigger>
          <TabsTrigger value="body">요청 바디</TabsTrigger>
          <TabsTrigger value="auth">인증</TabsTrigger>
        </TabsList>

        {/* 기본 설정 탭 */}
        <TabsContent value="basic" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-base">
                <Globe className="h-4 w-4" />
                기본 설정
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              {/* API URL */}
              <div className="space-y-2">
                <Label htmlFor="apiUrl">API URL *</Label>
                <Input
                  id="apiUrl"
                  type="url"
                  placeholder="https://api.example.com/webhook"
                  value={settings.apiUrl}
                  onChange={(e) => handleUrlChange(e.target.value)}
                  disabled={readonly}
                  className={validationErrors.some((e) => e.includes("URL")) ? "border-destructive" : ""}
                />
                <div className="text-muted-foreground text-xs">호출할 API의 전체 URL을 입력하세요.</div>
              </div>

              {/* HTTP 메서드 */}
              <div className="space-y-2">
                <Label htmlFor="httpMethod">HTTP 메서드</Label>
                <Select value={settings.httpMethod} onValueChange={handleMethodChange} disabled={readonly}>
                  <SelectTrigger>
                    <SelectValue />
                  </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>

              {/* 고급 설정 (접을 수 있는 섹션) */}
              <Collapsible open={isAdvancedOpen} onOpenChange={setIsAdvancedOpen}>
                <CollapsibleTrigger asChild>
                  <Button variant="ghost" className="h-auto w-full justify-between p-0">
                    <span className="flex items-center gap-2">
                      <Clock className="h-4 w-4" />
                      고급 설정
                    </span>
                    {isAdvancedOpen ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
                  </Button>
                </CollapsibleTrigger>
                <CollapsibleContent className="mt-4 space-y-4">
                  <div className="grid grid-cols-2 gap-4">
                    {/* 타임아웃 */}
                    <div className="space-y-2">
                      <Label htmlFor="timeout">타임아웃 (초)</Label>
                      <Input
                        id="timeout"
                        type="number"
                        min="1"
                        max="300"
                        value={Math.round((settings.timeout || DEFAULT_TIMEOUT_CONFIG.request) / 1000)}
                        onChange={(e) => handleTimeoutChange(parseInt(e.target.value))}
                        disabled={readonly}
                      />
                    </div>

                    {/* 재시도 횟수 */}
                    <div className="space-y-2">
                      <Label htmlFor="retryCount">재시도 횟수</Label>
                      <Input
                        id="retryCount"
                        type="number"
                        min="0"
                        max="10"
                        value={settings.retryCount || DEFAULT_RETRY_POLICY.maxRetries}
                        onChange={(e) => handleRetryCountChange(parseInt(e.target.value))}
                        disabled={readonly}
                      />
                    </div>
                  </div>
                </CollapsibleContent>
              </Collapsible>
            </CardContent>
          </Card>
        </TabsContent>

        {/* 헤더 탭 */}
        <TabsContent value="headers" className="space-y-4">
          <Card>
            <CardHeader>
              <div className="flex items-center justify-between">
                <CardTitle className="text-base">HTTP 헤더</CardTitle>
                <div className="flex gap-2">
                  {COMMON_HEADER_PRESETS.map((preset) => (
                    <Button
                      key={preset.name}
                      variant="outline"
                      size="sm"
                      onClick={() => handleApplyHeaderPreset(preset.name)}
                      disabled={readonly}
                      className="text-xs"
                    >
                      {preset.name}
                    </Button>
                  ))}
                </div>
              </div>
            </CardHeader>
            <CardContent className="space-y-4">
              {/* 기존 헤더 목록 */}
              <div className="space-y-2">
                {Object.entries(settings.headers).map(([key, value]) => (
                  <div key={key} className="bg-muted flex items-center gap-2 rounded p-2">
                    <div className="grid flex-1 grid-cols-2 gap-2">
                      <Input value={key} disabled className="bg-background" />
                      <Input value={value} disabled className="bg-background" />
                    </div>
                    {!readonly && (
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => handleRemoveHeader(key)}
                        className="text-destructive hover:text-destructive"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    )}
                  </div>
                ))}
              </div>

              {/* 새 헤더 추가 */}
              {!readonly && (
                <div className="space-y-2">
                  <Label>새 헤더 추가</Label>
                  <div className="flex gap-2">
                    <Input
                      placeholder="헤더명 (예: X-API-Key)"
                      value={newHeaderKey}
                      onChange={(e) => setNewHeaderKey(e.target.value)}
                    />
                    <Input
                      placeholder="헤더값"
                      value={newHeaderValue}
                      onChange={(e) => setNewHeaderValue(e.target.value)}
                    />
                    <Button onClick={handleAddHeader} disabled={!newHeaderKey || !newHeaderValue}>
                      <Plus className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        {/* 요청 바디 탭 */}
        <TabsContent value="body" className="space-y-4">
          <Card>
            <CardHeader>
              <div className="flex items-center justify-between">
                <CardTitle className="text-base">요청 바디 템플릿</CardTitle>
                <div className="flex gap-2">
                  {Object.entries(JSON_BODY_TEMPLATES).map(([key, template]) => (
                    <Button
                      key={key}
                      variant="outline"
                      size="sm"
                      onClick={() => handleApplyBodyPreset(key)}
                      disabled={readonly}
                      className="text-xs"
                    >
                      {template.name}
                    </Button>
                  ))}
                </div>
              </div>
            </CardHeader>
            <CardContent className="space-y-4">
              {["POST", "PUT", "PATCH"].includes(settings.httpMethod) ? (
                <>
                  <Textarea
                    placeholder="JSON 템플릿을 입력하세요..."
                    value={settings.bodyTemplate}
                    onChange={(e) => handleBodyTemplateChange(e.target.value)}
                    disabled={readonly}
                    className="min-h-[200px] font-mono text-sm"
                  />

                  <Alert>
                    <AlertCircle className="h-4 w-4" />
                    <AlertDescription className="text-sm">
                      템플릿 변수를 사용할 수 있습니다: {"{{sourceData}}"}, {"{{timestamp}}"}, {"{{relationshipId}}"} 등
                    </AlertDescription>
                  </Alert>
                </>
              ) : (
                <Alert>
                  <AlertCircle className="h-4 w-4" />
                  <AlertDescription>{settings.httpMethod} 메서드는 요청 바디를 사용하지 않습니다.</AlertDescription>
                </Alert>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        {/* 인증 탭 */}
        <TabsContent value="auth" className="space-y-4">
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2 text-base">
                <Key className="h-4 w-4" />
                인증 설정
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-4">
              {/* 인증 타입 선택 */}
              <div className="space-y-2">
                <Label>인증 방식</Label>
                <Select
                  value={settings.authentication?.type || "none"}
                  onValueChange={(type) => handleAuthChange({ type: type as AuthenticationType["type"] })}
                  disabled={readonly}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">인증 없음</SelectItem>
                    <SelectItem value="bearer">Bearer Token</SelectItem>
                    <SelectItem value="basic">Basic Authentication</SelectItem>
                    <SelectItem value="api-key">API Key</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              {/* 인증 타입별 설정 */}
              {settings.authentication?.type === "bearer" && (
                <div className="space-y-2">
                  <Label htmlFor="bearerToken">Bearer Token *</Label>
                  <div className="relative">
                    <Input
                      id="bearerToken"
                      type={showPassword ? "text" : "password"}
                      placeholder="토큰을 입력하세요"
                      value={settings.authentication.token || ""}
                      onChange={(e) => handleAuthChange({ token: e.target.value })}
                      disabled={readonly}
                      className="pr-10"
                    />
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      className="absolute top-0 right-0 h-full px-3"
                      onClick={() => setShowPassword(!showPassword)}
                    >
                      {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                    </Button>
                  </div>
                </div>
              )}

              {settings.authentication?.type === "basic" && (
                <div className="grid grid-cols-2 gap-4">
                  <div className="space-y-2">
                    <Label htmlFor="username">사용자명 *</Label>
                    <Input
                      id="username"
                      placeholder="사용자명"
                      value={settings.authentication.username || ""}
                      onChange={(e) => handleAuthChange({ username: e.target.value })}
                      disabled={readonly}
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="password">비밀번호 *</Label>
                    <div className="relative">
                      <Input
                        id="password"
                        type={showPassword ? "text" : "password"}
                        placeholder="비밀번호"
                        value={settings.authentication.password || ""}
                        onChange={(e) => handleAuthChange({ password: e.target.value })}
                        disabled={readonly}
                        className="pr-10"
                      />
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        className="absolute top-0 right-0 h-full px-3"
                        onClick={() => setShowPassword(!showPassword)}
                      >
                        {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                      </Button>
                    </div>
                  </div>
                </div>
              )}

              {settings.authentication?.type === "api-key" && (
                <div className="space-y-4">
                  <div className="space-y-2">
                    <Label htmlFor="apiKey">API Key *</Label>
                    <div className="relative">
                      <Input
                        id="apiKey"
                        type={showPassword ? "text" : "password"}
                        placeholder="API 키를 입력하세요"
                        value={settings.authentication.apiKey || ""}
                        onChange={(e) => handleAuthChange({ apiKey: e.target.value })}
                        disabled={readonly}
                        className="pr-10"
                      />
                      <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        className="absolute top-0 right-0 h-full px-3"
                        onClick={() => setShowPassword(!showPassword)}
                      >
                        {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                      </Button>
                    </div>
                  </div>

                  <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-2">
                      <Label>위치</Label>
                      <Select
                        value={settings.authentication.apiKeyLocation || "header"}
                        onValueChange={(location) =>
                          handleAuthChange({
                            apiKeyLocation: location as "header" | "query",
                          })
                        }
                        disabled={readonly}
                      >
                        <SelectTrigger>
                          <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="header">HTTP 헤더</SelectItem>
                          <SelectItem value="query">쿼리 파라미터</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>

                    <div className="space-y-2">
                      <Label htmlFor="keyName">키 이름</Label>
                      <Input
                        id="keyName"
                        placeholder={settings.authentication.apiKeyLocation === "query" ? "api_key" : "X-API-Key"}
                        value={settings.authentication.apiKeyHeader || settings.authentication.apiKeyQueryParam || ""}
                        onChange={(e) => {
                          if (settings.authentication?.apiKeyLocation === "query") {
                            handleAuthChange({ apiKeyQueryParam: e.target.value });
                          } else {
                            handleAuthChange({ apiKeyHeader: e.target.value });
                          }
                        }}
                        disabled={readonly}
                      />
                    </div>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>

      {/* 설정 상태 표시 */}
      <Card>
        <CardContent className="pt-6">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              {validationErrors.length === 0 ? (
                <>
                  <CheckCircle className="h-4 w-4 text-emerald-500" />
                  <span className="text-sm text-emerald-600">설정이 완료되었습니다</span>
                </>
              ) : (
                <>
                  <AlertCircle className="h-4 w-4 text-amber-500" />
                  <span className="text-sm text-amber-600">{validationErrors.length}개의 설정이 필요합니다</span>
                </>
              )}
            </div>

            <Badge variant={validationErrors.length === 0 ? "default" : "secondary"}>
              {validationErrors.length === 0 ? "완료" : "미완료"}
            </Badge>
          </div>
        </CardContent>
      </Card>
    </div>
  );
};

export default RestApiSettings;
