"use client";

import React, { useState } from "react";
import { ChartDataSource, QueryResult, ApiResponse } from "../types";
import { Card } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Plus, X, Play, AlertCircle } from "lucide-react";

interface ApiConfigProps {
  dataSource: ChartDataSource;
  onChange: (updates: Partial<ChartDataSource>) => void;
  onTestResult?: (result: QueryResult) => void;
}

/**
 * REST API 설정 컴포넌트
 * - API 엔드포인트 설정
 * - 헤더 및 쿼리 파라미터 추가
 * - JSON Path 설정
 */
export function ApiConfig({ dataSource, onChange, onTestResult }: ApiConfigProps) {
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState<QueryResult | null>(null);
  const [testError, setTestError] = useState<string | null>(null);

  // 헤더 추가
  const addHeader = () => {
    const headers = dataSource.headers || {};
    const newKey = `header_${Object.keys(headers).length + 1}`;
    onChange({ headers: { ...headers, [newKey]: "" } });
  };

  // 헤더 제거
  const removeHeader = (key: string) => {
    const headers = { ...dataSource.headers };
    delete headers[key];
    onChange({ headers });
  };

  // 헤더 업데이트
  const updateHeader = (oldKey: string, newKey: string, value: string) => {
    const headers = { ...dataSource.headers };
    delete headers[oldKey];
    headers[newKey] = value;
    onChange({ headers });
  };

  // 쿼리 파라미터 추가
  const addQueryParam = () => {
    const queryParams = dataSource.queryParams || {};
    const newKey = `param_${Object.keys(queryParams).length + 1}`;
    onChange({ queryParams: { ...queryParams, [newKey]: "" } });
  };

  // 쿼리 파라미터 제거
  const removeQueryParam = (key: string) => {
    const queryParams = { ...dataSource.queryParams };
    delete queryParams[key];
    onChange({ queryParams });
  };

  // 쿼리 파라미터 업데이트
  const updateQueryParam = (oldKey: string, newKey: string, value: string) => {
    const queryParams = { ...dataSource.queryParams };
    delete queryParams[oldKey];
    queryParams[newKey] = value;
    onChange({ queryParams });
  };

  // API 테스트
  const testApi = async () => {
    if (!dataSource.endpoint) {
      setTestError("API URL을 입력하세요");
      return;
    }

    setTesting(true);
    setTestError(null);
    setTestResult(null);

    try {
      // 쿼리 파라미터 구성
      const params = new URLSearchParams();
      if (dataSource.queryParams) {
        Object.entries(dataSource.queryParams).forEach(([key, value]) => {
          if (key && value) {
            params.append(key, value);
          }
        });
      }

      const url = `http://localhost:8080/api/dashboards/fetch-api?${params.toString()}`;

      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${localStorage.getItem("token") || "test-token"}`,
        },
        body: JSON.stringify({
          endpoint: dataSource.endpoint,
          headers: dataSource.headers || {},
          jsonPath: dataSource.jsonPath || "",
        }),
      });

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

      const result: ApiResponse<QueryResult> = await response.json();

      if (!result.success) {
        throw new Error(result.message || "API 호출에 실패했습니다");
      }

      setTestResult(result.data);
      onTestResult?.(result.data);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : "알 수 없는 오류가 발생했습니다";
      setTestError(errorMessage);
    } finally {
      setTesting(false);
    }
  };

  return (
    <div className="space-y-4">
      <div>
        <h3 className="text-lg font-semibold text-gray-800">2단계: REST API 설정</h3>
        <p className="mt-1 text-sm text-gray-600">외부 API에서 데이터를 가져올 설정을 입력하세요</p>
      </div>

      {/* API URL */}
      <Card className="space-y-4 p-4">
        <div>
          <Label className="text-sm font-medium text-gray-700">API URL *</Label>
          <Input
            type="url"
            placeholder="https://api.example.com/data"
            value={dataSource.endpoint || ""}
            onChange={(e) => onChange({ endpoint: e.target.value })}
            className="mt-2"
          />
          <p className="mt-1 text-xs text-gray-500">GET 요청을 보낼 API 엔드포인트</p>
        </div>

        {/* HTTP 메서드 (고정) */}
        <div>
          <Label className="text-sm font-medium text-gray-700">HTTP 메서드</Label>
          <div className="mt-2 rounded border border-gray-300 bg-gray-100 p-2 text-sm text-gray-700">GET (고정)</div>
          <p className="mt-1 text-xs text-gray-500">데이터 조회는 GET 메서드만 지원합니다</p>
        </div>
      </Card>

      {/* 쿼리 파라미터 */}
      <Card className="space-y-4 p-4">
        <div className="flex items-center justify-between">
          <Label className="text-sm font-medium text-gray-700">URL 쿼리 파라미터</Label>
          <Button variant="outline" size="sm" onClick={addQueryParam}>
            <Plus className="mr-1 h-3 w-3" />
            추가
          </Button>
        </div>

        {dataSource.queryParams && Object.keys(dataSource.queryParams).length > 0 ? (
          <div className="space-y-2">
            {Object.entries(dataSource.queryParams).map(([key, value]) => (
              <div key={key} className="flex gap-2">
                <Input
                  placeholder="key"
                  value={key}
                  onChange={(e) => updateQueryParam(key, e.target.value, value)}
                  className="flex-1"
                />
                <Input
                  placeholder="value"
                  value={value}
                  onChange={(e) => updateQueryParam(key, key, e.target.value)}
                  className="flex-1"
                />
                <Button variant="ghost" size="icon" onClick={() => removeQueryParam(key)}>
                  <X className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
        ) : (
          <p className="py-2 text-center text-sm text-gray-500">추가된 파라미터가 없습니다</p>
        )}

        <p className="text-xs text-gray-500">예: category=electronics, limit=10</p>
      </Card>

      {/* 헤더 */}
      <Card className="space-y-4 p-4">
        <div className="flex items-center justify-between">
          <Label className="text-sm font-medium text-gray-700">요청 헤더</Label>
          <Button variant="outline" size="sm" onClick={addHeader}>
            <Plus className="mr-1 h-3 w-3" />
            추가
          </Button>
        </div>

        {/* 빠른 헤더 템플릿 */}
        <div className="flex flex-wrap gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              onChange({
                headers: { ...dataSource.headers, Authorization: "Bearer YOUR_TOKEN" },
              });
            }}
          >
            + Authorization
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => {
              onChange({
                headers: { ...dataSource.headers, "Content-Type": "application/json" },
              });
            }}
          >
            + Content-Type
          </Button>
        </div>

        {dataSource.headers && Object.keys(dataSource.headers).length > 0 ? (
          <div className="space-y-2">
            {Object.entries(dataSource.headers).map(([key, value]) => (
              <div key={key} className="flex gap-2">
                <Input
                  placeholder="Header Name"
                  value={key}
                  onChange={(e) => updateHeader(key, e.target.value, value)}
                  className="flex-1"
                />
                <Input
                  placeholder="Header Value"
                  value={value}
                  onChange={(e) => updateHeader(key, key, e.target.value)}
                  className="flex-1"
                  type={key.toLowerCase().includes("auth") ? "password" : "text"}
                />
                <Button variant="ghost" size="icon" onClick={() => removeHeader(key)}>
                  <X className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
        ) : (
          <p className="py-2 text-center text-sm text-gray-500">추가된 헤더가 없습니다</p>
        )}
      </Card>

      {/* JSON Path */}
      <Card className="space-y-2 p-4">
        <Label className="text-sm font-medium text-gray-700">JSON Path (선택)</Label>
        <Input
          placeholder="data.results"
          value={dataSource.jsonPath || ""}
          onChange={(e) => onChange({ jsonPath: e.target.value })}
        />
        <p className="text-xs text-gray-500">
          JSON 응답에서 데이터 배열의 경로 (예: data.results, items, response.data)
          <br />
          비워두면 전체 응답을 사용합니다
        </p>
      </Card>

      {/* 테스트 버튼 */}
      <div className="flex justify-end">
        <Button onClick={testApi} disabled={!dataSource.endpoint || testing}>
          {testing ? (
            <>
              <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
              테스트 중...
            </>
          ) : (
            <>
              <Play className="mr-2 h-4 w-4" />
              API 테스트
            </>
          )}
        </Button>
      </div>

      {/* 테스트 오류 */}
      {testError && (
        <Card className="border-red-200 bg-red-50 p-4">
          <div className="flex items-start gap-2">
            <AlertCircle className="mt-0.5 h-5 w-5 flex-shrink-0 text-red-600" />
            <div>
              <div className="text-sm font-medium text-red-800">API 호출 실패</div>
              <div className="mt-1 text-sm text-red-700">{testError}</div>
            </div>
          </div>
        </Card>
      )}

      {/* 테스트 결과 */}
      {testResult && (
        <Card className="border-green-200 bg-green-50 p-4">
          <div className="mb-2 text-sm font-medium text-green-800">✅ API 호출 성공</div>
          <div className="space-y-1 text-xs text-green-700">
            <div>총 {testResult.rows.length}개의 데이터를 불러왔습니다</div>
            <div>컬럼: {testResult.columns.join(", ")}</div>
          </div>
        </Card>
      )}
    </div>
  );
}
