"use client";

import React, { useState, useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Settings, Filter, Layers, X } from "lucide-react";
import { useTableOptions } from "@/contexts/TableOptionsContext";
import { useTableSearchWidgetHeight } from "@/contexts/TableSearchWidgetHeightContext";
import { ColumnVisibilityPanel } from "@/components/screen/table-options/ColumnVisibilityPanel";
import { FilterPanel } from "@/components/screen/table-options/FilterPanel";
import { GroupingPanel } from "@/components/screen/table-options/GroupingPanel";
import { TableFilter } from "@/types/table-options";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

interface TableSearchWidgetProps {
  component: {
    id: string;
    title?: string;
    style?: {
      width?: string;
      height?: string;
      padding?: string;
      backgroundColor?: string;
    };
    componentConfig?: {
      autoSelectFirstTable?: boolean; // 첫 번째 테이블 자동 선택 여부
      showTableSelector?: boolean; // 테이블 선택 드롭다운 표시 여부
    };
  };
  screenId?: number; // 화면 ID
  onHeightChange?: (height: number) => void; // 높이 변화 콜백
}

export function TableSearchWidget({ component, screenId, onHeightChange }: TableSearchWidgetProps) {
  const { registeredTables, selectedTableId, setSelectedTableId, getTable } = useTableOptions();
  
  // 높이 관리 context (실제 화면에서만 사용)
  let setWidgetHeight: ((screenId: number, componentId: string, height: number, originalHeight: number) => void) | undefined;
  try {
    const heightContext = useTableSearchWidgetHeight();
    setWidgetHeight = heightContext.setWidgetHeight;
  } catch (e) {
    // Context가 없으면 (디자이너 모드) 무시
    setWidgetHeight = undefined;
  }
  
  const [columnVisibilityOpen, setColumnVisibilityOpen] = useState(false);
  const [filterOpen, setFilterOpen] = useState(false);
  const [groupingOpen, setGroupingOpen] = useState(false);
  
  // 활성화된 필터 목록
  const [activeFilters, setActiveFilters] = useState<TableFilter[]>([]);
  const [filterValues, setFilterValues] = useState<Record<string, string>>({});
  // select 타입 필터의 옵션들
  const [selectOptions, setSelectOptions] = useState<Record<string, Array<{ label: string; value: string }>>>({});
  // 선택된 값의 라벨 저장 (데이터 없을 때도 라벨 유지)
  const [selectedLabels, setSelectedLabels] = useState<Record<string, string>>({});
  
  // 높이 감지를 위한 ref
  const containerRef = useRef<HTMLDivElement>(null);

  const autoSelectFirstTable = component.componentConfig?.autoSelectFirstTable ?? true;
  const showTableSelector = component.componentConfig?.showTableSelector ?? true;

  // Map을 배열로 변환
  const tableList = Array.from(registeredTables.values());
  const currentTable = selectedTableId ? getTable(selectedTableId) : undefined;

  // 첫 번째 테이블 자동 선택
  useEffect(() => {
    const tables = Array.from(registeredTables.values());
    
    if (autoSelectFirstTable && tables.length > 0 && !selectedTableId) {
      setSelectedTableId(tables[0].tableId);
    }
  }, [registeredTables, selectedTableId, autoSelectFirstTable, setSelectedTableId]);

  // 현재 테이블의 저장된 필터 불러오기
  useEffect(() => {
    if (currentTable?.tableName) {
      const storageKey = `table_filters_${currentTable.tableName}`;
      const savedFilters = localStorage.getItem(storageKey);
      
      if (savedFilters) {
        try {
          const parsed = JSON.parse(savedFilters) as Array<{
            columnName: string;
            columnLabel: string;
            inputType: string;
            enabled: boolean;
            filterType: "text" | "number" | "date" | "select";
            width?: number;
          }>;
          
          // enabled된 필터들만 activeFilters로 설정
          const activeFiltersList: TableFilter[] = parsed
            .filter((f) => f.enabled)
            .map((f) => ({
              columnName: f.columnName,
              operator: "contains",
              value: "",
              filterType: f.filterType,
              width: f.width || 200, // 저장된 너비 포함
            }));
          
          setActiveFilters(activeFiltersList);
        } catch (error) {
          console.error("저장된 필터 불러오기 실패:", error);
        }
      }
    }
  }, [currentTable?.tableName]);

  // select 옵션 초기 로드 (한 번만 실행, 이후 유지)
  useEffect(() => {
    if (!currentTable?.getColumnUniqueValues || activeFilters.length === 0) {
      return;
    }

    const loadSelectOptions = async () => {
      const selectFilters = activeFilters.filter(f => f.filterType === "select");
      
      if (selectFilters.length === 0) {
        return;
      }

      const newOptions: Record<string, Array<{ label: string; value: string }>> = { ...selectOptions };
      
      for (const filter of selectFilters) {
        // 이미 로드된 옵션이 있으면 스킵 (초기값 유지)
        if (newOptions[filter.columnName] && newOptions[filter.columnName].length > 0) {
          continue;
        }
        
        try {
          const options = await currentTable.getColumnUniqueValues(filter.columnName);
          newOptions[filter.columnName] = options;
        } catch (error) {
          console.error("❌ [TableSearchWidget] select 옵션 로드 실패:", filter.columnName, error);
        }
      }
      setSelectOptions(newOptions);
    };
    
    loadSelectOptions();
  }, [activeFilters, currentTable?.tableName, currentTable?.getColumnUniqueValues]); // dataCount 제거, tableName으로 변경


  // 높이 변화 감지 및 알림 (실제 화면에서만)
  useEffect(() => {
    if (!containerRef.current || !screenId || !setWidgetHeight) return;
    
    // 컴포넌트의 원래 높이 (디자이너에서 설정한 높이)
    const originalHeight = (component as any).size?.height || 50;

    const resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        const newHeight = entry.contentRect.height;
        
        // Context에 높이 저장 (다른 컴포넌트 위치 조정에 사용)
        setWidgetHeight(screenId, component.id, newHeight, originalHeight);
        
        // localStorage에 높이 저장 (새로고침 시 복원용)
        localStorage.setItem(
          `table_search_widget_height_screen_${screenId}_${component.id}`,
          JSON.stringify({ height: newHeight, originalHeight })
        );
        
        // 콜백이 있으면 호출
        if (onHeightChange) {
          onHeightChange(newHeight);
        }
      }
    });

    resizeObserver.observe(containerRef.current);

    return () => {
      resizeObserver.disconnect();
    };
  }, [screenId, component.id, setWidgetHeight, onHeightChange]);

  // 화면 로딩 시 저장된 높이 복원
  useEffect(() => {
    if (!screenId || !setWidgetHeight) return;
    
    const storageKey = `table_search_widget_height_screen_${screenId}_${component.id}`;
    const savedData = localStorage.getItem(storageKey);
    
    if (savedData) {
      try {
        const { height, originalHeight } = JSON.parse(savedData);
        setWidgetHeight(screenId, component.id, height, originalHeight);
      } catch (error) {
        console.error("저장된 높이 복원 실패:", error);
      }
    }
  }, [screenId, component.id, setWidgetHeight]);

  const hasMultipleTables = tableList.length > 1;

  // 필터 값 변경 핸들러
  const handleFilterChange = (columnName: string, value: string) => {
    const newValues = {
      ...filterValues,
      [columnName]: value,
    };
    
    setFilterValues(newValues);
    
    // 실시간 검색: 값 변경 시 즉시 필터 적용
    applyFilters(newValues);
  };

  // 필터 적용 함수
  const applyFilters = (values: Record<string, string> = filterValues) => {
    // 빈 값이 아닌 필터만 적용
    const filtersWithValues = activeFilters.map((filter) => ({
      ...filter,
      value: values[filter.columnName] || "",
    })).filter((f) => f.value !== "");

    currentTable?.onFilterChange(filtersWithValues);
  };

  // 필터 초기화
  const handleResetFilters = () => {
    setFilterValues({});
    setSelectedLabels({});
    currentTable?.onFilterChange([]);
  };

  // 필터 입력 필드 렌더링
  const renderFilterInput = (filter: TableFilter) => {
    const column = currentTable?.columns.find((c) => c.columnName === filter.columnName);
    const value = filterValues[filter.columnName] || "";
    const width = filter.width || 200; // 기본 너비 200px

    switch (filter.filterType) {
      case "date":
        return (
          <Input
            type="date"
            value={value}
            onChange={(e) => handleFilterChange(filter.columnName, e.target.value)}
            className="h-9 text-xs sm:text-sm focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0"
            style={{ width: `${width}px`, height: '36px', minHeight: '36px', outline: 'none', boxShadow: 'none' }}
            placeholder={column?.columnLabel}
          />
        );

      case "number":
        return (
          <Input
            type="number"
            value={value}
            onChange={(e) => handleFilterChange(filter.columnName, e.target.value)}
            className="h-9 text-xs sm:text-sm focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0"
            style={{ width: `${width}px`, height: '36px', minHeight: '36px', outline: 'none', boxShadow: 'none' }}
            placeholder={column?.columnLabel}
          />
        );

      case "select": {
        let options = selectOptions[filter.columnName] || [];
        
        // 현재 선택된 값이 옵션 목록에 없으면 추가 (데이터 없을 때도 선택값 유지)
        if (value && !options.find(opt => opt.value === value)) {
          const savedLabel = selectedLabels[filter.columnName] || value;
          options = [{ value, label: savedLabel }, ...options];
        }
        
        // 중복 제거 (value 기준)
        const uniqueOptions = options.reduce((acc, option) => {
          if (!acc.find(opt => opt.value === option.value)) {
            acc.push(option);
          }
          return acc;
        }, [] as Array<{ value: string; label: string }>);
        
        return (
          <Select
            value={value}
            onValueChange={(val) => {
              // 선택한 값의 라벨 저장
              const selectedOption = uniqueOptions.find(opt => opt.value === val);
              if (selectedOption) {
                setSelectedLabels(prev => ({
                  ...prev,
                  [filter.columnName]: selectedOption.label,
                }));
              }
              handleFilterChange(filter.columnName, val);
            }}
          >
            <SelectTrigger 
              className="h-9 min-h-9 text-xs sm:text-sm focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0" 
              style={{ width: `${width}px`, height: '36px', minHeight: '36px', outline: 'none', boxShadow: 'none' }}
            >
              <SelectValue placeholder={column?.columnLabel || "선택"} />
            </SelectTrigger>
            <SelectContent>
              {uniqueOptions.length === 0 ? (
                <div className="px-2 py-1.5 text-xs text-muted-foreground">
                  옵션 없음
                </div>
              ) : (
                uniqueOptions.map((option, index) => (
                  <SelectItem key={`${filter.columnName}-${option.value}-${index}`} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))
              )}
            </SelectContent>
          </Select>
        );
      }

      default: // text
        return (
          <Input
            type="text"
            value={value}
            onChange={(e) => handleFilterChange(filter.columnName, e.target.value)}
            className="h-9 text-xs sm:text-sm focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0"
            style={{ width: `${width}px`, height: '36px', minHeight: '36px', outline: 'none', boxShadow: 'none' }}
            placeholder={column?.columnLabel}
          />
        );
    }
  };

  return (
    <div
      ref={containerRef}
      className="flex w-full flex-wrap items-center gap-2 border-b bg-card"
      style={{
        padding: component.style?.padding || "0.75rem",
        backgroundColor: component.style?.backgroundColor,
        minHeight: "48px",
      }}
    >
      {/* 필터 입력 필드들 */}
      {activeFilters.length > 0 && (
        <div className="flex flex-1 flex-wrap items-center gap-2">
          {activeFilters.map((filter) => (
            <div key={filter.columnName}>
              {renderFilterInput(filter)}
            </div>
          ))}
          
          {/* 초기화 버튼 */}
          <Button
            variant="outline"
            size="sm"
            onClick={handleResetFilters}
            className="h-9 shrink-0 text-xs sm:text-sm"
          >
            <X className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
            초기화
          </Button>
        </div>
      )}

      {/* 필터가 없을 때는 빈 공간 */}
      {activeFilters.length === 0 && <div className="flex-1" />}

      {/* 오른쪽: 데이터 건수 + 설정 버튼들 */}
      <div className="flex items-center gap-2 flex-shrink-0">
        {/* 데이터 건수 표시 */}
        {currentTable?.dataCount !== undefined && (
          <div className="rounded-md bg-muted px-3 py-1.5 text-xs font-medium text-muted-foreground sm:text-sm">
            {currentTable.dataCount.toLocaleString()}건
          </div>
        )}

        <Button
          variant="outline"
          size="sm"
          onClick={() => setColumnVisibilityOpen(true)}
          disabled={!selectedTableId}
          className="h-8 text-xs sm:h-9 sm:text-sm"
        >
          <Settings className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
          테이블 옵션
        </Button>

        <Button
          variant="outline"
          size="sm"
          onClick={() => setFilterOpen(true)}
          disabled={!selectedTableId}
          className="h-8 text-xs sm:h-9 sm:text-sm"
        >
          <Filter className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
          필터 설정
        </Button>

        <Button
          variant="outline"
          size="sm"
          onClick={() => setGroupingOpen(true)}
          disabled={!selectedTableId}
          className="h-8 text-xs sm:h-9 sm:text-sm"
        >
          <Layers className="mr-1 h-3 w-3 sm:h-4 sm:w-4" />
          그룹 설정
        </Button>
      </div>

      {/* 패널들 */}
      <ColumnVisibilityPanel
        isOpen={columnVisibilityOpen}
        onClose={() => setColumnVisibilityOpen(false)}
      />
      <FilterPanel 
        isOpen={filterOpen} 
        onClose={() => setFilterOpen(false)}
        onFiltersApplied={(filters) => setActiveFilters(filters)}
      />
      <GroupingPanel isOpen={groupingOpen} onClose={() => setGroupingOpen(false)} />
    </div>
  );
}

