"use client";

import { useState, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { LoadingSpinner } from "@/components/common/LoadingSpinner";
import { CodeFormModal } from "./CodeFormModal";
import { SortableCodeItem } from "./SortableCodeItem";
import { AlertModal } from "@/components/common/AlertModal";
import { Search, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { useDeleteCode, useReorderCodes } from "@/hooks/queries/useCodes";
import { useCodesInfinite } from "@/hooks/queries/useCodesInfinite";
import type { CodeInfo } from "@/types/commonCode";

// Drag and Drop
import { DndContext, DragOverlay } from "@dnd-kit/core";
import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import { useDragAndDrop } from "@/hooks/useDragAndDrop";
import { useSearchAndFilter } from "@/hooks/useSearchAndFilter";

interface CodeDetailPanelProps {
  categoryCode: string;
}

export function CodeDetailPanel({ categoryCode }: CodeDetailPanelProps) {
  // 검색 및 필터 상태 (먼저 선언)
  const [searchTerm, setSearchTerm] = useState("");
  const [showActiveOnly, setShowActiveOnly] = useState(false);

  // React Query로 코드 데이터 관리 (무한 스크롤)
  const {
    data: codes = [],
    isLoading,
    error,
    handleScroll,
    isFetchingNextPage,
    hasNextPage,
  } = useCodesInfinite(categoryCode, {
    search: searchTerm || undefined,
    active: showActiveOnly || undefined,
  });
  const deleteCodeMutation = useDeleteCode();
  const reorderCodesMutation = useReorderCodes();

  // 드래그앤드롭을 위해 필터링된 코드 목록 사용
  const { filteredItems: filteredCodesRaw } = useSearchAndFilter(codes, {
    searchFields: ["code_name", "code_value"],
  });

  // 계층 구조로 정렬 (부모 → 자식 순서)
  const filteredCodes = useMemo(() => {
    if (!filteredCodesRaw || filteredCodesRaw.length === 0) return [];

    // 코드를 계층 순서로 정렬하는 함수
    const sortHierarchically = (codes: CodeInfo[]): CodeInfo[] => {
      const result: CodeInfo[] = [];
      const codeMap = new Map<string, CodeInfo>();
      const childrenMap = new Map<string, CodeInfo[]>();

      // 코드 맵 생성
      codes.forEach((code) => {
        const codeValue = code.codeValue || code.code_value || "";
        const parentValue = code.parentCodeValue || code.parent_code_value;
        codeMap.set(codeValue, code);

        if (parentValue) {
          if (!childrenMap.has(parentValue)) {
            childrenMap.set(parentValue, []);
          }
          childrenMap.get(parentValue)!.push(code);
        }
      });

      // 재귀적으로 트리 구조 순회
      const traverse = (parentValue: string | null, depth: number) => {
        const children = parentValue
          ? childrenMap.get(parentValue) || []
          : codes.filter((c) => !c.parentCodeValue && !c.parent_code_value);

        // 정렬 순서로 정렬
        children
          .sort((a, b) => (a.sortOrder || a.sort_order || 0) - (b.sortOrder || b.sort_order || 0))
          .forEach((code) => {
            result.push(code);
            const codeValue = code.codeValue || code.code_value || "";
            traverse(codeValue, depth + 1);
          });
      };

      traverse(null, 1);

      // 트리에 포함되지 않은 코드들도 추가 (orphan 코드)
      codes.forEach((code) => {
        if (!result.includes(code)) {
          result.push(code);
        }
      });

      return result;
    };

    return sortHierarchically(filteredCodesRaw);
  }, [filteredCodesRaw]);

  // 모달 상태
  const [showFormModal, setShowFormModal] = useState(false);
  const [editingCode, setEditingCode] = useState<CodeInfo | null>(null);
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [deletingCode, setDeletingCode] = useState<CodeInfo | null>(null);
  const [defaultParentCode, setDefaultParentCode] = useState<string | undefined>(undefined);

  // 트리 접기/펼치기 상태 (코드값 Set)
  const [collapsedCodes, setCollapsedCodes] = useState<Set<string>>(new Set());

  // 자식 정보 계산
  const childrenMap = useMemo(() => {
    const map = new Map<string, CodeInfo[]>();
    codes.forEach((code) => {
      const parentValue = code.parentCodeValue || code.parent_code_value;
      if (parentValue) {
        if (!map.has(parentValue)) {
          map.set(parentValue, []);
        }
        map.get(parentValue)!.push(code);
      }
    });
    return map;
  }, [codes]);

  // 접기/펼치기 토글
  const toggleExpand = (codeValue: string) => {
    setCollapsedCodes((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(codeValue)) {
        newSet.delete(codeValue);
      } else {
        newSet.add(codeValue);
      }
      return newSet;
    });
  };

  // 특정 코드가 표시되어야 하는지 확인 (부모가 접혀있으면 숨김)
  const isCodeVisible = (code: CodeInfo): boolean => {
    const parentValue = code.parentCodeValue || code.parent_code_value;
    if (!parentValue) return true; // 최상위 코드는 항상 표시

    // 부모가 접혀있으면 숨김
    if (collapsedCodes.has(parentValue)) return false;

    // 부모의 부모도 확인 (재귀적으로)
    const parentCode = codes.find((c) => (c.codeValue || c.code_value) === parentValue);
    if (parentCode) {
      return isCodeVisible(parentCode);
    }

    return true;
  };

  // 표시할 코드 목록 (접힌 상태 반영)
  const visibleCodes = useMemo(() => {
    return filteredCodes.filter(isCodeVisible);
  }, [filteredCodes, collapsedCodes, codes]);

  // 드래그 앤 드롭 훅 사용
  const dragAndDrop = useDragAndDrop<CodeInfo>({
    items: filteredCodes,
    onReorder: async (reorderedItems) => {
      await reorderCodesMutation.mutateAsync({
        categoryCode,
        codes: reorderedItems.map((item) => ({
          codeValue: item.id,
          sortOrder: item.sortOrder,
        })),
      });
    },
    getItemId: (code: CodeInfo) => code.codeValue || code.code_value,
  });

  // 새 코드 생성
  const handleNewCode = () => {
    setEditingCode(null);
    setDefaultParentCode(undefined);
    setShowFormModal(true);
  };

  // 코드 수정
  const handleEditCode = (code: CodeInfo) => {
    setEditingCode(code);
    setDefaultParentCode(undefined);
    setShowFormModal(true);
  };

  // 하위 코드 추가
  const handleAddChild = (parentCode: CodeInfo) => {
    setEditingCode(null);
    setDefaultParentCode(parentCode.codeValue || parentCode.code_value || "");
    setShowFormModal(true);
  };

  // 코드 삭제 확인
  const handleDeleteCode = (code: CodeInfo) => {
    setDeletingCode(code);
    setShowDeleteModal(true);
  };

  // 코드 삭제 실행
  const handleConfirmDelete = async () => {
    if (!deletingCode) return;

    try {
      await deleteCodeMutation.mutateAsync({
        categoryCode,
        codeValue: deletingCode.codeValue || deletingCode.code_value,
      });

      setShowDeleteModal(false);
      setDeletingCode(null);
    } catch (error) {
      console.error("코드 삭제 실패:", error);
    }
  };

  // 드래그 앤 드롭 로직은 useDragAndDrop 훅에서 처리

  if (!categoryCode) {
    return (
      <div className="flex h-96 items-center justify-center">
        <p className="text-muted-foreground text-sm">카테고리를 선택하세요</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex h-96 items-center justify-center">
        <div className="text-center">
          <p className="text-destructive text-sm font-semibold">코드를 불러오는 중 오류가 발생했습니다.</p>
          <Button variant="outline" onClick={() => window.location.reload()} className="mt-4 h-10 text-sm font-medium">
            다시 시도
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex h-full flex-col space-y-4">
      {/* 검색 및 액션 */}
      <div className="space-y-3">
        {/* 검색 + 버튼 */}
        <div className="flex items-center gap-2">
          <div className="relative w-full sm:w-[300px]">
            <Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
            <Input
              placeholder="코드 검색..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="h-10 pl-10 text-sm"
            />
          </div>
          <Button onClick={handleNewCode} className="h-10 gap-2 text-sm font-medium">
            <Plus className="h-4 w-4" />
            등록
          </Button>
        </div>

        {/* 활성 필터 */}
        <div className="flex items-center gap-2">
          <input
            type="checkbox"
            id="activeOnlyCodes"
            checked={showActiveOnly}
            onChange={(e) => setShowActiveOnly(e.target.checked)}
            className="border-input h-4 w-4 rounded"
          />
          <label htmlFor="activeOnlyCodes" className="text-muted-foreground text-sm">
            활성만 표시
          </label>
        </div>
      </div>

      {/* 코드 목록 (무한 스크롤) */}
      <div className="space-y-3" onScroll={handleScroll}>
        {isLoading ? (
          <div className="flex h-32 items-center justify-center">
            <LoadingSpinner />
          </div>
        ) : visibleCodes.length === 0 ? (
          <div className="flex h-32 items-center justify-center">
            <p className="text-muted-foreground text-sm">
              {codes.length === 0 ? "코드가 없습니다." : "검색 결과가 없습니다."}
            </p>
          </div>
        ) : (
          <>
            <DndContext {...dragAndDrop.dndContextProps}>
              <SortableContext
                items={visibleCodes.map((code) => code.codeValue || code.code_value)}
                strategy={verticalListSortingStrategy}
              >
                {visibleCodes.map((code, index) => {
                  const codeValue = code.codeValue || code.code_value || "";
                  const children = childrenMap.get(codeValue) || [];
                  const hasChildren = children.length > 0;
                  const isExpanded = !collapsedCodes.has(codeValue);

                  return (
                    <SortableCodeItem
                      key={`${codeValue}-${index}`}
                      code={code}
                      categoryCode={categoryCode}
                      onEdit={() => handleEditCode(code)}
                      onDelete={() => handleDeleteCode(code)}
                      onAddChild={() => handleAddChild(code)}
                      hasChildren={hasChildren}
                      childCount={children.length}
                      isExpanded={isExpanded}
                      onToggleExpand={() => toggleExpand(codeValue)}
                    />
                  );
                })}
              </SortableContext>

              <DragOverlay dropAnimation={null}>
                {dragAndDrop.activeItem ? (
                  <div className="bg-card cursor-grabbing rounded-lg border p-4 shadow-lg">
                    {(() => {
                      const activeCode = dragAndDrop.activeItem;
                      if (!activeCode) return null;
                      return (
                        <div className="flex items-start justify-between">
                          <div className="min-w-0 flex-1">
                            <div className="flex items-center gap-2">
                              <h4 className="text-sm font-semibold">{activeCode.codeName || activeCode.code_name}</h4>
                              <Badge
                                variant={
                                  activeCode.isActive === "Y" || activeCode.is_active === "Y" ? "default" : "secondary"
                                }
                              >
                                {activeCode.isActive === "Y" || activeCode.is_active === "Y" ? "활성" : "비활성"}
                              </Badge>
                            </div>
                            <p className="text-muted-foreground mt-1 text-xs">
                              {activeCode.codeValue || activeCode.code_value}
                            </p>
                            {activeCode.description && (
                              <p className="text-muted-foreground mt-1 text-xs">{activeCode.description}</p>
                            )}
                          </div>
                        </div>
                      );
                    })()}
                  </div>
                ) : null}
              </DragOverlay>
            </DndContext>

            {/* 무한 스크롤 로딩 인디케이터 */}
            {isFetchingNextPage && (
              <div className="flex items-center justify-center py-4">
                <LoadingSpinner size="sm" />
                <span className="text-muted-foreground ml-2 text-sm">코드를 더 불러오는 중...</span>
              </div>
            )}

            {/* 모든 코드 로드 완료 메시지 */}
            {!hasNextPage && codes.length > 0 && (
              <div className="text-muted-foreground py-4 text-center text-sm">모든 코드를 불러왔습니다.</div>
            )}
          </>
        )}
      </div>

      {/* 코드 폼 모달 */}
      {showFormModal && (
        <CodeFormModal
          isOpen={showFormModal}
          onClose={() => {
            setShowFormModal(false);
            setEditingCode(null);
            setDefaultParentCode(undefined);
          }}
          categoryCode={categoryCode}
          editingCode={editingCode}
          codes={codes}
          defaultParentCode={defaultParentCode}
        />
      )}

      {/* 삭제 확인 모달 */}
      {showDeleteModal && (
        <AlertModal
          isOpen={showDeleteModal}
          onClose={() => setShowDeleteModal(false)}
          type="error"
          title="코드 삭제"
          message="정말로 이 코드를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다."
          confirmText="삭제"
          onConfirm={handleConfirmDelete}
        />
      )}
    </div>
  );
}
