"use client";

import { useState, useEffect, ChangeEvent } from "react";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Textarea } from "@/components/ui/textarea";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { ExternalDbConnectionAPI } from "@/lib/api/externalDbConnection";

interface TableColumn {
  column_name: string;
  data_type: string;
  is_nullable: string;
  column_default: string | null;
}

interface TableInfo {
  table_name: string;
  columns: TableColumn[];
  description: string | null;
}

interface QueryResult {
  [key: string]: string | number | boolean | null | undefined;
}

interface TableColumn {
  column_name: string;
  data_type: string;
  is_nullable: string;
  column_default: string | null;
}

interface TableInfo {
  table_name: string;
  columns: TableColumn[];
  description: string | null;
}

interface SqlQueryModalProps {
  isOpen: boolean;
  onClose: () => void;
  connectionId: number;
  connectionName: string;
}

export const SqlQueryModal: React.FC<SqlQueryModalProps> = ({ isOpen, onClose, connectionId, connectionName }) => {
  const { toast } = useToast();
  const [query, setQuery] = useState("SELECT * FROM ");
  const [results, setResults] = useState<QueryResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [tables, setTables] = useState<TableInfo[]>([]);
  const [selectedTable, setSelectedTable] = useState("");
  const [loadingTables, setLoadingTables] = useState(false);
  const [selectedTableColumns, setSelectedTableColumns] = useState<TableColumn[]>([]);
  const [loadingColumns, setLoadingColumns] = useState(false);

  // 테이블 목록 로딩
  useEffect(() => {
    console.log("SqlQueryModal - connectionId:", connectionId);
    const loadTables = async () => {
      setLoadingTables(true);
      try {
        const result = await ExternalDbConnectionAPI.getTables(connectionId);
        if (result.success && result.data) {
          setTables(result.data as unknown as TableInfo[]);
        }
      } catch (error) {
        console.error("테이블 목록 로딩 오류:", error);
        toast({
          title: "오류",
          description: "테이블 목록을 불러오는데 실패했습니다.",
          variant: "destructive",
        });
      } finally {
        setLoadingTables(false);
      }
    };
    loadTables();
  }, []);

  // 테이블 선택 시 컬럼 정보 로딩
  const loadTableColumns = async (tableName: string) => {
    if (!tableName) {
      setSelectedTableColumns([]);
      return;
    }

    setLoadingColumns(true);
    try {
      const result = await ExternalDbConnectionAPI.getTableColumns(connectionId, tableName);
      if (result.success && result.data) {
        setSelectedTableColumns(result.data as TableColumn[]);
      }
    } catch (error) {
      console.error("컬럼 정보 로딩 오류:", error);
      toast({
        title: "오류",
        description: "컬럼 정보를 불러오는데 실패했습니다.",
        variant: "destructive",
      });
    } finally {
      setLoadingColumns(false);
    }
  };

  const handleExecute = async () => {
    console.log("실행 버튼 클릭");
    if (!query.trim()) {
      toast({
        title: "오류",
        description: "실행할 쿼리를 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    // SELECT 쿼리만 허용하는 검증
    const trimmedQuery = query.trim().toUpperCase();
    if (!trimmedQuery.startsWith("SELECT")) {
      toast({
        title: "보안 오류",
        description:
          "외부 데이터베이스에서는 SELECT 쿼리만 실행할 수 있습니다. INSERT, UPDATE, DELETE는 허용되지 않습니다.",
        variant: "destructive",
      });
      return;
    }

    // 위험한 키워드 검사
    const dangerousKeywords = ["INSERT", "UPDATE", "DELETE", "DROP", "CREATE", "ALTER", "TRUNCATE", "EXEC", "EXECUTE"];
    const hasDangerousKeyword = dangerousKeywords.some((keyword) => trimmedQuery.includes(keyword));

    if (hasDangerousKeyword) {
      toast({
        title: "보안 오류",
        description: "데이터를 변경하거나 삭제하는 쿼리는 허용되지 않습니다. SELECT 쿼리만 사용해주세요.",
        variant: "destructive",
      });
      return;
    }

    console.log("쿼리 실행 시작:", { connectionId, query });
    setLoading(true);
    try {
      const result = await ExternalDbConnectionAPI.executeQuery(connectionId, query);
      console.log("쿼리 실행 결과:", result);
      if (result.success && result.data) {
        setResults(result.data);
        toast({
          title: "성공",
          description: "쿼리가 성공적으로 실행되었습니다.",
        });
      } else {
        toast({
          title: "오류",
          description: result.message || "쿼리 실행 중 오류가 발생했습니다.",
          variant: "destructive",
        });
      }
    } catch (error) {
      console.error("쿼리 실행 오류:", error);
      toast({
        title: "오류",
        description: error instanceof Error ? error.message : "쿼리 실행 중 오류가 발생했습니다.",
        variant: "destructive",
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-h-[90vh] max-w-5xl overflow-hidden" aria-describedby="modal-description">
        <DialogHeader>
          <DialogTitle>{connectionName} - SQL 쿼리 실행</DialogTitle>
          <DialogDescription>
            데이터베이스에 대해 SQL SELECT 쿼리를 실행하고 결과를 확인할 수 있습니다.
          </DialogDescription>
        </DialogHeader>

        {/* 쿼리 입력 영역 */}
        <div className="space-y-4">
          <div className="space-y-2">
            {/* 테이블 선택 */}
            <div className="flex flex-col gap-4">
              <div className="flex items-center gap-2">
                <Select
                  value={selectedTable}
                  onValueChange={(value) => {
                    setSelectedTable(value);
                    loadTableColumns(value);
                    // 현재 커서 위치에 테이블 이름 삽입
                    setQuery((prev) => {
                      const fromIndex = prev.toUpperCase().lastIndexOf("FROM");
                      if (fromIndex === -1) {
                        return `SELECT * FROM ${value}`;
                      }
                      const beforeFrom = prev.substring(0, fromIndex + 4);
                      return `${beforeFrom} ${value}`;
                    });
                  }}
                  disabled={loadingTables}
                >
                  <SelectTrigger className="w-[200px]">
                    <SelectValue placeholder={loadingTables ? "테이블 로딩 중..." : "테이블 선택"} />
                  </SelectTrigger>
                  <SelectContent>
                    {tables.map((table) => (
                      <SelectItem key={table.table_name} value={table.table_name}>
                        {table.table_name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {/* 테이블 정보 */}
              <div className="bg-muted/50 space-y-4 rounded-md border p-4">
                <div>
                  <h3 className="mb-2 text-sm font-medium">사용 가능한 테이블</h3>
                  <div className="max-h-[200px] overflow-hidden">
                    <div className="space-y-2 pr-2">
                      {tables.map((table) => (
                        <div key={table.table_name} className="bg-card rounded-lg border p-3 shadow-sm">
                          <div className="flex items-center justify-between">
                            <h4 className="font-mono text-sm font-bold">{table.table_name}</h4>
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => {
                                setSelectedTable(table.table_name);
                                loadTableColumns(table.table_name);
                                setQuery(`SELECT * FROM ${table.table_name}`);
                              }}
                              className="h-8 text-xs"
                            >
                              선택
                            </Button>
                          </div>
                          {table.description && (
                            <p className="text-muted-foreground mt-1 text-sm">{table.description}</p>
                          )}
                        </div>
                      ))}
                    </div>
                  </div>
                </div>

                {/* 선택된 테이블의 컬럼 정보 */}
                {selectedTable && (
                  <div>
                    <h3 className="mb-2 text-sm font-medium">테이블 컬럼 정보: {selectedTable}</h3>
                    {loadingColumns ? (
                      <div className="text-muted-foreground text-sm">컬럼 정보 로딩 중...</div>
                    ) : selectedTableColumns.length > 0 ? (
                      <div className="max-h-[200px] overflow-hidden">
                        <div className="bg-card rounded-lg border shadow-sm">
                          <Table>
                            <TableHeader>
                              <TableRow>
                                <TableHead className="w-[200px]">컬럼명</TableHead>
                                <TableHead className="w-[150px]">데이터 타입</TableHead>
                                <TableHead className="w-[100px]">NULL 허용</TableHead>
                                <TableHead>기본값</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {selectedTableColumns.map((column) => (
                                <TableRow key={column.column_name}>
                                  <TableCell className="font-mono font-medium">{column.column_name}</TableCell>
                                  <TableCell className="text-sm">{column.data_type}</TableCell>
                                  <TableCell className="text-sm">{column.is_nullable}</TableCell>
                                  <TableCell className="text-sm">{column.column_default || "-"}</TableCell>
                                </TableRow>
                              ))}
                            </TableBody>
                          </Table>
                        </div>
                      </div>
                    ) : (
                      <div className="text-muted-foreground text-sm">컬럼 정보를 불러올 수 없습니다.</div>
                    )}
                  </div>
                )}
              </div>
            </div>

            {/* 쿼리 입력 */}
            <div className="relative">
              <Textarea
                value={query}
                onChange={(e: ChangeEvent<HTMLTextAreaElement>) => setQuery(e.target.value)}
                placeholder="SELECT * FROM table_name"
                className="min-h-[120px] pr-24 font-mono"
              />
              <Button
                onClick={() => {
                  console.log("버튼 클릭됨");
                  handleExecute();
                }}
                disabled={loading}
                className="absolute top-2 right-2 w-20"
                size="sm"
              >
                {loading ? "실행 중..." : "실행"}
              </Button>
            </div>
          </div>
        </div>

        {/* 결과 섹션 */}
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <div className="text-muted-foreground text-sm">
              {loading
                ? "쿼리 실행 중..."
                : results.length > 0
                  ? `${results.length}개의 결과가 있습니다.`
                  : "실행된 쿼리가 없습니다."}
            </div>
          </div>

          {/* 결과 그리드 */}
          <div className="bg-card rounded-md border">
            <div className="max-h-[300px] overflow-hidden">
              <div className="inline-block min-w-full align-middle">
                <div className="overflow-x-auto">
                  <Table>
                    {results.length > 0 ? (
                      <>
                        <TableHeader className="bg-card sticky top-0 z-10">
                          <TableRow>
                            {Object.keys(results[0]).map((key) => (
                              <TableHead key={key} className="font-mono font-bold">
                                {key}
                              </TableHead>
                            ))}
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {results.map((row: QueryResult, i: number) => (
                            <TableRow key={i} className="hover:bg-muted/50">
                              {Object.values(row).map((value, j) => (
                                <TableCell key={j} className="font-mono whitespace-nowrap">
                                  {value === null ? (
                                    <span className="text-muted-foreground italic">NULL</span>
                                  ) : (
                                    String(value)
                                  )}
                                </TableCell>
                              ))}
                            </TableRow>
                          ))}
                        </TableBody>
                      </>
                    ) : (
                      <TableBody>
                        <TableRow>
                          <TableCell className="text-muted-foreground h-32 text-center">
                            {loading ? "쿼리 실행 중..." : "쿼리를 실행하면 결과가 여기에 표시됩니다."}
                          </TableCell>
                        </TableRow>
                      </TableBody>
                    )}
                  </Table>
                </div>
              </div>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
};
