import React, { useState, useEffect } from "react";
import { useTableOptions } from "@/contexts/TableOptionsContext";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import { GripVertical, Eye, EyeOff, Lock } from "lucide-react";
import { ColumnVisibility } from "@/types/table-options";

interface Props {
  isOpen: boolean;
  onClose: () => void;
}

export const ColumnVisibilityPanel: React.FC<Props> = ({
  isOpen,
  onClose,
}) => {
  const { getTable, selectedTableId } = useTableOptions();
  const table = selectedTableId ? getTable(selectedTableId) : undefined;

  const [localColumns, setLocalColumns] = useState<ColumnVisibility[]>([]);
  const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
  const [frozenColumnCount, setFrozenColumnCount] = useState<number>(0);

  // 테이블 정보 로드
  useEffect(() => {
    if (table) {
      setLocalColumns(
        table.columns.map((col) => ({
          columnName: col.columnName,
          visible: col.visible,
          width: col.width,
          order: 0,
        }))
      );
      // 현재 틀고정 컬럼 수 로드
      setFrozenColumnCount(table.frozenColumnCount ?? 0);
    }
  }, [table]);

  const handleVisibilityChange = (columnName: string, visible: boolean) => {
    setLocalColumns((prev) =>
      prev.map((col) =>
        col.columnName === columnName ? { ...col, visible } : col
      )
    );
  };

  const handleWidthChange = (columnName: string, width: number) => {
    setLocalColumns((prev) =>
      prev.map((col) =>
        col.columnName === columnName ? { ...col, width } : col
      )
    );
  };

  const moveColumn = (fromIndex: number, toIndex: number) => {
    const newColumns = [...localColumns];
    const [movedItem] = newColumns.splice(fromIndex, 1);
    newColumns.splice(toIndex, 0, movedItem);
    setLocalColumns(newColumns);
  };

  const handleDragStart = (index: number) => {
    setDraggedIndex(index);
  };

  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    if (draggedIndex === null || draggedIndex === index) return;
    moveColumn(draggedIndex, index);
    setDraggedIndex(index);
  };

  const handleDragEnd = () => {
    setDraggedIndex(null);
  };

  const handleApply = () => {
    table?.onColumnVisibilityChange(localColumns);
    
    // 컬럼 순서 변경 콜백 호출
    if (table?.onColumnOrderChange) {
      const newOrder = localColumns
        .map((col) => col.columnName)
        .filter((name) => name !== "__checkbox__");
      table.onColumnOrderChange(newOrder);
    }
    
    // 틀고정 컬럼 수 변경 콜백 호출 (현재 컬럼 상태도 함께 전달)
    if (table?.onFrozenColumnCountChange) {
      const updatedColumns = localColumns.map((col) => ({
        columnName: col.columnName,
        visible: col.visible,
      }));
      table.onFrozenColumnCountChange(frozenColumnCount, updatedColumns);
    }
    
    onClose();
  };

  const handleReset = () => {
    if (table) {
      setLocalColumns(
        table.columns.map((col) => ({
          columnName: col.columnName,
          visible: true,
          width: 150,
          order: 0,
        }))
      );
      setFrozenColumnCount(0);
    }
  };

  // 틀고정 컬럼 수 변경 핸들러
  const handleFrozenColumnCountChange = (value: string) => {
    const count = parseInt(value) || 0;
    // 최대값은 표시 가능한 컬럼 수
    const maxCount = localColumns.filter((col) => col.visible).length;
    setFrozenColumnCount(Math.min(Math.max(0, count), maxCount));
  };

  const visibleCount = localColumns.filter((col) => col.visible).length;

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-[95vw] sm:max-w-2xl">
        <DialogHeader>
          <DialogTitle className="text-base sm:text-lg">
            테이블 옵션
          </DialogTitle>
          <DialogDescription className="text-xs sm:text-sm">
            컬럼 표시/숨기기, 순서 변경, 너비 등을 설정할 수 있습니다. 모든
            테두리를 드래그하여 크기를 조정할 수 있습니다.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3 sm:space-y-4">
          {/* 상태 표시 및 틀고정 설정 */}
          <div className="flex flex-col gap-3 rounded-lg border bg-muted/50 p-3 sm:flex-row sm:items-center sm:justify-between">
            <div className="flex items-center gap-4">
              <div className="text-xs text-muted-foreground sm:text-sm">
                {visibleCount}/{localColumns.length}개 컬럼 표시 중
              </div>
              
              {/* 틀고정 설정 */}
              <div className="flex items-center gap-2">
                <Lock className="h-4 w-4 text-muted-foreground" />
                <Label className="text-xs text-muted-foreground whitespace-nowrap">
                  틀고정:
                </Label>
                <Input
                  type="number"
                  value={frozenColumnCount}
                  onChange={(e) => handleFrozenColumnCountChange(e.target.value)}
                  className="h-7 w-16 text-xs sm:h-8 sm:w-20 sm:text-sm"
                  min={0}
                  max={visibleCount}
                  placeholder="0"
                />
                <span className="text-xs text-muted-foreground whitespace-nowrap">
                  개 컬럼
                </span>
              </div>
            </div>
            
            <Button
              variant="ghost"
              size="sm"
              onClick={handleReset}
              className="h-7 text-xs"
            >
              초기화
            </Button>
          </div>

          {/* 컬럼 리스트 */}
          <ScrollArea className="h-[300px] sm:h-[400px]">
            <div className="space-y-2 pr-4">
              {localColumns.map((col, index) => {
                const columnMeta = table?.columns.find(
                  (c) => c.columnName === col.columnName
                );
                // 표시 가능한 컬럼 중 몇 번째인지 계산 (틀고정 표시용)
                const visibleIndex = localColumns
                  .slice(0, index + 1)
                  .filter((c) => c.visible).length;
                const isFrozen = col.visible && visibleIndex <= frozenColumnCount;
                
                return (
                  <div
                    key={col.columnName}
                    draggable
                    onDragStart={() => handleDragStart(index)}
                    onDragOver={(e) => handleDragOver(e, index)}
                    onDragEnd={handleDragEnd}
                    className={`flex items-center gap-3 rounded-lg border p-3 transition-colors cursor-move ${
                      isFrozen 
                        ? "bg-primary/10 border-primary/20 dark:bg-primary/15/30 dark:border-primary/30" 
                        : "bg-background hover:bg-muted/50"
                    }`}
                  >
                    {/* 드래그 핸들 */}
                    <GripVertical className="h-4 w-4 shrink-0 text-muted-foreground" />

                    {/* 체크박스 */}
                    <Checkbox
                      checked={col.visible}
                      onCheckedChange={(checked) =>
                        handleVisibilityChange(
                          col.columnName,
                          checked as boolean
                        )
                      }
                    />

                    {/* 가시성/틀고정 아이콘 */}
                    {isFrozen ? (
                      <Lock className="h-4 w-4 shrink-0 text-primary" />
                    ) : col.visible ? (
                      <Eye className="h-4 w-4 shrink-0 text-primary" />
                    ) : (
                      <EyeOff className="h-4 w-4 shrink-0 text-muted-foreground" />
                    )}

                    {/* 컬럼명 */}
                    <div className="flex-1">
                      <div className="flex items-center gap-2">
                        <span className="text-xs font-medium sm:text-sm">
                          {columnMeta?.columnLabel}
                        </span>
                        {isFrozen && (
                          <span className="text-[10px] text-primary dark:text-primary/80 font-medium">
                            (고정)
                          </span>
                        )}
                      </div>
                      <div className="text-[10px] text-muted-foreground sm:text-xs">
                        {col.columnName}
                      </div>
                    </div>

                    {/* 너비 설정 */}
                    <div className="flex items-center gap-2">
                      <Label className="text-xs text-muted-foreground">
                        너비:
                      </Label>
                      <Input
                        type="number"
                        value={col.width || 150}
                        onChange={(e) =>
                          handleWidthChange(
                            col.columnName,
                            parseInt(e.target.value) || 150
                          )
                        }
                        className="h-7 w-16 text-xs sm:h-8 sm:w-20 sm:text-sm"
                        min={50}
                        max={500}
                      />
                    </div>
                  </div>
                );
              })}
            </div>
          </ScrollArea>
        </div>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={onClose}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            취소
          </Button>
          <Button
            onClick={handleApply}
            className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
          >
            저장
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

