"use client";

/**
 * FieldPanel 컴포넌트
 * 피벗 그리드 상단의 필드 배치 영역 (열, 행, 데이터)
 * 드래그 앤 드롭으로 필드 재배치 가능
 */

import React, { useState } from "react";
import {
  DndContext,
  DragOverlay,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragStartEvent,
  DragEndEvent,
  DragOverEvent,
} from "@dnd-kit/core";
import {
  SortableContext,
  sortableKeyboardCoordinates,
  horizontalListSortingStrategy,
  useSortable,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { cn } from "@/lib/utils";
import { PivotFieldConfig, PivotAreaType } from "../types";
import {
  X,
  Filter,
  Columns,
  Rows,
  BarChart3,
  GripVertical,
  ChevronDown,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

// ==================== 타입 ====================

interface FieldPanelProps {
  fields: PivotFieldConfig[];
  onFieldsChange: (fields: PivotFieldConfig[]) => void;
  onFieldRemove?: (field: PivotFieldConfig) => void;
  onFieldSettingsChange?: (field: PivotFieldConfig) => void;
  collapsed?: boolean;
  onToggleCollapse?: () => void;
}

interface FieldChipProps {
  field: PivotFieldConfig;
  onRemove: () => void;
  onSettingsChange?: (field: PivotFieldConfig) => void;
}

interface DroppableAreaProps {
  area: PivotAreaType;
  fields: PivotFieldConfig[];
  title: string;
  icon: React.ReactNode;
  onFieldRemove: (field: PivotFieldConfig) => void;
  onFieldSettingsChange?: (field: PivotFieldConfig) => void;
  isOver?: boolean;
}

// ==================== 영역 설정 ====================

const AREA_CONFIG: Record<
  PivotAreaType,
  { title: string; icon: React.ReactNode; color: string }
> = {
  filter: {
    title: "필터",
    icon: <Filter className="h-3.5 w-3.5" />,
    color: "bg-amber-50 border-orange-200 dark:bg-orange-950/20 dark:border-orange-800",
  },
  column: {
    title: "열",
    icon: <Columns className="h-3.5 w-3.5" />,
    color: "bg-primary/10 border-primary/20 dark:bg-primary/10 dark:border-primary/30",
  },
  row: {
    title: "행",
    icon: <Rows className="h-3.5 w-3.5" />,
    color: "bg-emerald-50 border-emerald-200 dark:bg-emerald-950/20 dark:border-emerald-800",
  },
  data: {
    title: "데이터",
    icon: <BarChart3 className="h-3.5 w-3.5" />,
    color: "bg-purple-50 border-purple-200 dark:bg-purple-950/20 dark:border-purple-800",
  },
};

// ==================== 필드 칩 (드래그 가능) ====================

const SortableFieldChip: React.FC<FieldChipProps> = ({
  field,
  onRemove,
  onSettingsChange,
}) => {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: `${field.area}-${field.field}` });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs",
        "bg-background border border-border shadow-sm",
        "hover:bg-accent/50 transition-colors",
        isDragging && "opacity-50 shadow-lg"
      )}
    >
      {/* 드래그 핸들 */}
      <button
        {...attributes}
        {...listeners}
        className="cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground"
      >
        <GripVertical className="h-3 w-3" />
      </button>

      {/* 필드 라벨 */}
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <button className="flex items-center gap-1 hover:text-primary">
            <span className="font-medium">{field.caption}</span>
            {field.area === "data" && field.summaryType && (
              <span className="text-muted-foreground">
                ({getSummaryLabel(field.summaryType)})
              </span>
            )}
            <ChevronDown className="h-3 w-3 text-muted-foreground" />
          </button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="start" className="w-48">
          {field.area === "data" && (
            <>
              <DropdownMenuItem
                onClick={() =>
                  onSettingsChange?.({ ...field, summaryType: "sum" })
                }
              >
                합계
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() =>
                  onSettingsChange?.({ ...field, summaryType: "count" })
                }
              >
                개수
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() =>
                  onSettingsChange?.({ ...field, summaryType: "avg" })
                }
              >
                평균
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() =>
                  onSettingsChange?.({ ...field, summaryType: "min" })
                }
              >
                최소
              </DropdownMenuItem>
              <DropdownMenuItem
                onClick={() =>
                  onSettingsChange?.({ ...field, summaryType: "max" })
                }
              >
                최대
              </DropdownMenuItem>
              <DropdownMenuSeparator />
            </>
          )}
          <DropdownMenuItem
            onClick={() =>
              onSettingsChange?.({
                ...field,
                sortOrder: field.sortOrder === "asc" ? "desc" : "asc",
              })
            }
          >
            {field.sortOrder === "asc" ? "내림차순 정렬" : "오름차순 정렬"}
          </DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuItem
            onClick={() => onSettingsChange?.({ ...field, visible: false })}
          >
            필드 숨기기
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      {/* 삭제 버튼 */}
      <button
        onClick={(e) => {
          e.stopPropagation();
          onRemove();
        }}
        className="text-muted-foreground hover:text-destructive transition-colors"
      >
        <X className="h-3 w-3" />
      </button>
    </div>
  );
};

// ==================== 드롭 영역 ====================

const DroppableArea: React.FC<DroppableAreaProps> = ({
  area,
  fields,
  title,
  icon,
  onFieldRemove,
  onFieldSettingsChange,
  isOver,
}) => {
  const config = AREA_CONFIG[area];
  const areaFields = fields.filter((f) => f.area === area && f.visible !== false);
  const fieldIds = areaFields.map((f) => `${area}-${f.field}`);

  return (
    <div
      className={cn(
        "flex-1 min-h-[44px] rounded border border-dashed p-1.5",
        "transition-colors duration-200",
        config.color,
        isOver && "border-primary bg-primary/5"
      )}
      data-area={area}
    >
      {/* 영역 헤더 */}
      <div className="flex items-center gap-1 mb-1 text-[11px] font-medium text-muted-foreground">
        {icon}
        <span>{title}</span>
        {areaFields.length > 0 && (
          <span className="text-[10px] bg-muted px-1 rounded">
            {areaFields.length}
          </span>
        )}
      </div>

      {/* 필드 목록 */}
      <SortableContext items={fieldIds} strategy={horizontalListSortingStrategy}>
        <div className="flex flex-wrap gap-1 min-h-[22px]">
          {areaFields.length === 0 ? (
            <span className="text-[10px] text-muted-foreground/50 italic">
              필드를 여기로 드래그
            </span>
          ) : (
            areaFields.map((field) => (
              <SortableFieldChip
                key={`${area}-${field.field}`}
                field={field}
                onRemove={() => onFieldRemove(field)}
                onSettingsChange={onFieldSettingsChange}
              />
            ))
          )}
        </div>
      </SortableContext>
    </div>
  );
};

// ==================== 유틸리티 ====================

function getSummaryLabel(type: string): string {
  const labels: Record<string, string> = {
    sum: "합계",
    count: "개수",
    avg: "평균",
    min: "최소",
    max: "최대",
    countDistinct: "고유",
  };
  return labels[type] || type;
}

// ==================== 메인 컴포넌트 ====================

export const FieldPanel: React.FC<FieldPanelProps> = ({
  fields,
  onFieldsChange,
  onFieldRemove,
  onFieldSettingsChange,
  collapsed = false,
  onToggleCollapse,
}) => {
  const [activeId, setActiveId] = useState<string | null>(null);
  const [overArea, setOverArea] = useState<PivotAreaType | null>(null);

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  // 드래그 시작
  const handleDragStart = (event: DragStartEvent) => {
    setActiveId(event.active.id as string);
  };

  // 드래그 오버
  const handleDragOver = (event: DragOverEvent) => {
    const { over } = event;
    if (!over) {
      setOverArea(null);
      return;
    }

    // 드롭 영역 감지
    const overId = over.id as string;
    const targetArea = overId.split("-")[0] as PivotAreaType;
    if (["filter", "column", "row", "data"].includes(targetArea)) {
      setOverArea(targetArea);
    }
  };

  // 드래그 종료
  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    setActiveId(null);
    setOverArea(null);

    if (!over) return;

    const activeId = active.id as string;
    const overId = over.id as string;

    // 필드 정보 파싱
    const [sourceArea, sourceField] = activeId.split("-") as [
      PivotAreaType,
      string
    ];
    const [targetArea] = overId.split("-") as [PivotAreaType, string];

    // 같은 영역 내 정렬
    if (sourceArea === targetArea) {
      const areaFields = fields.filter((f) => f.area === sourceArea);
      const sourceIndex = areaFields.findIndex((f) => f.field === sourceField);
      const targetIndex = areaFields.findIndex(
        (f) => `${f.area}-${f.field}` === overId
      );

      if (sourceIndex !== targetIndex && targetIndex >= 0) {
        // 순서 변경
        const newFields = [...fields];
        const fieldToMove = newFields.find(
          (f) => f.field === sourceField && f.area === sourceArea
        );
        if (fieldToMove) {
          fieldToMove.areaIndex = targetIndex;
          // 다른 필드들 인덱스 조정
          newFields
            .filter((f) => f.area === sourceArea && f.field !== sourceField)
            .sort((a, b) => (a.areaIndex || 0) - (b.areaIndex || 0))
            .forEach((f, idx) => {
              f.areaIndex = idx >= targetIndex ? idx + 1 : idx;
            });
        }
        onFieldsChange(newFields);
      }
      return;
    }

    // 다른 영역으로 이동
    if (["filter", "column", "row", "data"].includes(targetArea)) {
      const newFields = fields.map((f) => {
        if (f.field === sourceField && f.area === sourceArea) {
          return {
            ...f,
            area: targetArea as PivotAreaType,
            areaIndex: fields.filter((ff) => ff.area === targetArea).length,
          };
        }
        return f;
      });
      onFieldsChange(newFields);
    }
  };

  // 필드 제거
  const handleFieldRemove = (field: PivotFieldConfig) => {
    if (onFieldRemove) {
      onFieldRemove(field);
    } else {
      // 기본 동작: visible을 false로 설정
      const newFields = fields.map((f) =>
        f.field === field.field && f.area === field.area
          ? { ...f, visible: false }
          : f
      );
      onFieldsChange(newFields);
    }
  };

  // 필드 설정 변경
  const handleFieldSettingsChange = (updatedField: PivotFieldConfig) => {
    if (onFieldSettingsChange) {
      onFieldSettingsChange(updatedField);
    }
    const newFields = fields.map((f) =>
      f.field === updatedField.field && f.area === updatedField.area
        ? updatedField
        : f
    );
    onFieldsChange(newFields);
  };

  // 활성 필드 찾기 (드래그 중인 필드)
  const activeField = activeId
    ? fields.find((f) => `${f.area}-${f.field}` === activeId)
    : null;

  // 각 영역의 필드 수 계산
  const filterCount = fields.filter((f) => f.area === "filter" && f.visible !== false).length;
  const columnCount = fields.filter((f) => f.area === "column" && f.visible !== false).length;
  const rowCount = fields.filter((f) => f.area === "row" && f.visible !== false).length;
  const dataCount = fields.filter((f) => f.area === "data" && f.visible !== false).length;

  if (collapsed) {
    return (
      <div className="border-b border-border px-3 py-1.5 flex items-center justify-between bg-muted/10">
        <div className="flex items-center gap-3 text-xs text-muted-foreground">
          {filterCount > 0 && (
            <span className="flex items-center gap-1">
              <Filter className="h-3 w-3" />
              필터 {filterCount}
            </span>
          )}
          <span className="flex items-center gap-1">
            <Columns className="h-3 w-3" />
            열 {columnCount}
          </span>
          <span className="flex items-center gap-1">
            <Rows className="h-3 w-3" />
            행 {rowCount}
          </span>
          <span className="flex items-center gap-1">
            <BarChart3 className="h-3 w-3" />
            데이터 {dataCount}
          </span>
        </div>
        <Button
          variant="ghost"
          size="sm"
          onClick={onToggleCollapse}
          className="text-xs h-6 px-2"
        >
          필드 설정
        </Button>
      </div>
    );
  }

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragStart={handleDragStart}
      onDragOver={handleDragOver}
      onDragEnd={handleDragEnd}
    >
      <div className="border-b border-border bg-muted/20 p-2">
        {/* 4개 영역 배치: 2x2 그리드 */}
        <div className="grid grid-cols-2 gap-1.5">
          {/* 필터 영역 */}
          <DroppableArea
            area="filter"
            fields={fields}
            title={AREA_CONFIG.filter.title}
            icon={AREA_CONFIG.filter.icon}
            onFieldRemove={handleFieldRemove}
            onFieldSettingsChange={handleFieldSettingsChange}
            isOver={overArea === "filter"}
          />

          {/* 열 영역 */}
          <DroppableArea
            area="column"
            fields={fields}
            title={AREA_CONFIG.column.title}
            icon={AREA_CONFIG.column.icon}
            onFieldRemove={handleFieldRemove}
            onFieldSettingsChange={handleFieldSettingsChange}
            isOver={overArea === "column"}
          />

          {/* 행 영역 */}
          <DroppableArea
            area="row"
            fields={fields}
            title={AREA_CONFIG.row.title}
            icon={AREA_CONFIG.row.icon}
            onFieldRemove={handleFieldRemove}
            onFieldSettingsChange={handleFieldSettingsChange}
            isOver={overArea === "row"}
          />

          {/* 데이터 영역 */}
          <DroppableArea
            area="data"
            fields={fields}
            title={AREA_CONFIG.data.title}
            icon={AREA_CONFIG.data.icon}
            onFieldRemove={handleFieldRemove}
            onFieldSettingsChange={handleFieldSettingsChange}
            isOver={overArea === "data"}
          />
        </div>

        {/* 접기 버튼 */}
        {onToggleCollapse && (
          <div className="flex justify-center mt-1.5">
            <Button
              variant="ghost"
              size="sm"
              onClick={onToggleCollapse}
              className="text-xs h-5 px-2"
            >
              필드 패널 접기
            </Button>
          </div>
        )}
      </div>

      {/* 드래그 오버레이 */}
      <DragOverlay>
        {activeField ? (
          <div
            className={cn(
              "inline-flex items-center gap-1 px-2 py-1 rounded-md text-xs",
              "bg-background border border-primary shadow-lg"
            )}
          >
            <GripVertical className="h-3 w-3 text-muted-foreground" />
            <span className="font-medium">{activeField.caption}</span>
          </div>
        ) : null}
      </DragOverlay>
    </DndContext>
  );
};

export default FieldPanel;

