"use client";

import React, { useState, useEffect } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} 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 { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { toast } from "sonner";
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 loadMenus = async () => {
    try {
      setLoading(true);

      // 화면관리는 관리자 전용 기능이므로 관리자 메뉴만 가져오기
      const adminResponse = await apiClient.get("/admin/menus", { params: { menuType: "0" } });
      const adminMenus = adminResponse.data?.data || [];

      // 관리자 메뉴 정규화
      const normalizedAdminMenus = adminMenus.map((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: "0", // 관리자 메뉴
        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,
      }));

      console.log("로드된 관리자 메뉴 목록:", {
        total: normalizedAdminMenus.length,
        sample: normalizedAdminMenus.slice(0, 3),
      });
      setMenus(normalizedAdminMenus);
    } catch (error) {
      console.error("메뉴 목록 로드 실패:", error);
      toast.error("메뉴 목록을 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  };

  // 모달이 열릴 때 메뉴 목록 로드
  useEffect(() => {
    if (isOpen) {
      loadMenus();
      setSelectedMenuId("");
      setSelectedMenu(null);
      setSearchTerm("");
      setAssignmentSuccess(false);
      setAssignmentMessage("");
    }
  }, [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초 후 자동으로 화면 목록으로 이동
      setTimeout(() => {
        if (onBackToList) {
          onBackToList();
        } else {
          onClose();
        }
      }, 3000);
    } catch (error: any) {
      console.error("화면 할당 실패:", error);
      const errorMessage = error.response?.data?.message || "화면 할당에 실패했습니다.";
      toast.error(errorMessage);
    } finally {
      setAssigning(false);
    }
  };

  // 필터된 메뉴 목록
  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 = (): JSX.Element[] => {
    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>,
      ];
    }

    return filteredMenus
      .filter((menu) => menu.objid && menu.objid.toString().trim() !== "") // objid가 유효한 메뉴만 필터링
      .map((menu) => {
        const indent = "　".repeat(Math.max(0, menu.lev || 0));
        const menuId = menu.objid!.toString(); // 이미 필터링했으므로 non-null assertion 사용

        return (
          <SelectItem key={menuId} value={menuId}>
            {indent}
            {menu.menu_name_kor}
          </SelectItem>
        );
      });
  };

  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-green-100">
                    <svg className="h-5 w-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                    </svg>
                  </div>
                  화면 할당 완료
                </DialogTitle>
                <DialogDescription>화면이 성공적으로 메뉴에 할당되었습니다.</DialogDescription>
              </DialogHeader>

              <div className="space-y-4">
                <div className="rounded-lg border bg-green-50 p-4">
                  <div className="flex items-center gap-3">
                    <div className="flex h-10 w-10 items-center justify-center rounded-full bg-green-100">
                      <Monitor className="h-5 w-5 text-green-600" />
                    </div>
                    <div className="flex-1">
                      <p className="text-sm font-medium text-green-900">{assignmentMessage}</p>
                      <p className="mt-1 text-xs text-green-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-green-500 [animation-delay:-0.3s]"></div>
                  <div className="h-2 w-2 animate-bounce rounded-full bg-green-500 [animation-delay:-0.15s]"></div>
                  <div className="h-2 w-2 animate-bounce rounded-full bg-green-500"></div>
                </div>
              </div>

              <DialogFooter>
                <Button
                  onClick={() => {
                    if (onBackToList) {
                      onBackToList();
                    } else {
                      onClose();
                    }
                  }}
                  className="bg-green-600 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="mt-2 rounded-lg border bg-blue-50 p-3">
                    <div className="flex items-center gap-2">
                      <Monitor className="h-4 w-4 text-blue-600" />
                      <span className="font-medium text-blue-900">{screenInfo.screenName}</span>
                      <Badge variant="outline" className="font-mono text-xs">
                        {screenInfo.screenCode}
                      </Badge>
                    </div>
                    {screenInfo.description && <p className="mt-1 text-sm text-blue-700">{screenInfo.description}</p>}
                  </div>
                )}
              </DialogHeader>

              <div className="space-y-4">
                {/* 메뉴 선택 (검색 기능 포함) */}
                <div>
                  <Label htmlFor="menu-select">할당할 메뉴 선택</Label>
                  <Select value={selectedMenuId} onValueChange={handleMenuSelect} disabled={loading}>
                    <SelectTrigger>
                      <SelectValue placeholder={loading ? "메뉴 로딩 중..." : "메뉴를 선택하세요"} />
                    </SelectTrigger>
                    <SelectContent className="max-h-64">
                      {/* 검색 입력 필드 */}
                      <div className="sticky top-0 z-10 border-b bg-white p-2">
                        <div className="relative">
                          <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-gray-400" />
                          <Input
                            placeholder="메뉴명, URL, 설명으로 검색..."
                            value={searchTerm}
                            onChange={(e) => {
                              e.stopPropagation(); // 이벤트 전파 방지
                              setSearchTerm(e.target.value);
                            }}
                            onKeyDown={(e) => {
                              e.stopPropagation(); // 키보드 이벤트 전파 방지
                            }}
                            onClick={(e) => {
                              e.stopPropagation(); // 클릭 이벤트 전파 방지
                            }}
                            className="h-8 pr-8 pl-10 text-sm"
                          />
                          {searchTerm && (
                            <button
                              type="button"
                              onClick={(e) => {
                                e.stopPropagation();
                                setSearchTerm("");
                              }}
                              className="absolute top-1/2 right-2 h-4 w-4 -translate-y-1/2 transform text-gray-400 hover:text-gray-600"
                            >
                              <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-gray-50 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="default">관리자</Badge>
                          <Badge variant={selectedMenu.status === "active" ? "default" : "outline"}>
                            {selectedMenu.status === "active" ? "활성" : "비활성"}
                          </Badge>
                        </div>
                        <div className="mt-1 space-y-1 text-sm text-gray-600">
                          {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-yellow-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-yellow-600">새 화면을 할당하면 기존 화면들이 제거됩니다.</p>
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>

              <DialogFooter className="flex gap-2">
                <Button
                  variant="outline"
                  onClick={() => {
                    if (onBackToList) {
                      onBackToList();
                    } else {
                      onClose();
                    }
                  }}
                  disabled={assigning}
                >
                  <X className="mr-2 h-4 w-4" />
                  나중에 할당
                </Button>
                <Button
                  onClick={handleAssignScreen}
                  disabled={!selectedMenu || assigning}
                  className="bg-blue-600 hover:bg-blue-700"
                >
                  {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-orange-600" />
              화면 교체 확인
            </DialogTitle>
            <DialogDescription>선택한 메뉴에 이미 할당된 화면이 있습니다.</DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            {/* 기존 화면 목록 */}
            <div className="rounded-lg border bg-red-50 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-red-700">
                    <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-green-50 p-3">
                <p className="mb-2 text-sm font-medium text-green-800">새로 할당될 화면:</p>
                <div className="flex items-center gap-2 text-sm text-green-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-orange-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 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>
    </>
  );
};
