"use client";

/**
 * 플로우 편집기 페이지
 * - React Flow 기반 비주얼 플로우 편집
 * - 단계 추가/수정/삭제
 * - 단계 연결 생성/삭제
 * - 조건 설정
 */

import { useState, useEffect, useCallback } from "react";
import { useParams, useRouter } from "next/navigation";
import ReactFlow, {
  Node,
  Edge,
  addEdge,
  Connection,
  useNodesState,
  useEdgesState,
  Background,
  Controls,
  MiniMap,
  Panel,
} from "reactflow";
import "reactflow/dist/style.css";
import { ArrowLeft, Plus, Save, Play, Settings, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useToast } from "@/hooks/use-toast";
import {
  getFlowDefinition,
  getFlowSteps,
  getFlowConnections,
  createFlowStep,
  updateFlowStep,
  deleteFlowStep,
  createFlowConnection,
  deleteFlowConnection,
  getAllStepCounts,
} from "@/lib/api/flow";
import { FlowDefinition, FlowStep, FlowStepConnection, FlowNodeData } from "@/types/flow";
import { FlowNodeComponent } from "@/components/flow/FlowNodeComponent";
import { FlowStepPanel } from "@/components/flow/FlowStepPanel";
import { FlowConditionBuilder } from "@/components/flow/FlowConditionBuilder";

// 커스텀 노드 타입 등록
const nodeTypes = {
  flowStep: FlowNodeComponent,
};

export default function FlowEditorPage() {
  const params = useParams();
  const router = useRouter();
  const { toast } = useToast();
  const flowId = Number(params.id);

  // 상태
  const [flowDefinition, setFlowDefinition] = useState<FlowDefinition | null>(null);
  const [steps, setSteps] = useState<FlowStep[]>([]);
  const [connections, setConnections] = useState<FlowStepConnection[]>([]);
  const [selectedStep, setSelectedStep] = useState<FlowStep | null>(null);
  const [stepCounts, setStepCounts] = useState<Record<number, number>>({});
  const [loading, setLoading] = useState(true);

  // React Flow 상태
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);

  // 플로우 데이터 로드
  const loadFlowData = async () => {
    setLoading(true);
    try {
      // 플로우 정의 로드
      const flowRes = await getFlowDefinition(flowId);
      if (flowRes.success && flowRes.data) {
        console.log("🔍 Flow Definition loaded:", flowRes.data);
        console.log("📋 Table Name:", flowRes.data.definition?.tableName);
        setFlowDefinition(flowRes.data.definition);
      }

      // 단계 로드
      const stepsRes = await getFlowSteps(flowId);
      if (stepsRes.success && stepsRes.data) {
        setSteps(stepsRes.data);
      }

      // 연결 로드
      const connectionsRes = await getFlowConnections(flowId);
      if (connectionsRes.success && connectionsRes.data) {
        setConnections(connectionsRes.data);
      }

      // 데이터 카운트 로드
      const countsRes = await getAllStepCounts(flowId);
      if (countsRes.success && countsRes.data) {
        const counts: Record<number, number> = {};
        countsRes.data.forEach((item) => {
          counts[item.stepId] = item.count;
        });
        setStepCounts(counts);
      }
    } catch (error: any) {
      toast({
        title: "로딩 실패",
        description: error.message,
        variant: "destructive",
      });
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    loadFlowData();
  }, [flowId]);

  // React Flow 노드/엣지 변환
  useEffect(() => {
    if (steps.length === 0) return;

    // 노드 생성
    const newNodes: Node<FlowNodeData>[] = steps.map((step) => ({
      id: String(step.id),
      type: "flowStep",
      position: { x: step.positionX, y: step.positionY },
      data: {
        id: step.id,
        label: step.stepName,
        stepOrder: step.stepOrder,
        tableName: step.tableName,
        count: stepCounts[step.id] || 0,
        condition: step.conditionJson,
        integrationType: (step as any).integrationType,
        procedureName: (step as any).integrationConfig?.procedureName,
      },
    }));

    // 엣지 생성
    const newEdges: Edge[] = connections.map((conn) => ({
      id: String(conn.id),
      source: String(conn.fromStepId),
      target: String(conn.toStepId),
      label: conn.label,
      type: "smoothstep",
      animated: true,
    }));

    setNodes(newNodes);
    setEdges(newEdges);
  }, [steps, connections, stepCounts]);

  // 노드 추가
  const handleAddStep = async () => {
    const newStepOrder = steps.length + 1;
    const newStep = {
      stepName: `단계 ${newStepOrder}`,
      stepOrder: newStepOrder,
      color: "#3B82F6",
      positionX: 100 + newStepOrder * 250,
      positionY: 100,
    };

    try {
      const response = await createFlowStep(flowId, newStep);
      if (response.success && response.data) {
        toast({
          title: "단계 추가",
          description: "새로운 단계가 추가되었습니다.",
        });
        loadFlowData();
      }
    } catch (error: any) {
      toast({
        title: "추가 실패",
        description: error.message,
        variant: "destructive",
      });
    }
  };

  // 노드 위치 업데이트
  const handleNodeDragStop = useCallback(
    async (event: any, node: Node) => {
      const step = steps.find((s) => s.id === Number(node.id));
      if (!step) return;

      try {
        await updateFlowStep(step.id, {
          positionX: Math.round(node.position.x),
          positionY: Math.round(node.position.y),
        });
      } catch (error: any) {
        console.error("위치 업데이트 실패:", error);
      }
    },
    [steps],
  );

  // 연결 생성
  const handleConnect = useCallback(
    async (connection: Connection) => {
      if (!connection.source || !connection.target) return;

      try {
        const response = await createFlowConnection({
          flowDefinitionId: flowId,
          fromStepId: Number(connection.source),
          toStepId: Number(connection.target),
        });

        if (response.success) {
          toast({
            title: "연결 생성",
            description: "단계가 연결되었습니다.",
          });
          loadFlowData();
        }
      } catch (error: any) {
        toast({
          title: "연결 실패",
          description: error.message,
          variant: "destructive",
        });
      }
    },
    [flowId],
  );

  // 노드 클릭
  const handleNodeClick = useCallback(
    (event: React.MouseEvent, node: Node) => {
      const step = steps.find((s) => s.id === Number(node.id));
      if (step) {
        setSelectedStep(step);
      }
    },
    [steps],
  );

  if (loading) {
    return (
      <div className="container mx-auto p-6">
        <p>로딩 중...</p>
      </div>
    );
  }

  if (!flowDefinition) {
    return (
      <div className="container mx-auto p-6">
        <p>플로우를 찾을 수 없습니다.</p>
      </div>
    );
  }

  return (
    <div className="flex h-screen flex-col">
      {/* 헤더 */}
      <div className="border-b bg-white p-4">
        <div className="container mx-auto flex items-center justify-between">
          <div className="flex items-center gap-4">
            <Button variant="ghost" size="sm" onClick={() => router.push("/admin/flow-management")}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              목록으로
            </Button>
            <div>
              <h1 className="text-xl font-bold">{flowDefinition.name}</h1>
              <p className="text-muted-foreground text-sm">테이블: {flowDefinition.tableName}</p>
            </div>
          </div>

          <div className="flex gap-2">
            <Button variant="outline" size="sm" onClick={handleAddStep}>
              <Plus className="mr-2 h-4 w-4" />
              단계 추가
            </Button>
            <Button size="sm" onClick={() => loadFlowData()}>
              <Save className="mr-2 h-4 w-4" />
              새로고침
            </Button>
          </div>
        </div>
      </div>

      {/* 편집기 */}
      <div className="relative flex-1">
        <ReactFlow
          nodes={nodes}
          edges={edges}
          onNodesChange={onNodesChange}
          onEdgesChange={onEdgesChange}
          onConnect={handleConnect}
          onNodeClick={handleNodeClick}
          onNodeDragStop={handleNodeDragStop}
          nodeTypes={nodeTypes}
          fitView
          className="bg-muted"
        >
          <Background />
          <Controls />
          <MiniMap />

          <Panel position="top-right" className="rounded bg-white p-4 shadow">
            <div className="space-y-2 text-sm">
              <div>
                <strong>총 단계:</strong> {steps.length}개
              </div>
              <div>
                <strong>연결:</strong> {connections.length}개
              </div>
            </div>
          </Panel>
        </ReactFlow>
      </div>

      {/* 사이드 패널 */}
      {selectedStep && (
        <FlowStepPanel
          step={selectedStep}
          flowId={flowId}
          flowTableName={flowDefinition?.tableName} // 플로우 정의의 테이블명 전달
          flowDbSourceType={flowDefinition?.dbSourceType} // DB 소스 타입 전달
          flowDbConnectionId={flowDefinition?.dbConnectionId} // 외부 DB 연결 ID 전달
          flowRestApiConnectionId={flowDefinition?.restApiConnectionId} // REST API 연결 ID 전달
          flowRestApiEndpoint={flowDefinition?.restApiEndpoint} // REST API 엔드포인트 전달
          flowRestApiJsonPath={flowDefinition?.restApiJsonPath} // REST API JSON 경로 전달
          flowRestApiConnections={flowDefinition?.restApiConnections} // 다중 REST API 설정 전달
          onClose={() => setSelectedStep(null)}
          onUpdate={loadFlowData}
        />
      )}
    </div>
  );
}
