"use client";

import React, { useState, useCallback, useEffect } from "react";
import { ComponentRendererProps } from "../../types";
import { SplitPanelLayoutConfig } from "./types";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Plus, Search, GripVertical, Loader2, ChevronDown, ChevronUp } from "lucide-react";
import { dataApi } from "@/lib/api/data";
import { useToast } from "@/hooks/use-toast";
import { tableTypeApi } from "@/lib/api/screen";

export interface SplitPanelLayoutComponentProps extends ComponentRendererProps {
  // 추가 props
}

/**
 * SplitPanelLayout 컴포넌트
 * 마스터-디테일 패턴의 좌우 분할 레이아웃
 */
export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps> = ({
  component,
  isDesignMode = false,
  isSelected = false,
  onClick,
  ...props
}) => {
  const componentConfig = (component.componentConfig || {}) as SplitPanelLayoutConfig;

  // 기본 설정값
  const splitRatio = componentConfig.splitRatio || 30;
  const resizable = componentConfig.resizable ?? true;
  const minLeftWidth = componentConfig.minLeftWidth || 200;
  const minRightWidth = componentConfig.minRightWidth || 300;

  // 데이터 상태
  const [leftData, setLeftData] = useState<any[]>([]);
  const [rightData, setRightData] = useState<any[] | any>(null); // 조인 모드는 배열, 상세 모드는 객체
  const [selectedLeftItem, setSelectedLeftItem] = useState<any>(null);
  const [expandedRightItems, setExpandedRightItems] = useState<Set<string | number>>(new Set()); // 확장된 우측 아이템
  const [leftSearchQuery, setLeftSearchQuery] = useState("");
  const [rightSearchQuery, setRightSearchQuery] = useState("");
  const [isLoadingLeft, setIsLoadingLeft] = useState(false);
  const [isLoadingRight, setIsLoadingRight] = useState(false);
  const [rightTableColumns, setRightTableColumns] = useState<any[]>([]); // 우측 테이블 컬럼 정보
  const { toast } = useToast();

  // 리사이저 드래그 상태
  const [isDragging, setIsDragging] = useState(false);
  const [leftWidth, setLeftWidth] = useState(splitRatio);
  const containerRef = React.useRef<HTMLDivElement>(null);

  // 컴포넌트 스타일
  const componentStyle: React.CSSProperties = {
    position: "absolute",
    left: `${component.style?.positionX || 0}px`,
    top: `${component.style?.positionY || 0}px`,
    width: `${component.style?.width || 1000}px`,
    height: `${component.style?.height || 600}px`,
    zIndex: component.style?.positionZ || 1,
    cursor: isDesignMode ? "pointer" : "default",
    border: isSelected ? "2px solid #3b82f6" : "1px solid #e5e7eb",
  };

  // 좌측 데이터 로드
  const loadLeftData = useCallback(async () => {
    const leftTableName = componentConfig.leftPanel?.tableName;
    if (!leftTableName || isDesignMode) return;

    setIsLoadingLeft(true);
    try {
      const result = await dataApi.getTableData(leftTableName, {
        page: 1,
        size: 100,
        // searchTerm 제거 - 클라이언트 사이드에서 필터링
      });
      setLeftData(result.data);
    } catch (error) {
      console.error("좌측 데이터 로드 실패:", error);
      toast({
        title: "데이터 로드 실패",
        description: "좌측 패널 데이터를 불러올 수 없습니다.",
        variant: "destructive",
      });
    } finally {
      setIsLoadingLeft(false);
    }
  }, [componentConfig.leftPanel?.tableName, isDesignMode, toast]);

  // 우측 데이터 로드
  const loadRightData = useCallback(
    async (leftItem: any) => {
      const relationshipType = componentConfig.rightPanel?.relation?.type || "detail";
      const rightTableName = componentConfig.rightPanel?.tableName;

      if (!rightTableName || isDesignMode) return;

      setIsLoadingRight(true);
      try {
        if (relationshipType === "detail") {
          // 상세 모드: 동일 테이블의 상세 정보
          const primaryKey = leftItem.id || leftItem.ID || Object.values(leftItem)[0];
          const detail = await dataApi.getRecordDetail(rightTableName, primaryKey);
          setRightData(detail);
        } else if (relationshipType === "join") {
          // 조인 모드: 다른 테이블의 관련 데이터 (여러 개)
          const leftColumn = componentConfig.rightPanel?.relation?.leftColumn;
          const rightColumn = componentConfig.rightPanel?.relation?.foreignKey;
          const leftTable = componentConfig.leftPanel?.tableName;

          if (leftColumn && rightColumn && leftTable) {
            const leftValue = leftItem[leftColumn];
            const joinedData = await dataApi.getJoinedData(
              leftTable,
              rightTableName,
              leftColumn,
              rightColumn,
              leftValue,
            );
            setRightData(joinedData || []); // 모든 관련 레코드 (배열)
          }
        }
      } catch (error) {
        console.error("우측 데이터 로드 실패:", error);
        toast({
          title: "데이터 로드 실패",
          description: "우측 패널 데이터를 불러올 수 없습니다.",
          variant: "destructive",
        });
      } finally {
        setIsLoadingRight(false);
      }
    },
    [
      componentConfig.rightPanel?.tableName,
      componentConfig.rightPanel?.relation,
      componentConfig.leftPanel?.tableName,
      isDesignMode,
      toast,
    ],
  );

  // 좌측 항목 선택 핸들러
  const handleLeftItemSelect = useCallback(
    (item: any) => {
      setSelectedLeftItem(item);
      setExpandedRightItems(new Set()); // 좌측 항목 변경 시 우측 확장 초기화
      loadRightData(item);
    },
    [loadRightData],
  );

  // 우측 항목 확장/축소 토글
  const toggleRightItemExpansion = useCallback((itemId: string | number) => {
    setExpandedRightItems((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(itemId)) {
        newSet.delete(itemId);
      } else {
        newSet.add(itemId);
      }
      return newSet;
    });
  }, []);

  // 컬럼명을 라벨로 변환하는 함수
  const getColumnLabel = useCallback(
    (columnName: string) => {
      const column = rightTableColumns.find((col) => col.columnName === columnName || col.column_name === columnName);
      return column?.columnLabel || column?.column_label || column?.displayName || columnName;
    },
    [rightTableColumns],
  );

  // 우측 테이블 컬럼 정보 로드
  useEffect(() => {
    const loadRightTableColumns = async () => {
      const rightTableName = componentConfig.rightPanel?.tableName;
      if (!rightTableName || isDesignMode) return;

      try {
        const columnsResponse = await tableTypeApi.getColumns(rightTableName);
        setRightTableColumns(columnsResponse || []);
      } catch (error) {
        console.error("우측 테이블 컬럼 정보 로드 실패:", error);
      }
    };

    loadRightTableColumns();
  }, [componentConfig.rightPanel?.tableName, isDesignMode]);

  // 초기 데이터 로드
  useEffect(() => {
    if (!isDesignMode && componentConfig.autoLoad !== false) {
      loadLeftData();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isDesignMode, componentConfig.autoLoad]);

  // 리사이저 드래그 핸들러
  const handleMouseDown = (e: React.MouseEvent) => {
    if (!resizable) return;
    setIsDragging(true);
    e.preventDefault();
  };

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (!isDragging || !containerRef.current) return;

      const containerRect = containerRef.current.getBoundingClientRect();
      const containerWidth = containerRect.width;
      const relativeX = e.clientX - containerRect.left;
      const newLeftWidth = (relativeX / containerWidth) * 100;

      // 최소/최대 너비 제한 (20% ~ 80%)
      if (newLeftWidth >= 20 && newLeftWidth <= 80) {
        setLeftWidth(newLeftWidth);
      }
    },
    [isDragging],
  );

  const handleMouseUp = useCallback(() => {
    setIsDragging(false);
  }, []);

  React.useEffect(() => {
    if (isDragging) {
      // 드래그 중에는 텍스트 선택 방지
      document.body.style.userSelect = "none";
      document.body.style.cursor = "col-resize";

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);

      return () => {
        document.body.style.userSelect = "";
        document.body.style.cursor = "";
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };
    }
  }, [isDragging, handleMouseMove, handleMouseUp]);

  return (
    <div
      ref={containerRef}
      style={componentStyle}
      onClick={(e) => {
        if (isDesignMode) {
          e.stopPropagation();
          onClick?.(e);
        }
      }}
      className="flex overflow-hidden rounded-lg bg-white shadow-sm"
    >
      {/* 좌측 패널 */}
      <div
        style={{ width: `${leftWidth}%`, minWidth: `${minLeftWidth}px` }}
        className="flex flex-col border-r border-gray-200"
      >
        <Card className="flex h-full flex-col border-0 shadow-none">
          <CardHeader className="border-b border-gray-100 pb-3">
            <div className="flex items-center justify-between">
              <CardTitle className="text-base font-semibold">
                {componentConfig.leftPanel?.title || "좌측 패널"}
              </CardTitle>
              {componentConfig.leftPanel?.showAdd && (
                <Button size="sm" variant="outline">
                  <Plus className="mr-1 h-4 w-4" />
                  추가
                </Button>
              )}
            </div>
            {componentConfig.leftPanel?.showSearch && (
              <div className="relative mt-2">
                <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
                <Input
                  placeholder="검색..."
                  value={leftSearchQuery}
                  onChange={(e) => setLeftSearchQuery(e.target.value)}
                  className="pl-9"
                />
              </div>
            )}
          </CardHeader>
          <CardContent className="flex-1 overflow-auto p-2">
            {/* 좌측 데이터 목록 */}
            <div className="space-y-1">
              {isDesignMode ? (
                // 디자인 모드: 샘플 데이터
                <>
                  <div
                    onClick={() => handleLeftItemSelect({ id: 1, name: "항목 1" })}
                    className={`cursor-pointer rounded-md p-3 transition-colors hover:bg-gray-50 ${
                      selectedLeftItem?.id === 1 ? "bg-blue-50 text-blue-700" : "text-gray-700"
                    }`}
                  >
                    <div className="font-medium">항목 1</div>
                    <div className="text-xs text-gray-500">설명 텍스트</div>
                  </div>
                  <div
                    onClick={() => handleLeftItemSelect({ id: 2, name: "항목 2" })}
                    className={`cursor-pointer rounded-md p-3 transition-colors hover:bg-gray-50 ${
                      selectedLeftItem?.id === 2 ? "bg-blue-50 text-blue-700" : "text-gray-700"
                    }`}
                  >
                    <div className="font-medium">항목 2</div>
                    <div className="text-xs text-gray-500">설명 텍스트</div>
                  </div>
                  <div
                    onClick={() => handleLeftItemSelect({ id: 3, name: "항목 3" })}
                    className={`cursor-pointer rounded-md p-3 transition-colors hover:bg-gray-50 ${
                      selectedLeftItem?.id === 3 ? "bg-blue-50 text-blue-700" : "text-gray-700"
                    }`}
                  >
                    <div className="font-medium">항목 3</div>
                    <div className="text-xs text-gray-500">설명 텍스트</div>
                  </div>
                </>
              ) : isLoadingLeft ? (
                // 로딩 중
                <div className="flex items-center justify-center py-8">
                  <Loader2 className="h-6 w-6 animate-spin text-blue-500" />
                  <span className="ml-2 text-sm text-gray-500">데이터를 불러오는 중...</span>
                </div>
              ) : (
                (() => {
                  // 검색 필터링 (클라이언트 사이드)
                  const filteredLeftData = leftSearchQuery
                    ? leftData.filter((item) => {
                        const searchLower = leftSearchQuery.toLowerCase();
                        return Object.entries(item).some(([key, value]) => {
                          if (value === null || value === undefined) return false;
                          return String(value).toLowerCase().includes(searchLower);
                        });
                      })
                    : leftData;

                  return filteredLeftData.length > 0 ? (
                    // 실제 데이터 표시
                    filteredLeftData.map((item, index) => {
                      const itemId = item.id || item.ID || item[Object.keys(item)[0]] || index;
                      const isSelected =
                        selectedLeftItem && (selectedLeftItem.id === itemId || selectedLeftItem === item);
                      // 첫 번째 2-3개 필드를 표시
                      const keys = Object.keys(item).filter((k) => k !== "id" && k !== "ID");
                      const displayTitle = item[keys[0]] || item.name || item.title || `항목 ${index + 1}`;
                      const displaySubtitle = keys[1] ? item[keys[1]] : null;

                      return (
                        <div
                          key={itemId}
                          onClick={() => handleLeftItemSelect(item)}
                          className={`cursor-pointer rounded-md p-3 transition-colors hover:bg-gray-50 ${
                            isSelected ? "bg-blue-50 text-blue-700" : "text-gray-700"
                          }`}
                        >
                          <div className="truncate font-medium">{displayTitle}</div>
                          {displaySubtitle && <div className="truncate text-xs text-gray-500">{displaySubtitle}</div>}
                        </div>
                      );
                    })
                  ) : (
                    // 검색 결과 없음
                    <div className="py-8 text-center text-sm text-gray-500">
                      {leftSearchQuery ? (
                        <>
                          <p>검색 결과가 없습니다.</p>
                          <p className="mt-1 text-xs text-gray-400">다른 검색어를 입력해보세요.</p>
                        </>
                      ) : (
                        "데이터가 없습니다."
                      )}
                    </div>
                  );
                })()
              )}
            </div>
          </CardContent>
        </Card>
      </div>

      {/* 리사이저 */}
      {resizable && (
        <div
          onMouseDown={handleMouseDown}
          className="group flex w-1 cursor-col-resize items-center justify-center bg-gray-200 transition-colors hover:bg-blue-400"
        >
          <GripVertical className="h-4 w-4 text-gray-400 group-hover:text-white" />
        </div>
      )}

      {/* 우측 패널 */}
      <div style={{ width: `${100 - leftWidth}%`, minWidth: `${minRightWidth}px` }} className="flex flex-col">
        <Card className="flex h-full flex-col border-0 shadow-none">
          <CardHeader className="border-b border-gray-100 pb-3">
            <div className="flex items-center justify-between">
              <CardTitle className="text-base font-semibold">
                {componentConfig.rightPanel?.title || "우측 패널"}
              </CardTitle>
              {componentConfig.rightPanel?.showAdd && (
                <Button size="sm" variant="outline">
                  <Plus className="mr-1 h-4 w-4" />
                  추가
                </Button>
              )}
            </div>
            {componentConfig.rightPanel?.showSearch && (
              <div className="relative mt-2">
                <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
                <Input
                  placeholder="검색..."
                  value={rightSearchQuery}
                  onChange={(e) => setRightSearchQuery(e.target.value)}
                  className="pl-9"
                />
              </div>
            )}
          </CardHeader>
          <CardContent className="flex-1 overflow-auto p-4">
            {/* 우측 데이터 */}
            {isLoadingRight ? (
              // 로딩 중
              <div className="flex h-full items-center justify-center">
                <div className="text-center">
                  <Loader2 className="mx-auto h-8 w-8 animate-spin text-blue-500" />
                  <p className="mt-2 text-sm text-gray-500">데이터를 불러오는 중...</p>
                </div>
              </div>
            ) : rightData ? (
              // 실제 데이터 표시
              Array.isArray(rightData) ? (
                // 조인 모드: 여러 데이터를 테이블/리스트로 표시
                (() => {
                  // 검색 필터링
                  const filteredData = rightSearchQuery
                    ? rightData.filter((item) => {
                        const searchLower = rightSearchQuery.toLowerCase();
                        return Object.entries(item).some(([key, value]) => {
                          if (value === null || value === undefined) return false;
                          return String(value).toLowerCase().includes(searchLower);
                        });
                      })
                    : rightData;

                  return filteredData.length > 0 ? (
                    <div className="space-y-2">
                      <div className="mb-2 text-xs text-gray-500">
                        {filteredData.length}개의 관련 데이터
                        {rightSearchQuery && filteredData.length !== rightData.length && (
                          <span className="ml-1 text-blue-600">(전체 {rightData.length}개 중)</span>
                        )}
                      </div>
                      {filteredData.map((item, index) => {
                        const itemId = item.id || item.ID || index;
                        const isExpanded = expandedRightItems.has(itemId);
                        const firstValues = Object.entries(item)
                          .filter(([key]) => !key.toLowerCase().includes("id"))
                          .slice(0, 3);
                        const allValues = Object.entries(item).filter(
                          ([key, value]) => value !== null && value !== undefined && value !== "",
                        );

                        return (
                          <div
                            key={itemId}
                            className="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm transition-all hover:shadow-md"
                          >
                            {/* 요약 정보 (클릭 가능) */}
                            <div
                              onClick={() => toggleRightItemExpansion(itemId)}
                              className="cursor-pointer p-3 transition-colors hover:bg-gray-50"
                            >
                              <div className="flex items-start justify-between gap-2">
                                <div className="min-w-0 flex-1">
                                  {firstValues.map(([key, value], idx) => (
                                    <div key={key} className="mb-1 last:mb-0">
                                      <div className="text-xs font-medium text-gray-500">{getColumnLabel(key)}</div>
                                      <div className="truncate text-sm text-gray-900" title={String(value || "-")}>
                                        {String(value || "-")}
                                      </div>
                                    </div>
                                  ))}
                                </div>
                                <div className="flex flex-shrink-0 items-start pt-1">
                                  {isExpanded ? (
                                    <ChevronUp className="h-5 w-5 text-gray-400" />
                                  ) : (
                                    <ChevronDown className="h-5 w-5 text-gray-400" />
                                  )}
                                </div>
                              </div>
                            </div>

                            {/* 상세 정보 (확장 시 표시) */}
                            {isExpanded && (
                              <div className="border-t border-gray-200 bg-gray-50 px-3 py-2">
                                <div className="mb-2 text-xs font-semibold text-gray-700">전체 상세 정보</div>
                                <div className="overflow-auto rounded-md border border-gray-200 bg-white">
                                  <table className="w-full text-sm">
                                    <tbody className="divide-y divide-gray-200">
                                      {allValues.map(([key, value]) => (
                                        <tr key={key} className="hover:bg-gray-50">
                                          <td className="px-3 py-2 font-medium whitespace-nowrap text-gray-600">
                                            {getColumnLabel(key)}
                                          </td>
                                          <td className="px-3 py-2 break-all text-gray-900">{String(value)}</td>
                                        </tr>
                                      ))}
                                    </tbody>
                                  </table>
                                </div>
                              </div>
                            )}
                          </div>
                        );
                      })}
                    </div>
                  ) : (
                    <div className="py-8 text-center text-sm text-gray-500">
                      {rightSearchQuery ? (
                        <>
                          <p>검색 결과가 없습니다.</p>
                          <p className="mt-1 text-xs text-gray-400">다른 검색어를 입력해보세요.</p>
                        </>
                      ) : (
                        "관련 데이터가 없습니다."
                      )}
                    </div>
                  );
                })()
              ) : (
                // 상세 모드: 단일 객체를 상세 정보로 표시
                <div className="space-y-2">
                  {Object.entries(rightData).map(([key, value]) => {
                    // null, undefined, 빈 문자열 제외
                    if (value === null || value === undefined || value === "") return null;

                    return (
                      <div key={key} className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
                        <div className="mb-1 text-xs font-semibold tracking-wide text-gray-500 uppercase">{key}</div>
                        <div className="text-sm text-gray-900">{String(value)}</div>
                      </div>
                    );
                  })}
                </div>
              )
            ) : selectedLeftItem && isDesignMode ? (
              // 디자인 모드: 샘플 데이터
              <div className="space-y-4">
                <div className="rounded-lg border border-gray-200 p-4">
                  <h3 className="mb-2 font-medium text-gray-900">{selectedLeftItem.name} 상세 정보</h3>
                  <div className="space-y-2 text-sm">
                    <div className="flex justify-between">
                      <span className="text-gray-600">항목 1:</span>
                      <span className="font-medium">값 1</span>
                    </div>
                    <div className="flex justify-between">
                      <span className="text-gray-600">항목 2:</span>
                      <span className="font-medium">값 2</span>
                    </div>
                    <div className="flex justify-between">
                      <span className="text-gray-600">항목 3:</span>
                      <span className="font-medium">값 3</span>
                    </div>
                  </div>
                </div>
              </div>
            ) : (
              // 선택 없음
              <div className="flex h-full items-center justify-center">
                <div className="text-center text-sm text-gray-500">
                  <p className="mb-2">좌측에서 항목을 선택하세요</p>
                  <p className="text-xs">선택한 항목의 상세 정보가 여기에 표시됩니다</p>
                </div>
              </div>
            )}
          </CardContent>
        </Card>
      </div>
    </div>
  );
};

/**
 * SplitPanelLayout 래퍼 컴포넌트
 */
export const SplitPanelLayoutWrapper: React.FC<SplitPanelLayoutComponentProps> = (props) => {
  return <SplitPanelLayoutComponent {...props} />;
};
