"use client";

/**
 * HTTP 요청 노드 속성 편집
 */

import { useEffect, useState, useCallback } from "react";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Plus, Trash2, Globe, Key, FileJson, Settings } from "lucide-react";
import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import type { HttpRequestActionNodeData } from "@/types/node-editor";

interface HttpRequestActionPropertiesProps {
  nodeId: string;
  data: HttpRequestActionNodeData;
}

export function HttpRequestActionProperties({ nodeId, data }: HttpRequestActionPropertiesProps) {
  const { updateNode } = useFlowEditorStore();

  // 로컬 상태
  const [displayName, setDisplayName] = useState(data.displayName || "HTTP 요청");
  const [url, setUrl] = useState(data.url || "");
  const [method, setMethod] = useState<HttpRequestActionNodeData["method"]>(data.method || "GET");
  const [bodyType, setBodyType] = useState<HttpRequestActionNodeData["bodyType"]>(data.bodyType || "none");
  const [body, setBody] = useState(data.body || "");
  
  // 인증
  const [authType, setAuthType] = useState<NonNullable<HttpRequestActionNodeData["authentication"]>["type"]>(
    data.authentication?.type || "none"
  );
  const [authUsername, setAuthUsername] = useState(data.authentication?.username || "");
  const [authPassword, setAuthPassword] = useState(data.authentication?.password || "");
  const [authToken, setAuthToken] = useState(data.authentication?.token || "");
  const [authApiKey, setAuthApiKey] = useState(data.authentication?.apiKey || "");
  const [authApiKeyName, setAuthApiKeyName] = useState(data.authentication?.apiKeyName || "X-API-Key");
  const [authApiKeyLocation, setAuthApiKeyLocation] = useState<"header" | "query">(
    data.authentication?.apiKeyLocation || "header"
  );
  
  // 옵션
  const [timeout, setTimeout] = useState(data.options?.timeout?.toString() || "30000");
  const [followRedirects, setFollowRedirects] = useState(data.options?.followRedirects ?? true);
  const [retryCount, setRetryCount] = useState(data.options?.retryCount?.toString() || "0");
  const [retryDelay, setRetryDelay] = useState(data.options?.retryDelay?.toString() || "1000");
  
  // 헤더
  const [headers, setHeaders] = useState<Array<{ key: string; value: string }>>(
    Object.entries(data.headers || {}).map(([key, value]) => ({ key, value }))
  );
  
  // 쿼리 파라미터
  const [queryParams, setQueryParams] = useState<Array<{ key: string; value: string }>>(
    Object.entries(data.queryParams || {}).map(([key, value]) => ({ key, value }))
  );
  
  // 응답 처리
  const [extractPath, setExtractPath] = useState(data.responseHandling?.extractPath || "");
  const [saveToVariable, setSaveToVariable] = useState(data.responseHandling?.saveToVariable || "");

  // 데이터 변경 시 로컬 상태 동기화
  useEffect(() => {
    setDisplayName(data.displayName || "HTTP 요청");
    setUrl(data.url || "");
    setMethod(data.method || "GET");
    setBodyType(data.bodyType || "none");
    setBody(data.body || "");
    setAuthType(data.authentication?.type || "none");
    setAuthUsername(data.authentication?.username || "");
    setAuthPassword(data.authentication?.password || "");
    setAuthToken(data.authentication?.token || "");
    setAuthApiKey(data.authentication?.apiKey || "");
    setAuthApiKeyName(data.authentication?.apiKeyName || "X-API-Key");
    setAuthApiKeyLocation(data.authentication?.apiKeyLocation || "header");
    setTimeout(data.options?.timeout?.toString() || "30000");
    setFollowRedirects(data.options?.followRedirects ?? true);
    setRetryCount(data.options?.retryCount?.toString() || "0");
    setRetryDelay(data.options?.retryDelay?.toString() || "1000");
    setHeaders(Object.entries(data.headers || {}).map(([key, value]) => ({ key, value })));
    setQueryParams(Object.entries(data.queryParams || {}).map(([key, value]) => ({ key, value })));
    setExtractPath(data.responseHandling?.extractPath || "");
    setSaveToVariable(data.responseHandling?.saveToVariable || "");
  }, [data]);

  // 노드 업데이트 함수
  const updateNodeData = useCallback(
    (updates: Partial<HttpRequestActionNodeData>) => {
      updateNode(nodeId, {
        ...data,
        ...updates,
      });
    },
    [nodeId, data, updateNode]
  );

  // 표시명 변경
  const handleDisplayNameChange = (value: string) => {
    setDisplayName(value);
    updateNodeData({ displayName: value });
  };

  // URL 업데이트
  const updateUrl = () => {
    updateNodeData({ url });
  };

  // 메서드 변경
  const handleMethodChange = (value: HttpRequestActionNodeData["method"]) => {
    setMethod(value);
    updateNodeData({ method: value });
  };

  // 바디 타입 변경
  const handleBodyTypeChange = (value: HttpRequestActionNodeData["bodyType"]) => {
    setBodyType(value);
    updateNodeData({ bodyType: value });
  };

  // 바디 업데이트
  const updateBody = () => {
    updateNodeData({ body });
  };

  // 인증 업데이트
  const updateAuthentication = useCallback(() => {
    updateNodeData({
      authentication: {
        type: authType,
        username: authUsername || undefined,
        password: authPassword || undefined,
        token: authToken || undefined,
        apiKey: authApiKey || undefined,
        apiKeyName: authApiKeyName || undefined,
        apiKeyLocation: authApiKeyLocation,
      },
    });
  }, [authType, authUsername, authPassword, authToken, authApiKey, authApiKeyName, authApiKeyLocation, updateNodeData]);

  // 옵션 업데이트
  const updateOptions = useCallback(() => {
    updateNodeData({
      options: {
        timeout: parseInt(timeout) || 30000,
        followRedirects,
        retryCount: parseInt(retryCount) || 0,
        retryDelay: parseInt(retryDelay) || 1000,
      },
    });
  }, [timeout, followRedirects, retryCount, retryDelay, updateNodeData]);

  // 응답 처리 업데이트
  const updateResponseHandling = useCallback(() => {
    updateNodeData({
      responseHandling: {
        extractPath: extractPath || undefined,
        saveToVariable: saveToVariable || undefined,
      },
    });
  }, [extractPath, saveToVariable, updateNodeData]);

  // 헤더 추가
  const addHeader = () => {
    setHeaders([...headers, { key: "", value: "" }]);
  };

  // 헤더 삭제
  const removeHeader = (index: number) => {
    const newHeaders = headers.filter((_, i) => i !== index);
    setHeaders(newHeaders);
    const headersObj = Object.fromEntries(newHeaders.filter(h => h.key).map(h => [h.key, h.value]));
    updateNodeData({ headers: headersObj });
  };

  // 헤더 업데이트
  const updateHeader = (index: number, field: "key" | "value", value: string) => {
    const newHeaders = [...headers];
    newHeaders[index][field] = value;
    setHeaders(newHeaders);
  };

  // 헤더 저장
  const saveHeaders = () => {
    const headersObj = Object.fromEntries(headers.filter(h => h.key).map(h => [h.key, h.value]));
    updateNodeData({ headers: headersObj });
  };

  // 쿼리 파라미터 추가
  const addQueryParam = () => {
    setQueryParams([...queryParams, { key: "", value: "" }]);
  };

  // 쿼리 파라미터 삭제
  const removeQueryParam = (index: number) => {
    const newParams = queryParams.filter((_, i) => i !== index);
    setQueryParams(newParams);
    const paramsObj = Object.fromEntries(newParams.filter(p => p.key).map(p => [p.key, p.value]));
    updateNodeData({ queryParams: paramsObj });
  };

  // 쿼리 파라미터 업데이트
  const updateQueryParam = (index: number, field: "key" | "value", value: string) => {
    const newParams = [...queryParams];
    newParams[index][field] = value;
    setQueryParams(newParams);
  };

  // 쿼리 파라미터 저장
  const saveQueryParams = () => {
    const paramsObj = Object.fromEntries(queryParams.filter(p => p.key).map(p => [p.key, p.value]));
    updateNodeData({ queryParams: paramsObj });
  };

  return (
    <div className="space-y-4 p-4">
      {/* 표시명 */}
      <div className="space-y-2">
        <Label className="text-xs font-medium">표시명</Label>
        <Input
          value={displayName}
          onChange={(e) => handleDisplayNameChange(e.target.value)}
          placeholder="HTTP 요청"
          className="h-8 text-sm"
        />
      </div>

      {/* URL */}
      <div className="space-y-2">
        <Label className="text-xs font-medium">URL *</Label>
        <Input
          value={url}
          onChange={(e) => setUrl(e.target.value)}
          onBlur={updateUrl}
          placeholder="https://api.example.com/endpoint"
          className="h-8 text-sm"
        />
      </div>

      {/* 메서드 */}
      <div className="space-y-2">
        <Label className="text-xs font-medium">HTTP 메서드</Label>
        <Select value={method} onValueChange={handleMethodChange}>
          <SelectTrigger className="h-8 text-sm">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="GET">GET</SelectItem>
            <SelectItem value="POST">POST</SelectItem>
            <SelectItem value="PUT">PUT</SelectItem>
            <SelectItem value="PATCH">PATCH</SelectItem>
            <SelectItem value="DELETE">DELETE</SelectItem>
            <SelectItem value="HEAD">HEAD</SelectItem>
            <SelectItem value="OPTIONS">OPTIONS</SelectItem>
          </SelectContent>
        </Select>
      </div>

      <Tabs defaultValue="headers" className="w-full">
        <TabsList className="grid w-full grid-cols-4">
          <TabsTrigger value="headers" className="text-xs">
            <Globe className="mr-1 h-3 w-3" />
            헤더
          </TabsTrigger>
          <TabsTrigger value="body" className="text-xs">
            <FileJson className="mr-1 h-3 w-3" />
            바디
          </TabsTrigger>
          <TabsTrigger value="auth" className="text-xs">
            <Key className="mr-1 h-3 w-3" />
            인증
          </TabsTrigger>
          <TabsTrigger value="options" className="text-xs">
            <Settings className="mr-1 h-3 w-3" />
            옵션
          </TabsTrigger>
        </TabsList>

        {/* 헤더 탭 */}
        <TabsContent value="headers" className="space-y-3 pt-3">
          {/* 쿼리 파라미터 */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-xs">쿼리 파라미터</Label>
              <Button variant="outline" size="sm" className="h-6 text-xs" onClick={addQueryParam}>
                <Plus className="mr-1 h-3 w-3" />
                추가
              </Button>
            </div>
            {queryParams.map((param, index) => (
              <div key={index} className="flex gap-2">
                <Input
                  value={param.key}
                  onChange={(e) => updateQueryParam(index, "key", e.target.value)}
                  onBlur={saveQueryParams}
                  placeholder="파라미터명"
                  className="h-8 text-sm"
                />
                <Input
                  value={param.value}
                  onChange={(e) => updateQueryParam(index, "value", e.target.value)}
                  onBlur={saveQueryParams}
                  placeholder="값"
                  className="h-8 text-sm"
                />
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => removeQueryParam(index)}>
                  <Trash2 className="h-3 w-3 text-destructive" />
                </Button>
              </div>
            ))}
          </div>

          {/* 헤더 */}
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <Label className="text-xs">요청 헤더</Label>
              <Button variant="outline" size="sm" className="h-6 text-xs" onClick={addHeader}>
                <Plus className="mr-1 h-3 w-3" />
                추가
              </Button>
            </div>
            {headers.map((header, index) => (
              <div key={index} className="flex gap-2">
                <Input
                  value={header.key}
                  onChange={(e) => updateHeader(index, "key", e.target.value)}
                  onBlur={saveHeaders}
                  placeholder="헤더명"
                  className="h-8 text-sm"
                />
                <Input
                  value={header.value}
                  onChange={(e) => updateHeader(index, "value", e.target.value)}
                  onBlur={saveHeaders}
                  placeholder="값"
                  className="h-8 text-sm"
                />
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => removeHeader(index)}>
                  <Trash2 className="h-3 w-3 text-destructive" />
                </Button>
              </div>
            ))}
          </div>
        </TabsContent>

        {/* 바디 탭 */}
        <TabsContent value="body" className="space-y-3 pt-3">
          <div className="space-y-2">
            <Label className="text-xs">바디 타입</Label>
            <Select value={bodyType} onValueChange={handleBodyTypeChange}>
              <SelectTrigger className="h-8 text-sm">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none">없음</SelectItem>
                <SelectItem value="json">JSON</SelectItem>
                <SelectItem value="form">Form Data</SelectItem>
                <SelectItem value="text">텍스트</SelectItem>
              </SelectContent>
            </Select>
          </div>

          {bodyType !== "none" && (
            <div className="space-y-2">
              <Label className="text-xs">요청 바디</Label>
              <Textarea
                value={body}
                onChange={(e) => setBody(e.target.value)}
                onBlur={updateBody}
                placeholder={bodyType === "json" ? '{\n  "key": "value"\n}' : "바디 내용"}
                className="min-h-[200px] font-mono text-xs"
              />
            </div>
          )}

          <Card className="bg-muted">
            <CardContent className="p-3 text-xs text-muted-foreground">
              <div className="font-medium mb-1">템플릿 변수 사용:</div>
              <code className="block">{"{{sourceData}}"}</code>
              <code className="block">{"{{필드명}}"}</code>
            </CardContent>
          </Card>
        </TabsContent>

        {/* 인증 탭 */}
        <TabsContent value="auth" className="space-y-3 pt-3">
          <div className="space-y-2">
            <Label className="text-xs">인증 방식</Label>
            <Select value={authType} onValueChange={(v: any) => {
              setAuthType(v);
              updateNodeData({ authentication: { ...data.authentication, type: v } });
            }}>
              <SelectTrigger className="h-8 text-sm">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none">인증 없음</SelectItem>
                <SelectItem value="basic">Basic Auth</SelectItem>
                <SelectItem value="bearer">Bearer Token</SelectItem>
                <SelectItem value="apikey">API Key</SelectItem>
              </SelectContent>
            </Select>
          </div>

          {authType === "basic" && (
            <>
              <div className="space-y-2">
                <Label className="text-xs">사용자명</Label>
                <Input
                  value={authUsername}
                  onChange={(e) => setAuthUsername(e.target.value)}
                  onBlur={updateAuthentication}
                  placeholder="username"
                  className="h-8 text-sm"
                />
              </div>
              <div className="space-y-2">
                <Label className="text-xs">비밀번호</Label>
                <Input
                  type="password"
                  value={authPassword}
                  onChange={(e) => setAuthPassword(e.target.value)}
                  onBlur={updateAuthentication}
                  placeholder="password"
                  className="h-8 text-sm"
                />
              </div>
            </>
          )}

          {authType === "bearer" && (
            <div className="space-y-2">
              <Label className="text-xs">Bearer Token</Label>
              <Input
                value={authToken}
                onChange={(e) => setAuthToken(e.target.value)}
                onBlur={updateAuthentication}
                placeholder="your-token-here"
                className="h-8 text-sm"
              />
            </div>
          )}

          {authType === "apikey" && (
            <>
              <div className="space-y-2">
                <Label className="text-xs">API Key</Label>
                <Input
                  value={authApiKey}
                  onChange={(e) => setAuthApiKey(e.target.value)}
                  onBlur={updateAuthentication}
                  placeholder="your-api-key"
                  className="h-8 text-sm"
                />
              </div>
              <div className="space-y-2">
                <Label className="text-xs">헤더/파라미터 이름</Label>
                <Input
                  value={authApiKeyName}
                  onChange={(e) => setAuthApiKeyName(e.target.value)}
                  onBlur={updateAuthentication}
                  placeholder="X-API-Key"
                  className="h-8 text-sm"
                />
              </div>
              <div className="space-y-2">
                <Label className="text-xs">위치</Label>
                <Select value={authApiKeyLocation} onValueChange={(v: "header" | "query") => {
                  setAuthApiKeyLocation(v);
                  updateNodeData({
                    authentication: { ...data.authentication, type: authType, apiKeyLocation: v },
                  });
                }}>
                  <SelectTrigger className="h-8 text-sm">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="header">헤더</SelectItem>
                    <SelectItem value="query">쿼리 파라미터</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </>
          )}
        </TabsContent>

        {/* 옵션 탭 */}
        <TabsContent value="options" className="space-y-3 pt-3">
          <div className="space-y-2">
            <Label className="text-xs">타임아웃 (ms)</Label>
            <Input
              type="number"
              value={timeout}
              onChange={(e) => setTimeout(e.target.value)}
              onBlur={updateOptions}
              placeholder="30000"
              className="h-8 text-sm"
            />
          </div>

          <div className="flex items-center space-x-2">
            <Switch
              checked={followRedirects}
              onCheckedChange={(checked) => {
                setFollowRedirects(checked);
                updateNodeData({ options: { ...data.options, followRedirects: checked } });
              }}
            />
            <Label className="text-xs">리다이렉트 따라가기</Label>
          </div>

          <div className="grid grid-cols-2 gap-2">
            <div className="space-y-2">
              <Label className="text-xs">재시도 횟수</Label>
              <Input
                type="number"
                value={retryCount}
                onChange={(e) => setRetryCount(e.target.value)}
                onBlur={updateOptions}
                placeholder="0"
                className="h-8 text-sm"
              />
            </div>
            <div className="space-y-2">
              <Label className="text-xs">재시도 간격 (ms)</Label>
              <Input
                type="number"
                value={retryDelay}
                onChange={(e) => setRetryDelay(e.target.value)}
                onBlur={updateOptions}
                placeholder="1000"
                className="h-8 text-sm"
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label className="text-xs">응답 데이터 추출 경로 (JSONPath)</Label>
            <Input
              value={extractPath}
              onChange={(e) => setExtractPath(e.target.value)}
              onBlur={updateResponseHandling}
              placeholder="data.items"
              className="h-8 text-sm"
            />
          </div>

          <div className="space-y-2">
            <Label className="text-xs">결과 저장 변수명</Label>
            <Input
              value={saveToVariable}
              onChange={(e) => setSaveToVariable(e.target.value)}
              onBlur={updateResponseHandling}
              placeholder="apiResponse"
              className="h-8 text-sm"
            />
          </div>
        </TabsContent>
      </Tabs>
    </div>
  );
}

