"use client";

import { useEffect, useMemo, useState, useRef } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Search, X, Check, ChevronsUpDown, Database, Globe } from "lucide-react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import { screenApi, tableTypeApi } from "@/lib/api/screen";
import { ScreenDefinition } from "@/types/screen";
import { useAuth } from "@/hooks/useAuth";
import { ExternalRestApiConnectionAPI, ExternalRestApiConnection } from "@/lib/api/externalRestApiConnection";

interface CreateScreenModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCreated?: (screen: ScreenDefinition) => void;
  isPop?: boolean; // POP 화면 생성 모드
}

export default function CreateScreenModal({ open, onOpenChange, onCreated, isPop = false }: CreateScreenModalProps) {
  const { user } = useAuth();

  const [screenName, setScreenName] = useState("");
  const [screenCode, setScreenCode] = useState("");
  const [tableName, setTableName] = useState("");
  const [description, setDescription] = useState("");
  const [tables, setTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
  const [submitting, setSubmitting] = useState(false);
  const [tableSearchTerm, setTableSearchTerm] = useState("");
  const searchInputRef = useRef<HTMLInputElement>(null);

  // 데이터 소스 타입 (database: 데이터베이스, restapi: REST API)
  const [dataSourceType, setDataSourceType] = useState<"database" | "restapi">("database");
  
  // 외부 DB 연결 관련 상태
  const [selectedDbSource, setSelectedDbSource] = useState<"internal" | number>("internal");
  const [externalConnections, setExternalConnections] = useState<any[]>([]);
  const [externalTableList, setExternalTableList] = useState<string[]>([]);
  const [loadingExternalTables, setLoadingExternalTables] = useState(false);
  const [openDbSourceCombobox, setOpenDbSourceCombobox] = useState(false);
  
  // REST API 연결 관련 상태
  const [restApiConnections, setRestApiConnections] = useState<ExternalRestApiConnection[]>([]);
  const [selectedRestApiId, setSelectedRestApiId] = useState<number | null>(null);
  const [openRestApiCombobox, setOpenRestApiCombobox] = useState(false);
  const [restApiEndpoint, setRestApiEndpoint] = useState("");
  const [restApiJsonPath, setRestApiJsonPath] = useState("data"); // 응답에서 데이터 추출 경로
  // 화면 코드 자동 생성
  const generateCode = async () => {
    try {
      const companyCode = (user as any)?.company_code || (user as any)?.companyCode || "*";
      const generatedCode = await screenApi.generateScreenCode(companyCode);
      setScreenCode(generatedCode);
    } catch (e) {
      // console.error("화면 코드 생성 실패", e);
    }
  };

  // 내부 DB 테이블 목록 로드
  useEffect(() => {
    if (!open) return;
    let abort = false;
    const loadTables = async () => {
      try {
        const list = await tableTypeApi.getTables();
        if (abort) return;
        setTables(list.map((t) => ({ tableName: t.tableName, displayName: t.displayName || t.tableName })));
      } catch (e) {
        setTables([]);
      }
    };
    loadTables();
    return () => {
      abort = true;
    };
  }, [open]);

  // 외부 DB 연결 목록 로드
  useEffect(() => {
    if (!open) return;
    const loadConnections = async () => {
      try {
        const token = localStorage.getItem("authToken");
        if (!token) {
          console.warn("No auth token found");
          return;
        }

        const response = await fetch("/api/external-db-connections/control/active", {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });

        if (response && response.ok) {
          const data = await response.json();
          if (data.success && data.data) {
            const filtered = data.data.filter(
              (conn: any) => !conn.connection_name.includes("메인") && !conn.connection_name.includes("현재 시스템"),
            );
            setExternalConnections(filtered);
          }
        }
      } catch (error) {
        console.error("Failed to load external connections:", error);
        setExternalConnections([]);
      }
    };
    loadConnections();
  }, [open]);

  // REST API 연결 목록 로드
  useEffect(() => {
    if (!open) return;
    const loadRestApiConnections = async () => {
      try {
        const connections = await ExternalRestApiConnectionAPI.getConnections({ is_active: "Y" });
        setRestApiConnections(connections);
      } catch (error) {
        console.error("Failed to load REST API connections:", error);
        setRestApiConnections([]);
      }
    };
    loadRestApiConnections();
  }, [open]);

  // 외부 DB 테이블 목록 로드
  useEffect(() => {
    if (selectedDbSource === "internal" || !selectedDbSource) {
      setExternalTableList([]);
      return;
    }

    const loadExternalTables = async () => {
      try {
        setLoadingExternalTables(true);
        const token = localStorage.getItem("authToken");

        const response = await fetch(`/api/multi-connection/connections/${selectedDbSource}/tables`, {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });

        if (response && response.ok) {
          const data = await response.json();
          if (data.success && data.data) {
            const tables = Array.isArray(data.data) ? data.data : [];
            const tableNames = tables
              .map((t: any) => (typeof t === "string" ? t : t.tableName || t.table_name || t.tablename || t.name))
              .filter(Boolean);
            setExternalTableList(tableNames);
          } else {
            setExternalTableList([]);
          }
        } else {
          setExternalTableList([]);
        }
      } catch (error) {
        console.error("외부 DB 테이블 목록 조회 오류:", error);
        setExternalTableList([]);
      } finally {
        setLoadingExternalTables(false);
      }
    };

    loadExternalTables();
  }, [selectedDbSource]);

  // 모달이 열릴 때 자동으로 화면 코드 생성
  useEffect(() => {
    if (open && !screenCode) {
      generateCode();
    }
  }, [open, screenCode]);

  // 테이블 선택은 선택 사항 - 컴포넌트별로 테이블을 설정할 수 있음
  const isValid = useMemo(() => {
    const baseValid = screenName.trim().length > 0 && screenCode.trim().length > 0;
    
    if (dataSourceType === "database") {
      // 테이블 선택은 선택 사항 (비워두면 컴포넌트별로 테이블 설정)
      return baseValid;
    } else {
      // REST API: 연결 선택 필수
      return baseValid && selectedRestApiId !== null;
    }
  }, [screenName, screenCode, dataSourceType, selectedRestApiId]);

  // 테이블 필터링 (내부 DB용)
  const filteredTables = useMemo(() => {
    if (!tableSearchTerm) return tables;
    const searchLower = tableSearchTerm.toLowerCase();
    return tables.filter(
      (table) =>
        table.displayName.toLowerCase().includes(searchLower) || table.tableName.toLowerCase().includes(searchLower),
    );
  }, [tables, tableSearchTerm]);

  // 외부 DB 테이블 필터링
  const filteredExternalTables = useMemo(() => {
    if (!tableSearchTerm) return externalTableList;
    const searchLower = tableSearchTerm.toLowerCase();
    return externalTableList.filter((table) => table.toLowerCase().includes(searchLower));
  }, [externalTableList, tableSearchTerm]);

  const handleSubmit = async () => {
    if (!isValid || submitting) return;
    try {
      setSubmitting(true);
      const companyCode = (user as any)?.company_code || (user as any)?.companyCode || "*";

      // 데이터 소스 타입에 따라 다른 정보 전달
      const createData: any = {
        screenName: screenName.trim(),
        screenCode: screenCode.trim(),
        companyCode,
        description: description.trim() || undefined,
        createdBy: (user as any)?.userId,
        dataSourceType: dataSourceType,
      };

      if (dataSourceType === "database") {
        // 데이터베이스 소스 - 테이블 선택은 선택 사항
        createData.tableName = tableName.trim() || null; // 비어있으면 null
        createData.dbSourceType = selectedDbSource === "internal" ? "internal" : "external";
        createData.dbConnectionId = selectedDbSource === "internal" ? undefined : Number(selectedDbSource);
      } else {
        // REST API 소스
        createData.tableName = `_restapi_${selectedRestApiId}`; // REST API용 가상 테이블명
        createData.restApiConnectionId = selectedRestApiId;
        createData.restApiEndpoint = restApiEndpoint.trim() || undefined;
        createData.restApiJsonPath = restApiJsonPath.trim() || "data";
      }

      const created = await screenApi.createScreen(createData);

      // POP 모드일 경우 빈 POP 레이아웃 자동 생성
      if (isPop && created.screenId) {
        try {
          await screenApi.saveLayoutPop(created.screenId, {
            version: "2.0",
            components: [],
          });
        } catch (popError) {
          console.error("POP 레이아웃 생성 실패:", popError);
          // POP 레이아웃 생성 실패해도 화면 생성은 성공으로 처리
        }
      }

      // 날짜 필드 보정
      const mapped: ScreenDefinition = {
        ...created,
        createdDate: created.createdDate ? new Date(created.createdDate as any) : new Date(),
        updatedDate: created.updatedDate ? new Date(created.updatedDate as any) : new Date(),
      } as ScreenDefinition;

      onCreated?.(mapped);
      onOpenChange(false);
      // 폼 초기화
      setScreenName("");
      setScreenCode("");
      setTableName("");
      setDescription("");
      setSelectedDbSource("internal");
      setDataSourceType("database");
      setSelectedRestApiId(null);
      setRestApiEndpoint("");
      setRestApiJsonPath("data");
    } catch (e: any) {
      console.error("화면 생성 실패:", e);
      const errorMessage = e?.response?.data?.message || e?.message || "화면 생성에 실패했습니다.";
      alert(errorMessage);
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>{isPop ? "새 POP 화면 생성" : "새 화면 생성"}</DialogTitle>
        </DialogHeader>

        <div className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="screenName">화면명</Label>
            <Input id="screenName" value={screenName} onChange={(e) => setScreenName(e.target.value)} />
          </div>

          <div className="space-y-2">
            <Label htmlFor="description">설명</Label>
            <Input
              id="description"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="화면 설명을 입력하세요 (모달에 표시됨)"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="screenCode">화면 코드</Label>
            <Input
              id="screenCode"
              value={screenCode}
              readOnly
              placeholder="자동 생성됩니다..."
              className="cursor-not-allowed bg-muted"
            />
          </div>

          {/* 데이터 소스 타입 선택 */}
          <div className="space-y-2">
            <Label>데이터 소스 타입</Label>
            <div className="flex gap-2">
              <Button
                type="button"
                variant={dataSourceType === "database" ? "default" : "outline"}
                className="flex-1"
                onClick={() => {
                  setDataSourceType("database");
                  setSelectedRestApiId(null);
                }}
              >
                <Database className="mr-2 h-4 w-4" />
                데이터베이스
              </Button>
              <Button
                type="button"
                variant={dataSourceType === "restapi" ? "default" : "outline"}
                className="flex-1"
                onClick={() => {
                  setDataSourceType("restapi");
                  setTableName("");
                  setSelectedDbSource("internal");
                }}
              >
                <Globe className="mr-2 h-4 w-4" />
                REST API
              </Button>
            </div>
          </div>

          {/* 데이터베이스 소스 설정 */}
          {dataSourceType === "database" && (
            <>
              {/* DB 소스 선택 */}
              <div className="space-y-2">
                <Label htmlFor="dbSource">데이터베이스 소스</Label>
                <Popover open={openDbSourceCombobox} onOpenChange={setOpenDbSourceCombobox}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={openDbSourceCombobox}
                      className="w-full justify-between"
                    >
                      <div className="flex items-center gap-2">
                        <Database className="h-4 w-4" />
                        {selectedDbSource === "internal"
                          ? "내부 데이터베이스"
                          : externalConnections.find((conn) => conn.id === selectedDbSource)?.connection_name ||
                            "선택하세요"}
                      </div>
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                    <Command>
                      <CommandInput placeholder="데이터베이스 검색..." />
                      <CommandList>
                        <CommandEmpty>데이터베이스를 찾을 수 없습니다.</CommandEmpty>
                        <CommandGroup>
                          <CommandItem
                            value="internal"
                            onSelect={() => {
                              setSelectedDbSource("internal");
                              setTableName("");
                              setTableSearchTerm("");
                              setOpenDbSourceCombobox(false);
                            }}
                          >
                            <Check
                              className={cn("mr-2 h-4 w-4", selectedDbSource === "internal" ? "opacity-100" : "opacity-0")}
                            />
                            <Database className="mr-2 h-4 w-4 text-primary" />
                            <div className="flex flex-col">
                              <span className="font-medium">내부 데이터베이스</span>
                              <span className="text-xs text-muted-foreground">PostgreSQL (현재 시스템)</span>
                            </div>
                          </CommandItem>
                          {externalConnections.map((conn: any) => (
                            <CommandItem
                              key={conn.id}
                              value={`${conn.connection_name} ${conn.db_type}`}
                              onSelect={() => {
                                setSelectedDbSource(conn.id);
                                setTableName("");
                                setTableSearchTerm("");
                                setOpenDbSourceCombobox(false);
                              }}
                            >
                              <Check
                                className={cn("mr-2 h-4 w-4", selectedDbSource === conn.id ? "opacity-100" : "opacity-0")}
                              />
                              <Database className="mr-2 h-4 w-4 text-emerald-500" />
                              <div className="flex flex-col">
                                <span className="font-medium">{conn.connection_name}</span>
                                <span className="text-xs text-muted-foreground">{conn.db_type?.toUpperCase()}</span>
                              </div>
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
                <p className="text-xs text-muted-foreground">화면에서 사용할 데이터베이스를 선택합니다</p>
              </div>
            </>
          )}

          {/* REST API 소스 설정 */}
          {dataSourceType === "restapi" && (
            <>
              {/* REST API 연결 선택 */}
              <div className="space-y-2">
                <Label htmlFor="restApiConnection">REST API 연결 *</Label>
                <Popover open={openRestApiCombobox} onOpenChange={setOpenRestApiCombobox}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={openRestApiCombobox}
                      className="w-full justify-between"
                    >
                      <div className="flex items-center gap-2">
                        <Globe className="h-4 w-4" />
                        {selectedRestApiId
                          ? restApiConnections.find((conn) => conn.id === selectedRestApiId)?.connection_name ||
                            "선택하세요"
                          : "REST API 연결을 선택하세요"}
                      </div>
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
                    <Command>
                      <CommandInput placeholder="REST API 검색..." />
                      <CommandList>
                        <CommandEmpty>등록된 REST API 연결이 없습니다.</CommandEmpty>
                        <CommandGroup>
                          {restApiConnections.map((conn) => (
                            <CommandItem
                              key={conn.id}
                              value={`${conn.connection_name} ${conn.base_url}`}
                              onSelect={() => {
                                setSelectedRestApiId(conn.id!);
                                setRestApiEndpoint(conn.endpoint_path || "");
                                setOpenRestApiCombobox(false);
                              }}
                            >
                              <Check
                                className={cn("mr-2 h-4 w-4", selectedRestApiId === conn.id ? "opacity-100" : "opacity-0")}
                              />
                              <Globe className="mr-2 h-4 w-4 text-purple-500" />
                              <div className="flex flex-col">
                                <span className="font-medium">{conn.connection_name}</span>
                                <span className="text-xs text-muted-foreground truncate max-w-[300px]">{conn.base_url}</span>
                              </div>
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
                <p className="text-xs text-muted-foreground">
                  등록된 REST API 연결을 선택합니다.
                  <Link href="/admin/externalRestApi" className="ml-1 text-primary hover:underline">
                    새 연결 등록
                  </Link>
                </p>
              </div>

              {/* 엔드포인트 경로 */}
              <div className="space-y-2">
                <Label htmlFor="restApiEndpoint">엔드포인트 경로</Label>
                <Input
                  id="restApiEndpoint"
                  value={restApiEndpoint}
                  onChange={(e) => setRestApiEndpoint(e.target.value)}
                  placeholder="/api/data 또는 /users"
                />
                <p className="text-xs text-muted-foreground">기본 URL 뒤에 추가될 경로 (선택사항)</p>
              </div>

              {/* JSON Path */}
              <div className="space-y-2">
                <Label htmlFor="restApiJsonPath">데이터 경로 (JSON Path)</Label>
                <Input
                  id="restApiJsonPath"
                  value={restApiJsonPath}
                  onChange={(e) => setRestApiJsonPath(e.target.value)}
                  placeholder="data 또는 result.items"
                />
                <p className="text-xs text-muted-foreground">API 응답에서 데이터 배열을 추출할 경로 (예: data, result.items)</p>
              </div>
            </>
          )}

          {/* 테이블 선택 (데이터베이스 모드일 때만) */}
          {dataSourceType === "database" && (
          <div className="space-y-2">
            <Label htmlFor="tableName">기본 테이블 (선택)</Label>
            <p className="text-muted-foreground text-xs">
              비워두면 화면 디자이너에서 컴포넌트별로 테이블을 설정할 수 있습니다.
            </p>
            <Select
              value={tableName}
              onValueChange={setTableName}
              disabled={loadingExternalTables}
              onOpenChange={(open) => {
                if (open) {
                  setTimeout(() => {
                    searchInputRef.current?.focus();
                  }, 100);
                }
              }}
            >
              <SelectTrigger className="w-full">
                <SelectValue placeholder={loadingExternalTables ? "로딩 중..." : "(선택 사항) 기본 테이블 선택"} />
              </SelectTrigger>
              <SelectContent className="max-h-80">
                {/* 검색 입력 필드 */}
                <div className="sticky top-0 z-10 border-b bg-white p-2" onKeyDown={(e) => e.stopPropagation()}>
                  <div className="relative">
                    <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-muted-foreground/70" />
                    <input
                      ref={searchInputRef}
                      type="text"
                      placeholder="테이블명으로 검색..."
                      value={tableSearchTerm}
                      autoFocus
                      onChange={(e) => {
                        e.stopPropagation();
                        setTableSearchTerm(e.target.value);
                      }}
                      onKeyDown={(e) => e.stopPropagation()}
                      onClick={(e) => e.stopPropagation()}
                      onFocus={(e) => e.stopPropagation()}
                      onMouseDown={(e) => e.stopPropagation()}
                      className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-8 w-full rounded-md border px-3 py-2 pr-8 pl-10 text-sm file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
                    />
                    {tableSearchTerm && (
                      <button
                        type="button"
                        onClick={(e) => {
                          e.stopPropagation();
                          setTableSearchTerm("");
                        }}
                        className="hover:text-muted-foreground absolute top-1/2 right-2 h-4 w-4 -translate-y-1/2 transform text-muted-foreground/70"
                      >
                        <X className="h-3 w-3" />
                      </button>
                    )}
                  </div>
                </div>

                {/* 테이블 옵션들 */}
                <div className="max-h-60 overflow-y-auto">
                  {selectedDbSource === "internal" ? (
                    // 내부 DB 테이블 목록
                    filteredTables.length === 0 ? (
                      <div className="px-2 py-6 text-center text-sm text-muted-foreground">
                        {tableSearchTerm ? `"${tableSearchTerm}"에 대한 검색 결과가 없습니다` : "테이블이 없습니다"}
                      </div>
                    ) : (
                      filteredTables.map((table) => (
                        <SelectItem key={table.tableName} value={table.tableName}>
                          {table.displayName} ({table.tableName})
                        </SelectItem>
                      ))
                    )
                  ) : // 외부 DB 테이블 목록
                  filteredExternalTables.length === 0 ? (
                    <div className="px-2 py-6 text-center text-sm text-muted-foreground">
                      {tableSearchTerm ? `"${tableSearchTerm}"에 대한 검색 결과가 없습니다` : "테이블이 없습니다"}
                    </div>
                  ) : (
                    filteredExternalTables.map((tableName) => (
                      <SelectItem key={tableName} value={tableName}>
                        {tableName}
                      </SelectItem>
                    ))
                  )}
                </div>
              </SelectContent>
            </Select>
          </div>
          )}
        </div>

        <DialogFooter className="mt-4">
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
            취소
          </Button>
          <Button onClick={handleSubmit} disabled={!isValid || submitting} variant="default">
            생성
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
