"use client";

import React, { useState, useEffect, useMemo } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Search, Loader2 } from "lucide-react";
import { useEntitySearch } from "../entity-search-input/useEntitySearch";
import { ItemSelectionModalProps, ModalFilterConfig } from "./types";
import { apiClient } from "@/lib/api/client";
import { getCategoryLabelsByCodes } from "@/lib/api/tableCategoryValue";

export function ItemSelectionModal({
  open,
  onOpenChange,
  sourceTable,
  sourceColumns,
  sourceSearchFields = [],
  multiSelect = true,
  filterCondition = {},
  modalTitle,
  alreadySelected = [],
  uniqueField,
  onSelect,
  columnLabels = {},
  modalFilters = [],
  categoryColumns = [],
}: ItemSelectionModalProps) {
  const [localSearchText, setLocalSearchText] = useState("");
  const [selectedItems, setSelectedItems] = useState<any[]>([]);

  // 모달 필터 값 상태
  const [modalFilterValues, setModalFilterValues] = useState<Record<string, any>>({});

  // 카테고리 옵션 상태 (categoryRef별로 로드된 옵션)
  const [categoryOptions, setCategoryOptions] = useState<Record<string, { value: string; label: string }[]>>({});

  // 카테고리 코드 → 라벨 매핑 (테이블 데이터 표시용)
  const [categoryLabelMap, setCategoryLabelMap] = useState<Record<string, string>>({});

  // 모달 필터 값과 기본 filterCondition을 합친 최종 필터 조건
  const combinedFilterCondition = useMemo(() => {
    const combined = { ...filterCondition };

    // 모달 필터 값 추가 (빈 값은 제외)
    for (const [key, value] of Object.entries(modalFilterValues)) {
      if (value !== undefined && value !== null && value !== "") {
        combined[key] = value;
      }
    }

    return combined;
  }, [filterCondition, modalFilterValues]);

  const { results, loading, error, search, clearSearch } = useEntitySearch({
    tableName: sourceTable,
    searchFields: sourceSearchFields.length > 0 ? sourceSearchFields : sourceColumns,
    filterCondition: combinedFilterCondition,
  });

  // 필터 옵션 로드 - 소스 테이블 컬럼의 distinct 값 조회
  const loadFilterOptions = async (filter: ModalFilterConfig) => {
    // 드롭다운 타입만 옵션 로드 필요 (select, category 지원)
    const isDropdownType = filter.type === "select" || filter.type === "category";
    if (!isDropdownType) return;

    const cacheKey = `${sourceTable}.${filter.column}`;

    // 이미 로드된 경우 스킵
    if (categoryOptions[cacheKey]) return;

    try {
      // 소스 테이블에서 해당 컬럼의 데이터 조회 (POST 메서드 사용)
      // 백엔드는 'size' 파라미터를 사용함
      const response = await apiClient.post(`/table-management/tables/${sourceTable}/data`, {
        page: 1,
        size: 10000, // 모든 데이터 조회를 위해 큰 값 설정
      });

      if (response.data?.success) {
        // 응답 구조에 따라 rows 추출
        const rows = response.data.data?.rows || response.data.data?.data || response.data.data || [];

        if (Array.isArray(rows)) {
          // 컬럼 값 중복 제거
          const uniqueValues = new Set<string>();
          for (const row of rows) {
            const val = row[filter.column];
            if (val !== null && val !== undefined && val !== "") {
              uniqueValues.add(String(val));
            }
          }

          // 🆕 CATEGORY_ 코드가 있는지 확인하고 라벨 조회
          const allCodes = new Set<string>();
          for (const val of uniqueValues) {
            // 콤마로 구분된 다중 값도 처리
            const codes = val.split(",").map((c) => c.trim());
            codes.forEach((code) => {
              if (code.startsWith("CATEGORY_")) {
                allCodes.add(code);
              }
            });
          }

          // CATEGORY_ 코드가 있으면 라벨 조회
          let labelMap: Record<string, string> = {};
          if (allCodes.size > 0) {
            try {
              const labelResponse = await getCategoryLabelsByCodes(Array.from(allCodes));
              if (labelResponse.success && labelResponse.data) {
                labelMap = labelResponse.data;
              }
            } catch (labelError) {
              console.error("카테고리 라벨 조회 실패:", labelError);
            }
          }

          // 정렬 후 옵션으로 변환 (라벨 적용)
          const options = Array.from(uniqueValues)
            .sort()
            .map((val) => {
              // 콤마로 구분된 다중 값 처리
              if (val.includes(",")) {
                const codes = val.split(",").map((c) => c.trim());
                const labels = codes.map((code) => labelMap[code] || code);
                return { value: val, label: labels.join(", ") };
              }
              // 단일 값
              return { value: val, label: labelMap[val] || val };
            });

          setCategoryOptions((prev) => ({
            ...prev,
            [cacheKey]: options,
          }));
        }
      }
    } catch (error) {
      console.error(`필터 옵션 로드 실패 (${cacheKey}):`, error);
      setCategoryOptions((prev) => ({
        ...prev,
        [cacheKey]: [],
      }));
    }
  };

  // 모달 열릴 때 초기 검색 및 필터 초기화
  useEffect(() => {
    if (open) {
      // 모달 필터 기본값 설정 & 옵션 로드
      const initialFilterValues: Record<string, any> = {};
      for (const filter of modalFilters) {
        if (filter.defaultValue !== undefined) {
          initialFilterValues[filter.column] = filter.defaultValue;
        }
        // 드롭다운 타입이면 옵션 로드 (소스 테이블에서 distinct 값 조회)
        const isDropdownType = filter.type === "select" || filter.type === "category";
        if (isDropdownType) {
          loadFilterOptions(filter);
        }
      }
      setModalFilterValues(initialFilterValues);

      search("", 1); // 빈 검색어로 전체 목록 조회
      setSelectedItems([]);
    } else {
      clearSearch();
      setLocalSearchText("");
      setSelectedItems([]);
      setModalFilterValues({});
    }
  }, [open]);

  // 모달 필터 값 변경 시 재검색
  useEffect(() => {
    if (open) {
      search(localSearchText, 1);
    }
  }, [modalFilterValues]);

  // 검색 결과가 변경되면 카테고리 값들의 라벨 조회
  useEffect(() => {
    const loadCategoryLabels = async () => {
      if (!open || categoryColumns.length === 0 || results.length === 0) {
        return;
      }

      // 현재 결과에서 카테고리 컬럼의 모든 고유한 값 수집
      // 쉼표로 구분된 다중 값도 개별적으로 수집
      const allCodes = new Set<string>();
      for (const row of results) {
        for (const col of categoryColumns) {
          const val = row[col];
          if (val && typeof val === "string") {
            // 쉼표로 구분된 다중 값 처리
            const codes = val
              .split(",")
              .map((c) => c.trim())
              .filter(Boolean);
            for (const code of codes) {
              if (!categoryLabelMap[code]) {
                allCodes.add(code);
              }
            }
          }
        }
      }

      if (allCodes.size === 0) {
        return;
      }

      try {
        const response = await apiClient.post("/table-categories/labels-by-codes", {
          valueCodes: Array.from(allCodes),
        });

        if (response.data?.success && response.data.data) {
          setCategoryLabelMap((prev) => ({
            ...prev,
            ...response.data.data,
          }));
        }
      } catch (error) {
        console.error("카테고리 라벨 조회 실패:", error);
      }
    };

    loadCategoryLabels();
  }, [open, results, categoryColumns]);

  // 모달 필터 값 변경 핸들러
  const handleModalFilterChange = (column: string, value: any) => {
    setModalFilterValues((prev) => ({
      ...prev,
      [column]: value,
    }));
  };

  const handleSearch = () => {
    search(localSearchText, 1);
  };

  const handleToggleItem = (item: any) => {
    const itemValue = uniqueField ? item[uniqueField] : undefined;

    if (!multiSelect) {
      setSelectedItems([item]);
      return;
    }

    // uniqueField 값이 undefined인 경우 객체 참조로 비교
    if (uniqueField && (itemValue === undefined || itemValue === null)) {
      console.warn(`⚠️ uniqueField "${uniqueField}"의 값이 undefined입니다. 객체 참조로 비교합니다.`);
      const itemIsSelected = selectedItems.includes(item);

      if (itemIsSelected) {
        const newSelected = selectedItems.filter((selected) => selected !== item);
        setSelectedItems(newSelected);
      } else {
        setSelectedItems([...selectedItems, item]);
      }
      return;
    }

    const itemIsSelected = selectedItems.some((selected) => {
      if (!uniqueField) {
        return selected === item;
      }
      const selectedValue = selected[uniqueField];
      if (selectedValue === undefined || selectedValue === null) {
        return false;
      }
      return selectedValue === itemValue;
    });

    if (itemIsSelected) {
      const newSelected = selectedItems.filter((selected) => {
        if (!uniqueField) {
          return selected !== item;
        }
        const selectedValue = selected[uniqueField];
        if (selectedValue === undefined || selectedValue === null) {
          return true;
        }
        return selectedValue !== itemValue;
      });
      setSelectedItems(newSelected);
    } else {
      setSelectedItems([...selectedItems, item]);
    }
  };

  const handleConfirm = () => {
    console.log("✅ ItemSelectionModal 추가:", selectedItems.length, "개 항목");

    onSelect(selectedItems);
    onOpenChange(false);
  };

  // 이미 추가된 항목인지 확인
  const isAlreadyAdded = (item: any): boolean => {
    if (!uniqueField) return false;
    return alreadySelected.some((selected) => selected[uniqueField] === item[uniqueField]);
  };

  // 이미 추가된 항목 제외한 결과 필터링
  const filteredResults = results.filter((item) => !isAlreadyAdded(item));

  // 선택된 항목인지 확인
  const isSelected = (item: any): boolean => {
    if (!uniqueField) {
      return selectedItems.includes(item);
    }

    const itemValue = item[uniqueField];

    // uniqueField 값이 undefined인 경우 객체 참조로 비교
    if (itemValue === undefined || itemValue === null) {
      return selectedItems.includes(item);
    }

    const result = selectedItems.some((selected) => {
      const selectedValue = selected[uniqueField];

      // selectedValue도 undefined면 안전하게 처리
      if (selectedValue === undefined || selectedValue === null) {
        return false;
      }

      const isMatch = selectedValue === itemValue;

      if (isMatch) {
        console.log("✅ 매칭 발견:", {
          selectedValue,
          itemValue,
          uniqueField,
        });
      }

      return isMatch;
    });

    return result;
  };

  // 유효한 컬럼만 필터링
  const validColumns = sourceColumns.filter((col) => col != null && col !== "");
  const totalColumns = validColumns.length + (multiSelect ? 1 : 0);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="flex max-w-[95vw] flex-col sm:max-w-[900px]">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">{modalTitle}</DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            항목을 검색하고 선택하세요
            {multiSelect && " (다중 선택 가능)"}
          </DialogDescription>
        </DialogHeader>

        {/* 검색 입력 */}
        <div className="flex gap-2">
          <Input
            placeholder="검색어를 입력하세요"
            value={localSearchText}
            onChange={(e) => setLocalSearchText(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") {
                handleSearch();
              }
            }}
            className="h-8 text-xs sm:h-10 sm:text-sm"
          />
          <Button onClick={handleSearch} disabled={loading} className="h-8 text-xs sm:h-10 sm:text-sm">
            {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
            <span className="ml-2">검색</span>
          </Button>
        </div>

        {/* 모달 필터 */}
        {modalFilters.length > 0 && (
          <div className="bg-muted/30 flex flex-wrap items-center gap-3 rounded-md px-1 py-2">
            {modalFilters.map((filter) => {
              // 소스 테이블의 해당 컬럼에서 로드된 옵션
              const options = categoryOptions[`${sourceTable}.${filter.column}`] || [];

              // 드롭다운 타입인지 확인 (select, category 모두 드롭다운으로 처리)
              const isDropdownType = filter.type === "select" || filter.type === "category";

              return (
                <div key={filter.column} className="flex items-center gap-2">
                  <span className="text-muted-foreground text-xs font-medium">{filter.label}:</span>
                  {isDropdownType && (
                    <Select
                      value={modalFilterValues[filter.column] || "__all__"}
                      onValueChange={(value) =>
                        handleModalFilterChange(filter.column, value === "__all__" ? "" : value)
                      }
                    >
                      <SelectTrigger className="h-7 w-[140px] text-xs">
                        <SelectValue placeholder="전체" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="__all__">전체</SelectItem>
                        {options.map((opt) => (
                          <SelectItem key={opt.value} value={opt.value || `__empty_${opt.label}__`}>
                            {opt.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  )}
                  {filter.type === "text" && (
                    <Input
                      value={modalFilterValues[filter.column] || ""}
                      onChange={(e) => handleModalFilterChange(filter.column, e.target.value)}
                      placeholder={filter.label}
                      className="h-7 w-[120px] text-xs"
                    />
                  )}
                </div>
              );
            })}
          </div>
        )}

        {/* 선택된 항목 수 */}
        {selectedItems.length > 0 && (
          <div className="text-primary text-sm">
            {selectedItems.length}개 항목 선택됨
            {uniqueField && (
              <span className="text-muted-foreground ml-2 text-xs">
                ({selectedItems.map((item) => item[uniqueField]).join(", ")})
              </span>
            )}
          </div>
        )}

        {/* 오류 메시지 */}
        {error && <div className="text-destructive bg-destructive/10 rounded-md p-3 text-sm">{error}</div>}

        {/* 검색 결과 테이블 */}
        <div className="min-h-0 flex-1 overflow-hidden rounded-md border">
          <div className="max-h-[50vh] overflow-auto">
            <table className="w-full text-xs sm:text-sm">
              <thead className="bg-muted">
                <tr>
                  {multiSelect && <th className="text-muted-foreground w-12 px-4 py-2 text-left font-medium">선택</th>}
                  {validColumns.map((col) => (
                    <th key={col} className="text-muted-foreground px-4 py-2 text-left font-medium">
                      {columnLabels[col] || col}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {loading && filteredResults.length === 0 ? (
                  <tr>
                    <td colSpan={totalColumns} className="px-4 py-8 text-center">
                      <Loader2 className="mx-auto h-6 w-6 animate-spin" />
                      <p className="text-muted-foreground mt-2">검색 중...</p>
                    </td>
                  </tr>
                ) : filteredResults.length === 0 ? (
                  <tr>
                    <td colSpan={totalColumns} className="text-muted-foreground px-4 py-8 text-center">
                      {results.length > 0 ? "모든 항목이 이미 추가되었습니다" : "검색 결과가 없습니다"}
                    </td>
                  </tr>
                ) : (
                  filteredResults.map((item, index) => {
                    const selected = isSelected(item);
                    // 🔧 index를 조합하여 항상 고유한 key 생성 (중복 데이터 대응)
                    const itemKey = `row-${index}`;

                    return (
                      <tr
                        key={itemKey}
                        className={`border-t transition-colors ${
                          selected ? "bg-primary/10" : "hover:bg-accent cursor-pointer"
                        }`}
                        onClick={() => handleToggleItem(item)}
                      >
                        {multiSelect && (
                          <td
                            className="px-4 py-2"
                            onClick={(e) => {
                              // 체크박스 영역 클릭을 행 클릭으로 전파
                              e.stopPropagation();
                              handleToggleItem(item);
                            }}
                          >
                            <div className="pointer-events-none">
                              <Checkbox checked={selected} />
                            </div>
                          </td>
                        )}
                        {validColumns.map((col) => {
                          const rawValue = item[col];
                          // 카테고리 컬럼이면 라벨로 변환
                          const isCategory = categoryColumns.includes(col);
                          let displayValue = rawValue;

                          if (isCategory && rawValue && typeof rawValue === "string") {
                            // 쉼표로 구분된 다중 값 처리
                            const codes = rawValue
                              .split(",")
                              .map((c) => c.trim())
                              .filter(Boolean);
                            const labels = codes.map((code) => categoryLabelMap[code] || code);
                            displayValue = labels.join(", ");
                          }

                          return (
                            <td key={col} className="px-4 py-2">
                              {displayValue || "-"}
                            </td>
                          );
                        })}
                      </tr>
                    );
                  })
                )}
              </tbody>
            </table>
          </div>
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>
          <Button
            onClick={handleConfirm}
            disabled={selectedItems.length === 0}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            추가 ({selectedItems.length})
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
