"use client";

import React from "react";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ColumnConfig } from "../types";
import { Database, Link2, GripVertical, X, Check, ChevronsUpDown, Lock, Unlock } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { cn } from "@/lib/utils";
import { DndContext, closestCenter, type DragEndEvent } from "@dnd-kit/core";
import { SortableContext, useSortable, verticalListSortingStrategy, arrayMove } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

function SortableColumnRow({
  id,
  col,
  index,
  isEntityJoin,
  onLabelChange,
  onWidthChange,
  onRemove,
}: {
  id: string;
  col: ColumnConfig;
  index: number;
  isEntityJoin?: boolean;
  onLabelChange: (value: string) => void;
  onWidthChange: (value: number) => void;
  onRemove: () => void;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
  const style = { transform: CSS.Transform.toString(transform), transition };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={cn(
        "bg-card flex items-center gap-1.5 rounded-md border px-2 py-1.5",
        isDragging && "z-50 opacity-50 shadow-md",
        isEntityJoin && "border-primary/20 bg-primary/10/30",
      )}
    >
      <div {...attributes} {...listeners} className="text-muted-foreground hover:text-foreground cursor-grab touch-none">
        <GripVertical className="h-3 w-3" />
      </div>
      {isEntityJoin ? (
        <Link2 className="h-3 w-3 shrink-0 text-primary" />
      ) : (
        <span className="text-muted-foreground w-5 shrink-0 text-center text-[10px] font-medium">#{index + 1}</span>
      )}
      <Input
        value={col.displayName || col.columnName}
        onChange={(e) => onLabelChange(e.target.value)}
        placeholder="표시명"
        className="h-6 min-w-0 flex-1 text-xs"
      />
      <Input
        value={col.width || ""}
        onChange={(e) => onWidthChange(parseInt(e.target.value) || 100)}
        placeholder="너비"
        className="h-6 w-14 shrink-0 text-xs"
      />
      <Button type="button" variant="ghost" size="sm" onClick={onRemove} className="text-muted-foreground hover:text-destructive h-5 w-5 shrink-0 p-0">
        <X className="h-3 w-3" />
      </Button>
    </div>
  );
}

export interface ColumnsConfigPanelProps {
  config: any;
  onChange: (key: string, value: any) => void;
  screenTableName?: string;
  targetTableName: string | undefined;
  availableColumns: Array<{ columnName: string; dataType: string; label?: string; input_type?: string }>;
  tableColumns?: any[];
  entityJoinColumns: {
    availableColumns: Array<{
      tableName: string;
      columnName: string;
      columnLabel: string;
      dataType: string;
      joinAlias: string;
      suggestedLabel: string;
    }>;
    joinTables: Array<{
      tableName: string;
      currentDisplayColumn: string;
      availableColumns: Array<{
        columnName: string;
        columnLabel: string;
        dataType: string;
        description?: string;
      }>;
    }>;
  };
  entityDisplayConfigs: Record<
    string,
    {
      sourceColumns: Array<{ columnName: string; displayName: string; dataType: string }>;
      joinColumns: Array<{ columnName: string; displayName: string; dataType: string }>;
      selectedColumns: string[];
      separator: string;
    }
  >;
  onAddColumn: (columnName: string) => void;
  onAddEntityColumn: (joinColumn: {
    tableName: string;
    columnName: string;
    columnLabel: string;
    dataType: string;
    joinAlias: string;
    suggestedLabel: string;
  }) => void;
  onRemoveColumn: (columnName: string) => void;
  onUpdateColumn: (columnName: string, updates: Partial<ColumnConfig>) => void;
  onToggleEntityDisplayColumn: (columnName: string, selectedColumn: string) => void;
  onUpdateEntityDisplaySeparator: (columnName: string, separator: string) => void;
}

/**
 * 컬럼 설정 패널: 컬럼 선택, Entity 조인, DnD 순서 변경
 */
export const ColumnsConfigPanel: React.FC<ColumnsConfigPanelProps> = ({
  config,
  onChange,
  screenTableName,
  targetTableName,
  availableColumns,
  tableColumns,
  entityJoinColumns,
  entityDisplayConfigs,
  onAddColumn,
  onAddEntityColumn,
  onRemoveColumn,
  onUpdateColumn,
  onToggleEntityDisplayColumn,
  onUpdateEntityDisplaySeparator,
}) => {
  const handleChange = (key: string, value: any) => {
    onChange(key, value);
  };

  return (
    <div className="space-y-6">
      {/* 엔티티 컬럼 표시 설정 섹션 */}
      {config.columns?.some((col: ColumnConfig) => col.isEntityJoin) && (
        <div className="space-y-3">
          {config.columns
            ?.filter((col: ColumnConfig) => col.isEntityJoin && col.entityDisplayConfig)
            .map((column: ColumnConfig) => (
              <div key={column.columnName} className="space-y-2">
                <div className="mb-2">
                  <span className="truncate text-xs font-medium" style={{ fontSize: "12px" }}>
                    {column.displayName || column.columnName}
                  </span>
                </div>

                {entityDisplayConfigs[column.columnName] ? (
                  <div className="space-y-2">
                    <div className="space-y-1">
                      <Label className="text-xs">구분자</Label>
                      <Input
                        value={entityDisplayConfigs[column.columnName].separator}
                        onChange={(e) => onUpdateEntityDisplaySeparator(column.columnName, e.target.value)}
                        className="h-6 w-full text-xs"
                        style={{ fontSize: "12px" }}
                        placeholder=" - "
                      />
                    </div>

                    <div className="space-y-1">
                      <Label className="text-xs">표시할 컬럼 선택</Label>
                      {entityDisplayConfigs[column.columnName].sourceColumns.length === 0 &&
                      entityDisplayConfigs[column.columnName].joinColumns.length === 0 ? (
                        <div className="py-2 text-center text-xs text-muted-foreground/70">
                          표시 가능한 컬럼이 없습니다.
                          {!column.entityDisplayConfig?.joinTable && (
                            <p className="mt-1 text-[10px]">
                              테이블 타입 관리에서 참조 테이블을 설정하면 더 많은 컬럼을 선택할 수 있습니다.
                            </p>
                          )}
                        </div>
                      ) : (
                        <Popover>
                          <PopoverTrigger asChild>
                            <Button
                              variant="outline"
                              className="h-6 w-full justify-between text-xs"
                              style={{ fontSize: "12px" }}
                            >
                              {entityDisplayConfigs[column.columnName].selectedColumns.length > 0
                                ? `${entityDisplayConfigs[column.columnName].selectedColumns.length}개 선택됨`
                                : "컬럼 선택"}
                              <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                            </Button>
                          </PopoverTrigger>
                          <PopoverContent className="w-full p-0" align="start">
                            <Command>
                              <CommandInput placeholder="컬럼 검색..." className="text-xs" />
                              <CommandList>
                                <CommandEmpty className="text-xs">컬럼을 찾을 수 없습니다.</CommandEmpty>
                                {entityDisplayConfigs[column.columnName].sourceColumns.length > 0 && (
                                  <CommandGroup
                                    heading={`기본 테이블: ${column.entityDisplayConfig?.sourceTable || config.selectedTable || screenTableName}`}
                                  >
                                    {entityDisplayConfigs[column.columnName].sourceColumns.map((col) => (
                                      <CommandItem
                                        key={`source-${col.columnName}`}
                                        onSelect={() => onToggleEntityDisplayColumn(column.columnName, col.columnName)}
                                        className="text-xs"
                                      >
                                        <Check
                                          className={cn(
                                            "mr-2 h-4 w-4",
                                            entityDisplayConfigs[column.columnName].selectedColumns.includes(col.columnName)
                                              ? "opacity-100"
                                              : "opacity-0",
                                          )}
                                        />
                                        {col.displayName}
                                      </CommandItem>
                                    ))}
                                  </CommandGroup>
                                )}
                                {entityDisplayConfigs[column.columnName].joinColumns.length > 0 && (
                                  <CommandGroup heading={`참조 테이블: ${column.entityDisplayConfig?.joinTable}`}>
                                    {entityDisplayConfigs[column.columnName].joinColumns.map((col) => (
                                      <CommandItem
                                        key={`join-${col.columnName}`}
                                        onSelect={() => onToggleEntityDisplayColumn(column.columnName, col.columnName)}
                                        className="text-xs"
                                      >
                                        <Check
                                          className={cn(
                                            "mr-2 h-4 w-4",
                                            entityDisplayConfigs[column.columnName].selectedColumns.includes(col.columnName)
                                              ? "opacity-100"
                                              : "opacity-0",
                                          )}
                                        />
                                        {col.displayName}
                                      </CommandItem>
                                    ))}
                                  </CommandGroup>
                                )}
                              </CommandList>
                            </Command>
                          </PopoverContent>
                        </Popover>
                      )}
                    </div>

                    {!column.entityDisplayConfig?.joinTable &&
                      entityDisplayConfigs[column.columnName].sourceColumns.length > 0 && (
                        <div className="rounded bg-primary/10 p-2 text-[10px] text-primary">
                          현재 기본 테이블 컬럼만 표시됩니다. 테이블 타입 관리에서 참조 테이블을 설정하면 조인된
                          테이블의 컬럼도 선택할 수 있습니다.
                        </div>
                      )}

                    {entityDisplayConfigs[column.columnName].selectedColumns.length > 0 && (
                      <div className="space-y-1">
                        <Label className="text-xs">미리보기</Label>
                        <div className="flex flex-wrap gap-1 rounded bg-muted p-2 text-xs">
                          {entityDisplayConfigs[column.columnName].selectedColumns.map((colName, idx) => (
                            <React.Fragment key={colName}>
                              <Badge variant="secondary" className="text-xs">
                                {colName}
                              </Badge>
                              {idx < entityDisplayConfigs[column.columnName].selectedColumns.length - 1 && (
                                <span className="text-muted-foreground/70">
                                  {entityDisplayConfigs[column.columnName].separator}
                                </span>
                              )}
                            </React.Fragment>
                          ))}
                        </div>
                      </div>
                    )}
                  </div>
                ) : (
                  <div className="py-4 text-center text-xs text-muted-foreground/70">컬럼 정보 로딩 중...</div>
                )}
              </div>
            ))}
        </div>
      )}

      {!targetTableName ? (
        <div className="space-y-3">
          <div className="text-center text-muted-foreground">
            <p>테이블이 선택되지 않았습니다.</p>
            <p className="text-sm">기본 설정 탭에서 테이블을 선택하세요.</p>
          </div>
        </div>
      ) : availableColumns.length === 0 ? (
        <div className="space-y-3">
          <div className="text-center text-muted-foreground">
            <p>컬럼을 추가하려면 먼저 컴포넌트에 테이블을 명시적으로 선택하거나</p>
            <p className="text-sm">기본 설정 탭에서 테이블을 설정해주세요.</p>
            <p className="mt-2 text-xs text-primary">현재 화면 테이블: {screenTableName}</p>
          </div>
        </div>
      ) : (
        <>
          <div className="space-y-2">
            <div>
              <h3 className="text-sm font-semibold">컬럼 선택</h3>
              <p className="text-muted-foreground text-[10px]">표시할 컬럼을 선택하세요</p>
            </div>
            <hr className="border-border" />
            <div className="max-h-48 space-y-0.5 overflow-y-auto rounded-md border p-2">
              {availableColumns.map((column) => {
                const isAdded = config.columns?.some((c: ColumnConfig) => c.columnName === column.columnName);
                return (
                  <div
                    key={column.columnName}
                    className={cn(
                      "hover:bg-muted/50 flex cursor-pointer items-center gap-2 rounded px-2 py-1",
                      isAdded && "bg-primary/10",
                    )}
                    onClick={() => {
                      if (isAdded) {
                        handleChange(
                          "columns",
                          config.columns?.filter((c: ColumnConfig) => c.columnName !== column.columnName) || [],
                        );
                      } else {
                        onAddColumn(column.columnName);
                      }
                    }}
                  >
                    <Checkbox
                      checked={isAdded}
                      onCheckedChange={() => {
                        if (isAdded) {
                          handleChange(
                            "columns",
                            config.columns?.filter((c: ColumnConfig) => c.columnName !== column.columnName) || [],
                          );
                        } else {
                          onAddColumn(column.columnName);
                        }
                      }}
                      className="pointer-events-none h-3.5 w-3.5"
                    />
                    <Database className="text-muted-foreground h-3 w-3 flex-shrink-0" />
                    <span className="truncate text-xs">{column.label || column.columnName}</span>
                    {isAdded && (
                      <button
                        type="button"
                        title={
                          config.columns?.find((c: ColumnConfig) => c.columnName === column.columnName)?.editable === false
                            ? "편집 잠금 (클릭하여 해제)"
                            : "편집 가능 (클릭하여 잠금)"
                        }
                        className={cn(
                          "ml-auto flex-shrink-0 rounded p-0.5 transition-colors",
                          config.columns?.find((c: ColumnConfig) => c.columnName === column.columnName)?.editable === false
                            ? "text-destructive hover:bg-destructive/10"
                            : "text-muted-foreground hover:bg-muted",
                        )}
                        onClick={(e) => {
                          e.stopPropagation();
                          const currentCol = config.columns?.find((c: ColumnConfig) => c.columnName === column.columnName);
                          if (currentCol) {
                            onUpdateColumn(column.columnName, {
                              editable: currentCol.editable === false ? undefined : false,
                            });
                          }
                        }}
                      >
                        {config.columns?.find((c: ColumnConfig) => c.columnName === column.columnName)?.editable === false ? (
                          <Lock className="h-3 w-3" />
                        ) : (
                          <Unlock className="h-3 w-3" />
                        )}
                      </button>
                    )}
                    <span className={cn("text-[10px] text-muted-foreground/70", !isAdded && "ml-auto")}>
                      {column.input_type || column.dataType}
                    </span>
                  </div>
                );
              })}
            </div>
          </div>

          {entityJoinColumns.joinTables.length > 0 && (
            <div className="space-y-2">
              <div>
                <h3 className="text-sm font-semibold">Entity 조인 컬럼</h3>
                <p className="text-muted-foreground text-[10px]">연관 테이블의 컬럼을 선택하세요</p>
              </div>
              <hr className="border-border" />
              <div className="space-y-3">
                {entityJoinColumns.joinTables.map((joinTable, tableIndex) => (
                  <div key={tableIndex} className="space-y-1">
                    <div className="mb-1 flex items-center gap-2 text-[10px] font-medium text-primary">
                      <Link2 className="h-3 w-3" />
                      <span>{joinTable.tableName}</span>
                      <Badge variant="outline" className="text-[10px]">
                        {joinTable.currentDisplayColumn}
                      </Badge>
                    </div>
                    <div className="max-h-28 space-y-0.5 overflow-y-auto rounded-md border border-primary/20 bg-primary/10/30 p-2">
                      {joinTable.availableColumns.map((column, colIndex) => {
                        const matchingJoinColumn = entityJoinColumns.availableColumns.find(
                          (jc) => jc.tableName === joinTable.tableName && jc.columnName === column.columnName,
                        );
                        const isAlreadyAdded = config.columns?.some(
                          (col: ColumnConfig) => col.columnName === matchingJoinColumn?.joinAlias,
                        );
                        if (!matchingJoinColumn) return null;

                        return (
                          <div
                            key={colIndex}
                            className={cn(
                              "flex cursor-pointer items-center gap-2 rounded px-2 py-1 hover:bg-primary/10/50",
                              isAlreadyAdded && "bg-primary/10",
                            )}
                            onClick={() => {
                              if (isAlreadyAdded) {
                                handleChange(
                                  "columns",
                                  config.columns?.filter(
                                    (c: ColumnConfig) => c.columnName !== matchingJoinColumn.joinAlias,
                                  ) || [],
                                );
                              } else {
                                onAddEntityColumn(matchingJoinColumn);
                              }
                            }}
                          >
                            <Checkbox
                              checked={isAlreadyAdded}
                              onCheckedChange={() => {
                                if (isAlreadyAdded) {
                                  handleChange(
                                    "columns",
                                    config.columns?.filter(
                                      (c: ColumnConfig) => c.columnName !== matchingJoinColumn.joinAlias,
                                    ) || [],
                                  );
                                } else {
                                  onAddEntityColumn(matchingJoinColumn);
                                }
                              }}
                              className="pointer-events-none h-3.5 w-3.5"
                            />
                            <Link2 className="h-3 w-3 flex-shrink-0 text-primary" />
                            <span className="truncate text-xs">{column.columnLabel}</span>
                            {isAlreadyAdded && (
                              <button
                                type="button"
                                title={
                                  config.columns?.find((c: ColumnConfig) => c.columnName === matchingJoinColumn.joinAlias)?.editable === false
                                    ? "편집 잠금 (클릭하여 해제)"
                                    : "편집 가능 (클릭하여 잠금)"
                                }
                                className={cn(
                                  "ml-auto flex-shrink-0 rounded p-0.5 transition-colors",
                                  config.columns?.find((c: ColumnConfig) => c.columnName === matchingJoinColumn.joinAlias)?.editable === false
                                    ? "text-destructive hover:bg-destructive/10"
                                    : "text-muted-foreground hover:bg-muted",
                                )}
                                onClick={(e) => {
                                  e.stopPropagation();
                                  const currentCol = config.columns?.find((c: ColumnConfig) => c.columnName === matchingJoinColumn.joinAlias);
                                  if (currentCol) {
                                    onUpdateColumn(matchingJoinColumn.joinAlias, {
                                      editable: currentCol.editable === false ? undefined : false,
                                    });
                                  }
                                }}
                              >
                                {config.columns?.find((c: ColumnConfig) => c.columnName === matchingJoinColumn.joinAlias)?.editable === false ? (
                                  <Lock className="h-3 w-3" />
                                ) : (
                                  <Unlock className="h-3 w-3" />
                                )}
                              </button>
                            )}
                            <span className={cn("text-[10px] text-primary/80", !isAlreadyAdded && "ml-auto")}>
                              {column.inputType || column.dataType}
                            </span>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}
        </>
      )}

      {config.columns && config.columns.length > 0 && (
        <div className="space-y-3">
          <div>
            <h3 className="text-sm font-semibold">표시할 컬럼 ({config.columns.length}개 선택)</h3>
            <p className="text-muted-foreground text-[10px]">
              드래그하여 순서를 변경하거나 표시명/너비를 수정할 수 있습니다
            </p>
          </div>
          <hr className="border-border" />
          <DndContext
            collisionDetection={closestCenter}
            onDragEnd={(event: DragEndEvent) => {
              const { active, over } = event;
              if (!over || active.id === over.id) return;
              const columns = [...(config.columns || [])];
              const oldIndex = columns.findIndex((c: ColumnConfig) => c.columnName === active.id);
              const newIndex = columns.findIndex((c: ColumnConfig) => c.columnName === over.id);
              if (oldIndex !== -1 && newIndex !== -1) {
                const reordered = arrayMove(columns, oldIndex, newIndex);
                reordered.forEach((col: ColumnConfig, idx: number) => {
                  col.order = idx;
                });
                handleChange("columns", reordered);
              }
            }}
          >
            <SortableContext
              items={(config.columns || []).map((c: ColumnConfig) => c.columnName)}
              strategy={verticalListSortingStrategy}
            >
              <div className="space-y-1">
                {(config.columns || []).map((column: ColumnConfig, idx: number) => {
                  const resolvedLabel =
                    column.displayName && column.displayName !== column.columnName
                      ? column.displayName
                      : availableColumns.find((c) => c.columnName === column.columnName)?.label ||
                        column.displayName ||
                        column.columnName;
                  const colWithLabel = { ...column, displayName: resolvedLabel };
                  return (
                    <SortableColumnRow
                      key={column.columnName}
                      id={column.columnName}
                      col={colWithLabel}
                      index={idx}
                      isEntityJoin={!!column.isEntityJoin}
                      onLabelChange={(value) => onUpdateColumn(column.columnName, { displayName: value })}
                      onWidthChange={(value) => onUpdateColumn(column.columnName, { width: value })}
                      onRemove={() => onRemoveColumn(column.columnName)}
                    />
                  );
                })}
              </div>
            </SortableContext>
          </DndContext>
        </div>
      )}
    </div>
  );
};
