"use client";

import React from "react";
import { ArrowRight, Link2, Unlink2, Plus, Trash2, Pencil, X, Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  PopComponentDefinition,
  PopDataConnection,
} from "../types/pop-layout";
import {
  PopComponentRegistry,
} from "@/lib/registry/PopComponentRegistry";
import { getTableColumns } from "@/lib/api/tableManagement";

// ========================================
// Props
// ========================================

interface ConnectionEditorProps {
  component: PopComponentDefinition;
  allComponents: PopComponentDefinition[];
  connections: PopDataConnection[];
  onAddConnection?: (conn: Omit<PopDataConnection, "id">) => void;
  onUpdateConnection?: (connectionId: string, conn: Omit<PopDataConnection, "id">) => void;
  onRemoveConnection?: (connectionId: string) => void;
}

// ========================================
// ConnectionEditor
// ========================================

export default function ConnectionEditor({
  component,
  allComponents,
  connections,
  onAddConnection,
  onUpdateConnection,
  onRemoveConnection,
}: ConnectionEditorProps) {
  const registeredComp = PopComponentRegistry.getComponent(component.type);
  const meta = registeredComp?.connectionMeta;

  const outgoing = connections.filter(
    (c) => c.sourceComponent === component.id
  );
  const incoming = connections.filter(
    (c) => c.targetComponent === component.id
  );

  const hasSendable = meta?.sendable && meta.sendable.length > 0;
  const hasReceivable = meta?.receivable && meta.receivable.length > 0;

  if (!hasSendable && !hasReceivable) {
    return (
      <div className="space-y-4">
        <div className="rounded-lg bg-muted p-4 text-center">
          <Link2 className="mx-auto mb-2 h-8 w-8 text-muted-foreground" />
          <p className="text-sm font-medium text-foreground">연결 없음</p>
          <p className="mt-1 text-xs text-muted-foreground">
            이 컴포넌트는 다른 컴포넌트와 연결할 수 없습니다
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {hasSendable && (
        <SendSection
          component={component}
          allComponents={allComponents}
          outgoing={outgoing}
          onAddConnection={onAddConnection}
          onUpdateConnection={onUpdateConnection}
          onRemoveConnection={onRemoveConnection}
        />
      )}

      {hasReceivable && (
        <ReceiveSection
          component={component}
          allComponents={allComponents}
          incoming={incoming}
        />
      )}
    </div>
  );
}

// ========================================
// 보내기 섹션
// ========================================

interface SendSectionProps {
  component: PopComponentDefinition;
  allComponents: PopComponentDefinition[];
  outgoing: PopDataConnection[];
  onAddConnection?: (conn: Omit<PopDataConnection, "id">) => void;
  onUpdateConnection?: (connectionId: string, conn: Omit<PopDataConnection, "id">) => void;
  onRemoveConnection?: (connectionId: string) => void;
}

function SendSection({
  component,
  allComponents,
  outgoing,
  onAddConnection,
  onUpdateConnection,
  onRemoveConnection,
}: SendSectionProps) {
  const [editingId, setEditingId] = React.useState<string | null>(null);

  return (
    <div className="space-y-3">
      <Label className="flex items-center gap-1 text-xs font-medium">
        <ArrowRight className="h-3 w-3 text-primary" />
        보내기
      </Label>

      {outgoing.map((conn) => (
        <div key={conn.id}>
          {editingId === conn.id ? (
            <SimpleConnectionForm
              component={component}
              allComponents={allComponents}
              initial={conn}
              onSubmit={(data) => {
                onUpdateConnection?.(conn.id, data);
                setEditingId(null);
              }}
              onCancel={() => setEditingId(null)}
              submitLabel="수정"
            />
          ) : (
            <div className="space-y-1 rounded border bg-primary/10 px-3 py-2">
              <div className="flex items-center gap-1">
              <span className="flex-1 truncate text-xs">
                {conn.label || `→ ${allComponents.find((c) => c.id === conn.targetComponent)?.label || conn.targetComponent}`}
              </span>
              <button
                onClick={() => setEditingId(conn.id)}
                className="shrink-0 p-0.5 text-muted-foreground hover:text-primary"
              >
                <Pencil className="h-3 w-3" />
              </button>
              {onRemoveConnection && (
                <button
                  onClick={() => onRemoveConnection(conn.id)}
                  className="shrink-0 p-0.5 text-muted-foreground hover:text-destructive"
                >
                  <Trash2 className="h-3 w-3" />
                </button>
              )}
              </div>
              {conn.filterConfig?.targetColumn && (
                <div className="flex flex-wrap gap-1">
                  <span className="rounded bg-white px-1.5 py-0.5 text-[9px] text-muted-foreground">
                    {conn.filterConfig.targetColumn}
                  </span>
                  <span className="rounded bg-white px-1.5 py-0.5 text-[9px] text-muted-foreground">
                    {conn.filterConfig.filterMode}
                  </span>
                  {conn.filterConfig.isSubTable && (
                    <span className="rounded bg-amber-100 px-1.5 py-0.5 text-[9px] text-amber-700">
                      자동 판단
                    </span>
                  )}
                </div>
              )}
            </div>
          )}
        </div>
      ))}

      <SimpleConnectionForm
        component={component}
        allComponents={allComponents}
        onSubmit={(data) => onAddConnection?.(data)}
        submitLabel="연결 추가"
      />
    </div>
  );
}

// ========================================
// 단순 연결 폼 (이벤트 타입: "어디로" 1개만)
// ========================================

interface SimpleConnectionFormProps {
  component: PopComponentDefinition;
  allComponents: PopComponentDefinition[];
  initial?: PopDataConnection;
  onSubmit: (data: Omit<PopDataConnection, "id">) => void;
  onCancel?: () => void;
  submitLabel: string;
}

function extractSubTableName(comp: PopComponentDefinition): string | null {
  const cfg = comp.config as Record<string, unknown> | undefined;
  if (!cfg) return null;

  const grid = cfg.cardGrid as { cells?: Array<{ timelineSource?: { processTable?: string } }> } | undefined;
  if (grid?.cells) {
    for (const cell of grid.cells) {
      if (cell.timelineSource?.processTable) return cell.timelineSource.processTable;
    }
  }
  return null;
}

function SimpleConnectionForm({
  component,
  allComponents,
  initial,
  onSubmit,
  onCancel,
  submitLabel,
}: SimpleConnectionFormProps) {
  const [selectedTargetId, setSelectedTargetId] = React.useState(
    initial?.targetComponent || ""
  );
  const [targetColumn, setTargetColumn] = React.useState(
    initial?.filterConfig?.targetColumn || ""
  );
  const [filterMode, setFilterMode] = React.useState<string>(
    initial?.filterConfig?.filterMode || "equals"
  );

  const [subColumns, setSubColumns] = React.useState<string[]>([]);
  const [loadingColumns, setLoadingColumns] = React.useState(false);

  const targetCandidates = allComponents.filter((c) => {
    if (c.id === component.id) return false;
    const reg = PopComponentRegistry.getComponent(c.type);
    return reg?.connectionMeta?.receivable && reg.connectionMeta.receivable.length > 0;
  });

  const sourceReg = PopComponentRegistry.getComponent(component.type);
  const targetComp = allComponents.find((c) => c.id === selectedTargetId);
  const targetReg = targetComp ? PopComponentRegistry.getComponent(targetComp.type) : null;
  const isFilterConnection = sourceReg?.connectionMeta?.sendable?.some((s) => s.type === "filter_value")
    && targetReg?.connectionMeta?.receivable?.some((r) => r.type === "filter_value");

  const subTableName = targetComp ? extractSubTableName(targetComp) : null;
  const mainTableName = (() => {
    const cfg = targetComp?.config as Record<string, unknown> | undefined;
    const ds = cfg?.dataSource as { tableName?: string } | undefined;
    return ds?.tableName || null;
  })();

  React.useEffect(() => {
    if (!isFilterConnection || !selectedTargetId) {
      setSubColumns([]);
      return;
    }
    const tables = [mainTableName, subTableName].filter(Boolean) as string[];
    if (tables.length === 0) { setSubColumns([]); return; }
    setLoadingColumns(true);
    Promise.all(tables.map((t) => getTableColumns(t)))
      .then((results) => {
        const allCols = new Set<string>();
        for (const res of results) {
          const cols = res.success && res.data?.columns;
          if (Array.isArray(cols)) {
            cols.forEach((c) => { if (c.columnName) allCols.add(c.columnName); });
          }
        }
        setSubColumns([...allCols].sort());
      })
      .catch(() => setSubColumns([]))
      .finally(() => setLoadingColumns(false));
  }, [isFilterConnection, selectedTargetId, mainTableName, subTableName]);

  const handleSubmit = () => {
    if (!selectedTargetId) return;

    const tComp = allComponents.find((c) => c.id === selectedTargetId);
    const srcLabel = component.label || component.id;
    const tgtLabel = tComp?.label || tComp?.id || "?";

    const conn: Omit<PopDataConnection, "id"> = {
      sourceComponent: component.id,
      sourceField: "",
      sourceOutput: "_auto",
      targetComponent: selectedTargetId,
      targetField: "",
      targetInput: "_auto",
      label: `${srcLabel} → ${tgtLabel}`,
    };

    if (isFilterConnection && targetColumn) {
      conn.filterConfig = {
        targetColumn,
        filterMode: filterMode as "equals" | "contains" | "starts_with" | "range",
      };
    }

    onSubmit(conn);

    if (!initial) {
      setSelectedTargetId("");
      setTargetColumn("");
      setFilterMode("equals");
    }
  };

  return (
    <div className="space-y-2 rounded border border-dashed p-3">
      {onCancel && (
        <div className="flex items-center justify-between">
          <p className="text-[10px] font-medium text-muted-foreground">연결 수정</p>
          <button onClick={onCancel} className="text-muted-foreground hover:text-foreground">
            <X className="h-3 w-3" />
          </button>
        </div>
      )}
      {!onCancel && (
        <p className="text-[10px] font-medium text-muted-foreground">새 연결 추가</p>
      )}

      <div className="space-y-1">
        <span className="text-[10px] text-muted-foreground">어디로?</span>
        <Select
          value={selectedTargetId}
          onValueChange={(v) => {
            setSelectedTargetId(v);
            setTargetColumn("");
          }}
        >
          <SelectTrigger className="h-7 text-xs">
            <SelectValue placeholder="컴포넌트 선택" />
          </SelectTrigger>
          <SelectContent>
            {targetCandidates.map((c) => (
              <SelectItem key={c.id} value={c.id} className="text-xs">
                {c.label || c.id}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      {isFilterConnection && selectedTargetId && (
        <div className="space-y-2 rounded bg-muted/50 p-2">
          <div className="space-y-1">
            <span className="text-[10px] text-muted-foreground">대상 컬럼</span>
            {loadingColumns ? (
              <div className="flex items-center gap-1 py-1">
                <Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />
                <span className="text-[10px] text-muted-foreground">컬럼 로딩 중...</span>
              </div>
            ) : (
              <Select value={targetColumn} onValueChange={setTargetColumn}>
                <SelectTrigger className="h-7 text-xs">
                  <SelectValue placeholder="컬럼 선택" />
                </SelectTrigger>
                <SelectContent>
                  {subColumns.filter(Boolean).map((col) => (
                    <SelectItem key={col} value={col} className="text-xs">
                      {col}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            )}
          </div>

          <div className="space-y-1">
            <span className="text-[10px] text-muted-foreground">비교 방식</span>
            <Select value={filterMode} onValueChange={setFilterMode}>
              <SelectTrigger className="h-7 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="equals" className="text-xs">일치 (equals)</SelectItem>
                <SelectItem value="contains" className="text-xs">포함 (contains)</SelectItem>
                <SelectItem value="starts_with" className="text-xs">시작 (starts_with)</SelectItem>
              </SelectContent>
            </Select>
          </div>
          <p className="text-[9px] text-muted-foreground">
            메인/하위 테이블 구분은 자동으로 판단됩니다
          </p>
        </div>
      )}

      <Button
        size="sm"
        variant="outline"
        className="h-7 w-full text-xs"
        disabled={!selectedTargetId}
        onClick={handleSubmit}
      >
        {!initial && <Plus className="mr-1 h-3 w-3" />}
        {submitLabel}
      </Button>
    </div>
  );
}

// ========================================
// 받기 섹션 (읽기 전용: 연결된 소스만 표시)
// ========================================

interface ReceiveSectionProps {
  component: PopComponentDefinition;
  allComponents: PopComponentDefinition[];
  incoming: PopDataConnection[];
}

function ReceiveSection({
  component,
  allComponents,
  incoming,
}: ReceiveSectionProps) {
  return (
    <div className="space-y-3">
      <Label className="flex items-center gap-1 text-xs font-medium">
        <Unlink2 className="h-3 w-3 text-emerald-500" />
        받기
      </Label>

      {incoming.length > 0 ? (
        <div className="space-y-1">
          {incoming.map((conn) => {
            const sourceComp = allComponents.find(
              (c) => c.id === conn.sourceComponent
            );
            return (
              <div
                key={conn.id}
                className="flex items-center gap-2 rounded border bg-emerald-50/50 px-3 py-2 text-xs"
              >
                <ArrowRight className="h-3 w-3 text-emerald-500" />
                <span className="truncate">
                  {sourceComp?.label || conn.sourceComponent}
                </span>
              </div>
            );
          })}
        </div>
      ) : (
        <p className="text-xs text-muted-foreground">
          연결된 소스가 없습니다
        </p>
      )}
    </div>
  );
}

