"use client";

import React, { useState, useEffect, useRef } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { Search, Monitor, Settings, X, Plus } from "lucide-react";
import { menuScreenApi } from "@/lib/api/screen";
import { apiClient } from "@/lib/api/client";
import type { MenuItem } from "@/lib/api/menu";
import { ScreenDefinition } from "@/types/screen";

interface MenuAssignmentModalProps {
  isOpen: boolean;
  onClose: () => void;
  screenInfo: ScreenDefinition | null;
  onAssignmentComplete?: () => void;
  onBackToList?: () => void; // 화면 목록으로 돌아가는 콜백 추가
}

export const MenuAssignmentModal: React.FC<MenuAssignmentModalProps> = ({
  isOpen,
  onClose,
  screenInfo,
  onAssignmentComplete,
  onBackToList,
}) => {
  const [menus, setMenus] = useState<MenuItem[]>([]);
  const [selectedMenuId, setSelectedMenuId] = useState<string>("");
  const [selectedMenu, setSelectedMenu] = useState<MenuItem | null>(null);
  const [searchTerm, setSearchTerm] = useState("");
  const [loading, setLoading] = useState(false);
  const [assigning, setAssigning] = useState(false);
  const [existingScreens, setExistingScreens] = useState<ScreenDefinition[]>([]);
  const [showReplaceDialog, setShowReplaceDialog] = useState(false);
  const [assignmentSuccess, setAssignmentSuccess] = useState(false);
  const [assignmentMessage, setAssignmentMessage] = useState("");
  const searchInputRef = useRef<HTMLInputElement>(null);
  const autoRedirectTimerRef = useRef<NodeJS.Timeout | null>(null);

  // 메뉴 목록 로드 (관리자 메뉴 + 사용자 메뉴)
  const loadMenus = async () => {
    try {
      setLoading(true);

      // 관리자 메뉴 가져오기
      const adminResponse = await apiClient.get("/admin/menus", { params: { menuType: "0" } });
      const adminMenus = adminResponse.data?.data || [];

      // 사용자 메뉴 가져오기
      const userResponse = await apiClient.get("/admin/menus", { params: { menuType: "1" } });
      const userMenus = userResponse.data?.data || [];

      // 메뉴 정규화 함수
      const normalizeMenu = (menu: any) => ({
        objid: menu.objid || menu.OBJID,
        parent_obj_id: menu.parent_obj_id || menu.PARENT_OBJ_ID,
        menu_name_kor: menu.menu_name_kor || menu.MENU_NAME_KOR,
        menu_url: menu.menu_url || menu.MENU_URL,
        menu_desc: menu.menu_desc || menu.MENU_DESC,
        seq: menu.seq || menu.SEQ,
        menu_type: menu.menu_type || menu.MENU_TYPE,
        status: menu.status || menu.STATUS,
        lev: menu.lev || menu.LEV,
        company_code: menu.company_code || menu.COMPANY_CODE,
        company_name: menu.company_name || menu.COMPANY_NAME,
      });

      // 관리자 메뉴 정규화
      const normalizedAdminMenus = adminMenus.map((menu: any) => normalizeMenu(menu));

      // 사용자 메뉴 정규화
      const normalizedUserMenus = userMenus.map((menu: any) => normalizeMenu(menu));

      // 모든 메뉴 합치기
      const allMenus = [...normalizedAdminMenus, ...normalizedUserMenus];

      // console.log("로드된 전체 메뉴 목록:", {
      // totalAdmin: normalizedAdminMenus.length,
      // totalUser: normalizedUserMenus.length,
      // total: allMenus.length,
      // });
      setMenus(allMenus);
    } catch (error) {
      // console.error("메뉴 목록 로드 실패:", error);
      showErrorToast("메뉴 목록을 불러오는 데 실패했습니다", error, { guidance: "네트워크 연결을 확인해 주세요." });
    } finally {
      setLoading(false);
    }
  };

  // 모달이 열릴 때 메뉴 목록 로드 및 정리
  useEffect(() => {
    if (isOpen) {
      loadMenus();
      setSelectedMenuId("");
      setSelectedMenu(null);
      setSearchTerm("");
      setAssignmentSuccess(false);
      setAssignmentMessage("");
    } else {
      // 모달이 닫힐 때 타이머 정리
      if (autoRedirectTimerRef.current) {
        clearTimeout(autoRedirectTimerRef.current);
        autoRedirectTimerRef.current = null;
      }
    }
    
    // 컴포넌트 언마운트 시 타이머 정리
    return () => {
      if (autoRedirectTimerRef.current) {
        clearTimeout(autoRedirectTimerRef.current);
        autoRedirectTimerRef.current = null;
      }
    };
  }, [isOpen]);

  // 메뉴 선택 처리
  const handleMenuSelect = async (menuId: string) => {
    // 유효하지 않은 메뉴 ID인 경우 처리하지 않음
    if (!menuId || menuId === "no-menu") {
      setSelectedMenuId("");
      setSelectedMenu(null);
      setExistingScreens([]);
      return;
    }

    setSelectedMenuId(menuId);
    const menu = menus.find((m) => m.objid?.toString() === menuId);
    setSelectedMenu(menu || null);

    // 선택된 메뉴에 할당된 화면들 확인
    if (menu) {
      try {
        const menuObjid = parseInt(menu.objid?.toString() || "0");
        if (menuObjid > 0) {
          const screens = await menuScreenApi.getScreensByMenu(menuObjid);
          setExistingScreens(screens);
          // console.log(`메뉴 "${menu.menu_name_kor}"에 할당된 화면:`, screens);
        }
      } catch (error) {
        // console.error("할당된 화면 조회 실패:", error);
        setExistingScreens([]);
      }
    }
  };

  // 화면 할당 처리
  const handleAssignScreen = async () => {
    if (!selectedMenu || !screenInfo) {
      toast.error("메뉴와 화면 정보가 필요합니다.");
      return;
    }

    // 기존에 할당된 화면이 있는지 확인
    if (existingScreens.length > 0) {
      // 이미 같은 화면이 할당되어 있는지 확인
      const alreadyAssigned = existingScreens.some((screen) => screen.screenId === screenInfo.screenId);
      if (alreadyAssigned) {
        toast.info("이미 해당 메뉴에 할당된 화면입니다.");
        return;
      }

      // 다른 화면이 할당되어 있으면 교체 확인
      setShowReplaceDialog(true);
      return;
    }

    // 기존 화면이 없으면 바로 할당
    await performAssignment();
  };

  // 실제 할당 수행
  const performAssignment = async (replaceExisting = false) => {
    if (!selectedMenu || !screenInfo) return;

    try {
      setAssigning(true);

      const menuObjid = parseInt(selectedMenu.objid?.toString() || "0");
      if (menuObjid === 0) {
        toast.error("유효하지 않은 메뉴 ID입니다.");
        return;
      }

      // 기존 화면 교체인 경우 기존 화면들 먼저 제거
      if (replaceExisting && existingScreens.length > 0) {
        // console.log("기존 화면들 제거 중...", existingScreens);
        for (const existingScreen of existingScreens) {
          try {
            await menuScreenApi.unassignScreenFromMenu(existingScreen.screenId, menuObjid);
            // console.log(`기존 화면 "${existingScreen.screenName}" 제거 완료`);
          } catch (error) {
            // console.error(`기존 화면 "${existingScreen.screenName}" 제거 실패:`, error);
          }
        }
      }

      // 새 화면 할당
      await menuScreenApi.assignScreenToMenu(screenInfo.screenId, menuObjid);

      const successMessage = replaceExisting
        ? `기존 화면을 제거하고 "${screenInfo.screenName}" 화면이 "${selectedMenu.menu_name_kor}" 메뉴에 할당되었습니다.`
        : `"${screenInfo.screenName}" 화면이 "${selectedMenu.menu_name_kor}" 메뉴에 성공적으로 할당되었습니다.`;

      // 성공 상태 설정
      setAssignmentSuccess(true);
      setAssignmentMessage(successMessage);

      // 할당 완료 콜백 호출 (모달은 아직 열린 상태 유지)
      if (onAssignmentComplete) {
        onAssignmentComplete();
      }

      // 3초 후 자동으로 모달 닫고 화면 목록으로 이동
      autoRedirectTimerRef.current = setTimeout(() => {
        onClose(); // 모달 닫기
        if (onBackToList) {
          onBackToList();
        }
      }, 3000);
    } catch (error: any) {
      // console.error("화면 할당 실패:", error);
      const errorMessage = error.response?.data?.message || "화면 할당에 실패했습니다.";
      toast.error(errorMessage);
    } finally {
      setAssigning(false);
    }
  };

  // "나중에 할당" 처리 - 시각적 효과 포함
  const handleAssignLater = () => {
    if (!screenInfo) return;

    // 성공 상태 설정 (나중에 할당 메시지)
    setAssignmentSuccess(true);
    setAssignmentMessage(`"${screenInfo.screenName}" 화면이 저장되었습니다. 나중에 메뉴에 할당할 수 있습니다.`);

    // 할당 완료 콜백 호출 (모달은 아직 열린 상태 유지)
    if (onAssignmentComplete) {
      onAssignmentComplete();
    }

    // 3초 후 자동으로 모달 닫고 화면 목록으로 이동
    autoRedirectTimerRef.current = setTimeout(() => {
      onClose(); // 모달 닫기
      if (onBackToList) {
        onBackToList();
      }
    }, 3000);
  };

  // 필터된 메뉴 목록
  const filteredMenus = menus.filter((menu) => {
    if (!searchTerm) return true;
    const searchLower = searchTerm.toLowerCase();
    return (
      menu.menu_name_kor?.toLowerCase().includes(searchLower) ||
      menu.menu_url?.toLowerCase().includes(searchLower) ||
      menu.menu_desc?.toLowerCase().includes(searchLower)
    );
  });

  // 메뉴 옵션 생성 (계층 구조 표시, 타입별 그룹화)
  const getMenuOptions = (): React.ReactNode[] => {
    if (loading) {
      return [
        <SelectItem key="loading" value="loading" disabled>
          메뉴 로딩 중...
        </SelectItem>,
      ];
    }

    if (filteredMenus.length === 0) {
      return [
        <SelectItem key="no-menu" value="no-menu" disabled>
          {searchTerm ? `"${searchTerm}"에 대한 검색 결과가 없습니다` : "메뉴가 없습니다"}
        </SelectItem>,
      ];
    }

    // 관리자 메뉴와 사용자 메뉴 분리
    const adminMenus = filteredMenus.filter(
      (menu) => menu.menu_type === "0" && menu.objid && menu.objid.toString().trim() !== "",
    );
    const userMenus = filteredMenus.filter(
      (menu) => menu.menu_type === "1" && menu.objid && menu.objid.toString().trim() !== "",
    );

    const options: React.ReactNode[] = [];

    // 관리자 메뉴 섹션
    if (adminMenus.length > 0) {
      options.push(
        <div key="admin-header" className="bg-primary/10 px-2 py-1.5 text-xs font-semibold text-primary">
          👤 관리자 메뉴
        </div>,
      );
      adminMenus.forEach((menu) => {
        const indent = "　".repeat(Math.max(0, menu.lev || 0));
        const menuId = menu.objid!.toString();
        options.push(
          <SelectItem key={menuId} value={menuId}>
            {indent}
            {menu.menu_name_kor}
          </SelectItem>,
        );
      });
    }

    // 사용자 메뉴 섹션
    if (userMenus.length > 0) {
      if (adminMenus.length > 0) {
        options.push(<div key="separator" className="my-1 border-t" />);
      }
      options.push(
        <div key="user-header" className="bg-emerald-50 px-2 py-1.5 text-xs font-semibold text-emerald-600">
          👥 사용자 메뉴
        </div>,
      );
      userMenus.forEach((menu) => {
        const indent = "　".repeat(Math.max(0, menu.lev || 0));
        const menuId = menu.objid!.toString();
        options.push(
          <SelectItem key={menuId} value={menuId}>
            {indent}
            {menu.menu_name_kor}
          </SelectItem>,
        );
      });
    }

    return options;
  };

  return (
    <>
      <Dialog open={isOpen} onOpenChange={onClose}>
        <DialogContent className="max-w-2xl">
          {assignmentSuccess ? (
            // 성공 화면
            <>
              <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                  <div className="flex h-8 w-8 items-center justify-center rounded-full bg-emerald-100">
                    <svg className="h-5 w-5 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                    </svg>
                  </div>
                  {assignmentMessage.includes("나중에") ? "화면 저장 완료" : "화면 할당 완료"}
                </DialogTitle>
                <DialogDescription>
                  {assignmentMessage.includes("나중에")
                    ? "화면이 성공적으로 저장되었습니다. 나중에 메뉴에 할당할 수 있습니다."
                    : "화면이 성공적으로 메뉴에 할당되었습니다."}
                </DialogDescription>
              </DialogHeader>

              <div className="space-y-4">
                <div className="rounded-lg border bg-emerald-50 p-4">
                  <div className="flex items-center gap-3">
                    <div className="flex h-10 w-10 items-center justify-center rounded-full bg-emerald-100">
                      <Monitor className="h-5 w-5 text-emerald-600" />
                    </div>
                    <div className="flex-1">
                      <p className="text-sm font-medium text-green-900">{assignmentMessage}</p>
                      <p className="mt-1 text-xs text-emerald-700">3초 후 자동으로 화면 목록으로 이동합니다...</p>
                    </div>
                  </div>
                </div>

                <div className="flex items-center justify-center space-x-2">
                  <div className="h-2 w-2 animate-bounce rounded-full bg-emerald-500 [animation-delay:-0.3s]"></div>
                  <div className="h-2 w-2 animate-bounce rounded-full bg-emerald-500 [animation-delay:-0.15s]"></div>
                  <div className="h-2 w-2 animate-bounce rounded-full bg-emerald-500"></div>
                </div>
              </div>

              <DialogFooter>
                <Button
                  onClick={() => {
                    // 타이머 정리
                    if (autoRedirectTimerRef.current) {
                      clearTimeout(autoRedirectTimerRef.current);
                      autoRedirectTimerRef.current = null;
                    }
                    
                    // 화면 목록으로 이동
                    if (onBackToList) {
                      onBackToList();
                    } else {
                      onClose();
                    }
                  }}
                  className="bg-emerald-600 text-white hover:bg-green-700"
                >
                  <Monitor className="mr-2 h-4 w-4" />
                  화면 목록으로 이동
                </Button>
              </DialogFooter>
            </>
          ) : (
            // 기본 할당 화면
            <>
              <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                  <Settings className="h-5 w-5" />
                  메뉴에 화면 할당
                </DialogTitle>
                <DialogDescription>
                  저장된 화면을 메뉴에 할당하여 사용자가 접근할 수 있도록 설정합니다.
                </DialogDescription>
                {screenInfo && (
                  <div className="bg-accent mt-2 rounded-lg border p-3">
                    <div className="flex items-center gap-2">
                      <Monitor className="text-primary h-4 w-4" />
                      <span className="font-medium text-primary">{screenInfo.screenName}</span>
                      <Badge variant="outline" className="font-mono text-xs">
                        {screenInfo.screenCode}
                      </Badge>
                    </div>
                    {screenInfo.description && <p className="mt-1 text-sm text-primary">{screenInfo.description}</p>}
                  </div>
                )}
              </DialogHeader>

              <div className="space-y-4">
                {/* 메뉴 선택 (검색 기능 포함) */}
                <div>
                  <Label htmlFor="menu-select">할당할 메뉴 선택</Label>
                  <Select
                    value={selectedMenuId}
                    onValueChange={handleMenuSelect}
                    disabled={loading}
                    onOpenChange={(open) => {
                      if (open) {
                        // Select가 열릴 때 검색창에 포커스
                        setTimeout(() => {
                          searchInputRef.current?.focus();
                        }, 100);
                      }
                    }}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={loading ? "메뉴 로딩 중..." : "메뉴를 선택하세요"} />
                    </SelectTrigger>
                    <SelectContent className="max-h-64">
                      {/* 검색 입력 필드 */}
                      <div
                        className="sticky top-0 z-10 border-b bg-white p-2"
                        onKeyDown={(e) => {
                          // 이 div 내에서 발생하는 모든 키 이벤트를 차단
                          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="메뉴명, URL, 설명으로 검색..."
                            value={searchTerm}
                            autoFocus
                            onChange={(e) => {
                              e.stopPropagation();
                              setSearchTerm(e.target.value);
                            }}
                            onKeyDown={(e) => {
                              // 이벤트가 Select로 전파되지 않도록 완전 차단
                              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"
                          />
                          {searchTerm && (
                            <button
                              type="button"
                              onClick={(e) => {
                                e.stopPropagation();
                                setSearchTerm("");
                              }}
                              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-48 overflow-y-auto">{getMenuOptions()}</div>
                    </SelectContent>
                  </Select>
                </div>

                {/* 선택된 메뉴 정보 */}
                {selectedMenu && (
                  <div className="rounded-lg border bg-muted p-4">
                    <div className="flex items-center justify-between">
                      <div className="flex-1">
                        <div className="flex items-center gap-2">
                          <h4 className="font-medium">{selectedMenu.menu_name_kor}</h4>
                          <Badge variant={selectedMenu.menu_type === "0" ? "default" : "secondary"}>
                            {selectedMenu.menu_type === "0" ? "관리자" : "사용자"}
                          </Badge>
                          <Badge variant={selectedMenu.status === "active" ? "default" : "outline"}>
                            {selectedMenu.status === "active" ? "활성" : "비활성"}
                          </Badge>
                        </div>
                        <div className="text-muted-foreground mt-1 space-y-1 text-sm">
                          {selectedMenu.menu_url && <p>URL: {selectedMenu.menu_url}</p>}
                          {selectedMenu.menu_desc && <p>설명: {selectedMenu.menu_desc}</p>}
                          {selectedMenu.company_name && <p>회사: {selectedMenu.company_name}</p>}
                        </div>

                        {/* 기존 할당된 화면 정보 */}
                        {existingScreens.length > 0 && (
                          <div className="mt-3 rounded border bg-amber-50 p-2">
                            <p className="text-sm font-medium text-yellow-800">
                              ⚠️ 이미 할당된 화면 ({existingScreens.length}개)
                            </p>
                            <div className="mt-1 space-y-1">
                              {existingScreens.map((screen) => (
                                <div key={screen.screenId} className="flex items-center gap-2 text-xs text-yellow-700">
                                  <Monitor className="h-3 w-3" />
                                  <span>{screen.screenName}</span>
                                  <Badge variant="outline" className="text-xs">
                                    {screen.screenCode}
                                  </Badge>
                                </div>
                              ))}
                            </div>
                            <p className="mt-1 text-xs text-amber-600">새 화면을 할당하면 기존 화면들이 제거됩니다.</p>
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>

              <DialogFooter className="flex gap-2">
                <Button variant="outline" onClick={handleAssignLater} disabled={assigning}>
                  <X className="mr-2 h-4 w-4" />
                  나중에 할당
                </Button>
                <Button
                  onClick={handleAssignScreen}
                  disabled={!selectedMenu || assigning}
                  className="bg-primary text-white hover:bg-primary/90"
                >
                  {assigning ? (
                    <>
                      <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
                      할당 중...
                    </>
                  ) : (
                    <>
                      <Settings className="mr-2 h-4 w-4" />
                      메뉴에 할당
                    </>
                  )}
                </Button>
              </DialogFooter>
            </>
          )}
        </DialogContent>
      </Dialog>

      {/* 화면 교체 확인 대화상자 */}
      <Dialog open={showReplaceDialog} onOpenChange={setShowReplaceDialog}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Monitor className="h-5 w-5 text-amber-600" />
              화면 교체 확인
            </DialogTitle>
            <DialogDescription>선택한 메뉴에 이미 할당된 화면이 있습니다.</DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            {/* 기존 화면 목록 */}
            <div className="bg-destructive/10 rounded-lg border p-3">
              <p className="mb-2 text-sm font-medium text-red-800">제거될 화면 ({existingScreens.length}개):</p>
              <div className="space-y-1">
                {existingScreens.map((screen) => (
                  <div key={screen.screenId} className="flex items-center gap-2 text-sm text-destructive">
                    <X className="h-3 w-3" />
                    <span>{screen.screenName}</span>
                    <Badge variant="outline" className="text-xs">
                      {screen.screenCode}
                    </Badge>
                  </div>
                ))}
              </div>
            </div>

            {/* 새로 할당될 화면 */}
            {screenInfo && (
              <div className="rounded-lg border bg-emerald-50 p-3">
                <p className="mb-2 text-sm font-medium text-emerald-800">새로 할당될 화면:</p>
                <div className="flex items-center gap-2 text-sm text-emerald-700">
                  <Plus className="h-3 w-3" />
                  <span>{screenInfo.screenName}</span>
                  <Badge variant="outline" className="text-xs">
                    {screenInfo.screenCode}
                  </Badge>
                </div>
              </div>
            )}

            <div className="rounded-lg border-l-4 border-orange-400 bg-amber-50 p-3">
              <p className="text-sm text-orange-800">
                <strong>주의:</strong> 기존 화면들이 메뉴에서 제거되고 새 화면으로 교체됩니다. 이 작업은 되돌릴 수
                없습니다.
              </p>
            </div>
          </div>

          <DialogFooter className="flex gap-2">
            <Button variant="outline" onClick={() => setShowReplaceDialog(false)} disabled={assigning}>
              취소
            </Button>
            <Button
              onClick={async () => {
                setShowReplaceDialog(false);
                await performAssignment(true);
              }}
              disabled={assigning}
              className="bg-orange-600 text-white hover:bg-orange-700"
            >
              {assigning ? (
                <>
                  <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
                  교체 중...
                </>
              ) : (
                <>
                  <Monitor className="mr-2 h-4 w-4" />
                  화면 교체
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
};
