"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import {
  ReactFlow,
  Node,
  Edge,
  Position,
  MarkerType,
  Background,
  Controls,
  MiniMap,
  useNodesState,
  useEdgesState,
} from "@xyflow/react";
import "@xyflow/react/dist/style.css";
import { cn } from "@/lib/utils";
import { Monitor, Layers, ArrowRight, Loader2 } from "lucide-react";
import { ScreenDefinition } from "@/types/screen";
import { screenApi } from "@/lib/api/screen";

// ============================================================
// 타입 정의
// ============================================================

interface PopScreenFlowViewProps {
  screen: ScreenDefinition | null;
  className?: string;
  onSubScreenSelect?: (subScreenId: string) => void;
}

interface PopLayoutData {
  version?: string;
  sections?: any[];
  mainScreen?: {
    id: string;
    name: string;
  };
  subScreens?: SubScreen[];
  flow?: FlowConnection[];
}

interface SubScreen {
  id: string;
  name: string;
  type: "modal" | "drawer" | "fullscreen";
  triggerFrom?: string; // 어느 화면/버튼에서 트리거되는지
}

interface FlowConnection {
  from: string;
  to: string;
  trigger?: string;
  label?: string;
}

// ============================================================
// 커스텀 노드 컴포넌트
// ============================================================

interface ScreenNodeData {
  label: string;
  type: "main" | "modal" | "drawer" | "fullscreen";
  isMain?: boolean;
}

function ScreenNode({ data }: { data: ScreenNodeData }) {
  const isMain = data.type === "main" || data.isMain;

  return (
    <div
      className={cn(
        "min-w-[140px] rounded-lg border-2 px-4 py-3 text-center shadow-sm transition-colors",
        isMain
          ? "bg-primary/10 border-primary text-primary"
          : "bg-background border-muted-foreground/30 hover:border-muted-foreground/50",
      )}
    >
      <div className="mb-1 flex items-center justify-center gap-2">
        {isMain ? <Monitor className="h-4 w-4" /> : <Layers className="h-4 w-4" />}
        <span className="text-muted-foreground text-xs">
          {isMain ? "메인 화면" : data.type === "modal" ? "모달" : data.type === "drawer" ? "드로어" : "전체화면"}
        </span>
      </div>
      <div className="text-sm font-medium">{data.label}</div>
    </div>
  );
}

const nodeTypes = {
  screenNode: ScreenNode,
};

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

export function PopScreenFlowView({ screen, className, onSubScreenSelect }: PopScreenFlowViewProps) {
  const [loading, setLoading] = useState(false);
  const [layoutData, setLayoutData] = useState<PopLayoutData | null>(null);
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);

  // 레이아웃 데이터 로드
  useEffect(() => {
    if (!screen) {
      setLayoutData(null);
      setNodes([]);
      setEdges([]);
      return;
    }

    const loadLayout = async () => {
      try {
        setLoading(true);
        const layout = await screenApi.getLayoutPop(screen.screenId);

        if (layout && layout.version === "pop-1.0") {
          setLayoutData(layout);
        } else {
          setLayoutData(null);
        }
      } catch (error) {
        console.error("레이아웃 로드 실패:", error);
        setLayoutData(null);
      } finally {
        setLoading(false);
      }
    };

    loadLayout();
  }, [screen]);

  // 레이아웃 데이터에서 노드/엣지 생성
  useEffect(() => {
    if (!layoutData || !screen) {
      return;
    }

    const newNodes: Node[] = [];
    const newEdges: Edge[] = [];

    // 메인 화면 노드
    const mainNodeId = "main";
    newNodes.push({
      id: mainNodeId,
      type: "screenNode",
      position: { x: 50, y: 100 },
      data: {
        label: screen.screenName,
        type: "main",
        isMain: true,
      },
      sourcePosition: Position.Right,
      targetPosition: Position.Left,
    });

    // 하위 화면 노드들
    const subScreens = layoutData.subScreens || [];
    const horizontalGap = 200;
    const verticalGap = 100;

    subScreens.forEach((subScreen, index) => {
      // 세로로 나열, 여러 개일 경우 열 분리
      const col = Math.floor(index / 3);
      const row = index % 3;

      newNodes.push({
        id: subScreen.id,
        type: "screenNode",
        position: {
          x: 300 + col * horizontalGap,
          y: 50 + row * verticalGap,
        },
        data: {
          label: subScreen.name,
          type: subScreen.type || "modal",
        },
        sourcePosition: Position.Right,
        targetPosition: Position.Left,
      });
    });

    // 플로우 연결 (flow 배열 또는 triggerFrom 기반)
    const flows = layoutData.flow || [];

    if (flows.length > 0) {
      // 명시적 flow 배열 사용
      flows.forEach((flow, index) => {
        newEdges.push({
          id: `edge-${index}`,
          source: flow.from,
          target: flow.to,
          type: "smoothstep",
          animated: true,
          label: flow.label || flow.trigger,
          markerEnd: {
            type: MarkerType.ArrowClosed,
            color: "#888",
          },
          style: { stroke: "#888", strokeWidth: 2 },
        });
      });
    } else {
      // triggerFrom 기반으로 엣지 생성 (기본: 메인 → 서브)
      subScreens.forEach((subScreen, index) => {
        const sourceId = subScreen.triggerFrom || mainNodeId;
        newEdges.push({
          id: `edge-${index}`,
          source: sourceId,
          target: subScreen.id,
          type: "smoothstep",
          animated: true,
          markerEnd: {
            type: MarkerType.ArrowClosed,
            color: "#888",
          },
          style: { stroke: "#888", strokeWidth: 2 },
        });
      });
    }

    setNodes(newNodes);
    setEdges(newEdges);
  }, [layoutData, screen, setNodes, setEdges]);

  // 노드 클릭 핸들러
  const onNodeClick = useCallback(
    (_: React.MouseEvent, node: Node) => {
      if (node.id !== "main" && onSubScreenSelect) {
        onSubScreenSelect(node.id);
      }
    },
    [onSubScreenSelect],
  );

  // 레이아웃 또는 하위 화면이 없는 경우
  const hasSubScreens = layoutData?.subScreens && layoutData.subScreens.length > 0;

  if (!screen) {
    return (
      <div className={cn("bg-muted/30 flex h-full flex-col", className)}>
        <div className="bg-background shrink-0 border-b p-3">
          <h3 className="text-sm font-medium">화면 흐름</h3>
        </div>
        <div className="text-muted-foreground flex flex-1 items-center justify-center">
          <div className="text-center">
            <ArrowRight className="mx-auto mb-3 h-8 w-8 opacity-50" />
            <p className="text-sm">화면을 선택하면 흐름이 표시됩니다.</p>
          </div>
        </div>
      </div>
    );
  }

  if (loading) {
    return (
      <div className={cn("bg-muted/30 flex h-full flex-col", className)}>
        <div className="bg-background shrink-0 border-b p-3">
          <h3 className="text-sm font-medium">화면 흐름</h3>
        </div>
        <div className="flex flex-1 items-center justify-center">
          <Loader2 className="text-muted-foreground h-6 w-6 animate-spin" />
        </div>
      </div>
    );
  }

  if (!layoutData) {
    return (
      <div className={cn("bg-muted/30 flex h-full flex-col", className)}>
        <div className="bg-background shrink-0 border-b p-3">
          <h3 className="text-sm font-medium">화면 흐름</h3>
        </div>
        <div className="text-muted-foreground flex flex-1 items-center justify-center">
          <div className="text-center">
            <ArrowRight className="mx-auto mb-3 h-8 w-8 opacity-50" />
            <p className="text-sm">POP 레이아웃이 없습니다.</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className={cn("flex h-full flex-col", className)}>
      <div className="bg-background flex shrink-0 items-center justify-between border-b p-3">
        <div className="flex items-center gap-2">
          <h3 className="text-sm font-medium">화면 흐름</h3>
          <span className="text-muted-foreground text-xs">{screen.screenName}</span>
        </div>
        {!hasSubScreens && <span className="text-muted-foreground text-xs">하위 화면 없음</span>}
      </div>

      <div className="flex-1">
        {hasSubScreens ? (
          <ReactFlow
            nodes={nodes}
            edges={edges}
            onNodesChange={onNodesChange}
            onEdgesChange={onEdgesChange}
            onNodeClick={onNodeClick}
            nodeTypes={nodeTypes}
            fitView
            fitViewOptions={{ padding: 0.2 }}
            minZoom={0.5}
            maxZoom={1.5}
            proOptions={{ hideAttribution: true }}
          >
            <Background color="#ddd" gap={16} />
            <Controls showInteractive={false} />
            <MiniMap
              nodeColor={(node) => (node.data?.isMain ? "#3b82f6" : "#9ca3af")}
              maskColor="rgba(0, 0, 0, 0.1)"
              className="!bg-muted/50"
            />
          </ReactFlow>
        ) : (
          // 하위 화면이 없으면 간단한 단일 노드 표시
          <div className="bg-muted/10 flex h-full items-center justify-center">
            <div className="text-center">
              <div className="border-primary bg-primary/10 inline-flex items-center justify-center rounded-lg border-2 px-6 py-4">
                <Monitor className="text-primary mr-2 h-5 w-5" />
                <span className="text-primary font-medium">{screen.screenName}</span>
              </div>
              <p className="text-muted-foreground mt-4 text-xs">
                이 화면에 연결된 하위 화면(모달)이 없습니다.
                <br />
                화면 설정에서 하위 화면을 추가할 수 있습니다.
              </p>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
