import React, { useState, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  FileText,
  Database,
  Download,
  GitBranch,
  HardDrive,
  Hash,
  Activity,
  Trash2,
  AlertCircle,
  Plus,
} from "lucide-react";
import { Trace, KnowledgeGraph } from "@/types";
import { formatFileSize, formatRelativeTime } from "@/lib/utils";
import { getTraceStatusColor } from "@/lib/status-utils";
import { api } from "@/lib/api";
import { useModal } from "@/context/ModalContext";
import { useNotification } from "@/context/NotificationContext";
import { useNavigation } from "@/context/NavigationContext";
import { useAgentGraph } from "@/context/AgentGraphContext";
import { KnowledgeGraphTree } from "@/components/features/traces/KnowledgeGraphTree";
import { SplitterSelectionModal, SplitterType } from "./SplitterSelectionModal";
import { useTaskPolling } from "@/hooks/useTaskPolling";
import { ContextDocumentsSection } from "@/components/features/context/ContextDocumentsSection";

interface TraceDetailsModalProps {
  data: {
    trace: Trace;
    knowledgeGraphs?: KnowledgeGraph[];
  };
  onClose: () => void;
}

export function TraceDetailsModal({
  data,
  onClose: _onClose,
}: TraceDetailsModalProps) {
  const { trace, knowledgeGraphs = [] } = data;
  const { openModal } = useModal();
  const { showNotification } = useNotification();
  const { actions: navigationActions } = useNavigation();

  // Helper to show both toast and persistent notifications
  const showSystemNotification = useCallback(
    (notification: {
      type: "success" | "error" | "warning" | "info";
      title: string;
      message: string;
    }) => {
      // Show toast notification
      showNotification(notification);

      // Add to persistent notifications for all types
      navigationActions.addNotification({
        type: notification.type,
        title: notification.title,
        message: notification.message,
      });
    },
    [showNotification, navigationActions]
  );

  const { actions } = useAgentGraph();
  const [isSplitterModalOpen, setIsSplitterModalOpen] = useState(false);
  const [isGenerating, setIsGenerating] = useState(false);
  const [generationProgress, setGenerationProgress] = useState(0);

  const formatTraceType = (type?: string) => {
    if (!type) return "Unknown";
    return type.replace(/[-_]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
  };

  const handleViewKnowledgeGraph = (kgId: string) => {
    const kg = knowledgeGraphs.find((k) => k.kg_id === kgId || k.id === kgId);
    if (!kg) return;

    openModal(
      "knowledge-graph",
      `Knowledge Graph - ${
        kg.filename || `Agent Graph ${kg.kg_id?.slice(0, 8) || "unknown"}`
      }`,
      {
        knowledgeGraph: kg,
        windowGraphs: kg.window_knowledge_graphs || [],
      },
      {
        size: "xl",
        closable: true,
      }
    );
  };

  const handleViewSegment = async (
    traceId: string,
    startChar: number,
    endChar: number,
    windowIndex: number
  ) => {
    try {
      const segmentData = await api.traces.extractSegment(
        traceId,
        startChar,
        endChar
      );

      openModal(
        "trace-segment",
        `Trace Segment - Window ${windowIndex}`,
        {
          trace: trace,
          segment: {
            content: segmentData.content,
            startChar,
            endChar,
            windowIndex,
          },
        },
        {
          size: "xl",
          closable: true,
        }
      );
    } catch (error) {
      console.error("Error loading trace segment:", error);
      showSystemNotification({
        type: "error",
        title: "Failed to Load Segment",
        message: "Could not load the trace segment. Please try again.",
      });
    }
  };

  const handleDeleteKnowledgeGraph = async (kgId: string, name: string) => {
    const confirmMessage = `Are you sure you want to delete the knowledge graph "${name}"?

This will permanently remove:
• The knowledge graph and all entities/relationships
• All prompt reconstruction data
• All perturbation test results
• All causal analysis results

This action cannot be undone.`;

    if (!confirm(confirmMessage)) {
      return;
    }

    try {
      const response = await fetch(`/api/knowledge-graphs/${kgId}`, {
        method: "DELETE",
        headers: {
          "Content-Type": "application/json",
        },
      });

      if (!response.ok) {
        throw new Error(`API error: ${response.status} ${response.statusText}`);
      }

      const data = await response.json();
      console.log("Knowledge graph deleted:", data);

      // TODO: Add success notification and refresh knowledge graphs list
      alert("Knowledge graph deleted successfully");
    } catch (error) {
      console.error("Error deleting knowledge graph:", error);
      alert(
        `Error deleting knowledge graph: ${
          error instanceof Error ? error.message : String(error)
        }`
      );
    }
  };

  const handleReplayKg = (
    kgId: string,
    traceId: string,
    processingRunId?: string
  ) => {
    // Handle replay functionality
    console.log("Replay KG:", { kgId, traceId, processingRunId });
    // Implement actual replay logic
  };

  const handleGenerateKG = () => {
    setIsSplitterModalOpen(true);
  };

  // Task polling setup for knowledge graph generation
  const { pollTaskStatus, isPolling } = useTaskPolling({
    onSuccess: (taskId) => {
      console.log("Knowledge graph generation completed:", taskId);
      showSystemNotification({
        type: "success",
        title: "Agent Graph Generation Complete",
        message: "Your agent graph has been generated successfully!",
      });

      // Refresh the trace data to get the updated knowledge graphs
      actions.setTraces([]);
      actions.setKnowledgeGraphs([]);
      setIsGenerating(false);
      setGenerationProgress(0);
    },
    onError: (error, taskId) => {
      console.error("Knowledge graph generation failed:", error, taskId);

      // Check if this is a timeout vs a real failure
      const isTimeout =
        error.includes("timeout") || error.includes("timed out");

      showSystemNotification({
        type: isTimeout ? "warning" : "error",
        title: isTimeout
          ? "Generation Taking Longer Than Expected"
          : "Agent Graph Generation Failed",
        message: isTimeout
          ? `${error} You can refresh the page to check if it completed.`
          : error,
      });

      // Only reset state if it's not a timeout (user might want to keep waiting)
      if (!isTimeout) {
        setIsGenerating(false);
        setGenerationProgress(0);
      }
    },
    onProgress: (progress, message) => {
      setGenerationProgress(progress);
      if (message) {
        console.log("Generation progress:", progress, message);
      }
    },
    maxAttempts: 180, // 15 minutes with exponential backoff
    interval: 5000, // Start with 5 seconds
    enableExponentialBackoff: true,
  });

  const handleSplitterConfirm = async (
    splitterType: SplitterType,
    methodName?: string,
    modelName?: string,
    chunkingConfig?: { min_chunk_size?: number; max_chunk_size?: number }
  ) => {
    const finalMethodName = methodName || "production";
    console.log("TraceDetailsModal: Using method name:", finalMethodName);
    console.log("TraceDetailsModal: Using chunking config:", chunkingConfig);

    setIsGenerating(true);
    setIsSplitterModalOpen(false); // Safety fallback - modal should already be closed
    setGenerationProgress(0);

    try {
      const response = await api.traces.generateKnowledgeGraph(
        trace.trace_id,
        splitterType,
        true,
        finalMethodName,
        modelName || "gpt-5-mini",
        chunkingConfig
      );

      showSystemNotification({
        type: "info",
        title: "Agent Graph Generation Started",
        message: `Using ${getSplitterDisplayName(
          splitterType
        )} splitter with ${finalMethodName} method. This may take several minutes.`,
      });

      // Start polling for task status if we got a task_id
      if (response.task_id) {
        pollTaskStatus(response.task_id);
      } else {
        // If no task_id, just refresh immediately and mark as complete
        const updatedTraces = await api.traces.list();
        actions.setTraces(updatedTraces);
        const updatedKGs = await api.knowledgeGraphs.list();
        actions.setKnowledgeGraphs(updatedKGs);
        setIsGenerating(false);
        showSystemNotification({
          type: "success",
          title: "Agent Graph Generation Complete",
          message: "Your agent graph has been generated successfully!",
        });
      }
    } catch (error) {
      console.error("Failed to generate knowledge graph:", error);
      showSystemNotification({
        type: "error",
        title: "Agent Graph Generation Failed",
        message: "Failed to start agent graph generation. Please try again.",
      });
      setIsGenerating(false);
      setGenerationProgress(0);
    }
  };

  // Helper function to get display name for splitter type
  const getSplitterDisplayName = (splitterType: SplitterType) => {
    switch (splitterType) {
      case "agent_semantic":
        return "Agent Semantic";
      case "json":
        return "JSON";
      case "prompt_interaction":
        return "Prompt Interaction";
      default:
        return splitterType;
    }
  };

  const handleViewContent = async () => {
    try {
      // Get numbered content for ContentReference compatibility
      const numberedContent = await api.traces.getNumberedContent(
        trace.trace_id
      );
      openModal(
        "trace-content",
        `Trace Content - ${trace.filename}`,
        {
          trace: trace,
          content: { content: numberedContent, type: "numbered" },
        },
        {
          size: "xl",
          closable: true,
        }
      );
    } catch (error) {
      console.error("Failed to load numbered content:", error);
      // Fallback to existing content if numbered content fails
      openModal(
        "trace-content",
        `Trace Content - ${trace.filename}`,
        {
          trace: trace,
          content: { content: trace.content || "", type: "raw" },
        },
        {
          size: "xl",
          closable: true,
        }
      );
    }
  };

  const handleDownloadTrace = async () => {
    try {
      // Get the full trace content instead of just metadata
      const traceContent = await api.traces.getContent(trace.trace_id);

      // Create blob with the actual trace content
      const blob = new Blob([traceContent], {
        type: "application/json",
      });
      const url = URL.createObjectURL(blob);

      const exportFileDefaultName = `${trace.filename || "trace"}.json`;

      const linkElement = document.createElement("a");
      linkElement.setAttribute("href", url);
      linkElement.setAttribute("download", exportFileDefaultName);
      linkElement.click();

      // Clean up the object URL
      URL.revokeObjectURL(url);

      console.log("Trace downloaded successfully:", trace.trace_id);
    } catch (error) {
      console.error("Failed to download trace:", error);
      alert("Failed to download trace. Please try again.");
    }
  };

  const handleDeleteTrace = async () => {
    const kgCount = knowledgeGraphs.length;
    const displayFilename =
      trace.filename.length > 50
        ? `${trace.filename.substring(0, 47)}...`
        : trace.filename;
    const confirmMessage = `Are you sure you want to delete the trace "${displayFilename}"?

This will permanently remove:
• The trace and all its content
• All associated knowledge graphs (${kgCount} found)
• All entities and relationships
• All prompt reconstruction data
• All perturbation test results
• All causal analysis results

This action cannot be undone.`;

    if (!confirm(confirmMessage)) {
      return;
    }

    try {
      await api.traces.delete(trace.trace_id);

      // Close modal and refresh page
      window.location.reload();
    } catch (error) {
      console.error("Error deleting trace:", error);
      alert(
        `Error deleting trace: ${
          error instanceof Error ? error.message : String(error)
        }`
      );
    }
  };

  // Calculate summary statistics - use consistent counting
  const finalKGsArray = knowledgeGraphs.filter(
    (kg) =>
      kg.is_final === true ||
      (kg.window_index === null && kg.window_total !== null)
  );
  const finalKGs = finalKGsArray.length; // Count of final KGs
  const totalKGs = finalKGs; // Use final KG count for consistency
  const completedPipelines = knowledgeGraphs.filter(
    (kg) => kg.is_analyzed
  ).length;

  return (
    <div className="space-y-6 p-6 max-h-[90vh] overflow-y-auto">
      {/* Trace Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="p-2 rounded-lg bg-primary/10">
            <FileText className="h-6 w-6 text-primary" />
          </div>
          <div>
            <h2 className="text-xl font-semibold">{trace.filename}</h2>
            <p className="text-sm text-muted-foreground">
              Uploaded{" "}
              {formatRelativeTime(
                trace.upload_timestamp || trace.timestamp || ""
              )}
            </p>
          </div>
        </div>
        <Badge variant="outline" className={getTraceStatusColor(trace.status)}>
          {trace.status}
        </Badge>
      </div>

      {/* Quick Stats */}
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
        <Card className="p-4 quick-stats-card">
          <div className="flex items-center gap-2">
            <HardDrive className="h-4 w-4 text-muted-foreground" />
            <div>
              <p className="text-2xl font-bold">
                {formatFileSize(trace.character_count || trace.size || 0)}
              </p>
              <p className="text-xs text-muted-foreground">File Size</p>
            </div>
          </div>
        </Card>

        <Card className="p-4 quick-stats-card">
          <div className="flex items-center gap-2">
            <GitBranch className="h-4 w-4 text-muted-foreground" />
            <div>
              <p className="text-2xl font-bold">{trace.turn_count || 0}</p>
              <p className="text-xs text-muted-foreground">Turns</p>
            </div>
          </div>
        </Card>

        <Card className="p-4 quick-stats-card">
          <div className="flex items-center gap-2">
            <Activity className="h-4 w-4 text-muted-foreground" />
            <div>
              <p className="text-2xl font-bold">{finalKGs}</p>
              <p className="text-xs text-muted-foreground">
                Final Agent Graphs
              </p>
            </div>
          </div>
        </Card>

        <Card className="p-4 quick-stats-card">
          <div className="flex items-center gap-2">
            <Database className="h-4 w-4 text-muted-foreground" />
            <div>
              <p className="text-2xl font-bold">{completedPipelines}</p>
              <p className="text-xs text-muted-foreground">Completed</p>
            </div>
          </div>
        </Card>
      </div>

      {/* Trace Information */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Database className="h-5 w-5" />
            Trace Information
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* Core Information Grid */}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {/* Characters */}
            <Card className="p-4 bg-muted/30">
              <div className="flex items-center gap-3">
                <div className="p-2 rounded-lg bg-primary/10">
                  <Hash className="h-4 w-4 text-primary" />
                </div>
                <div className="flex-1">
                  <p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">
                    Content Size
                  </p>
                  <p className="text-lg font-semibold">
                    {trace.character_count?.toLocaleString() || "N/A"} chars
                  </p>
                  {trace.turn_count && (
                    <p className="text-sm text-muted-foreground">
                      {trace.turn_count} turns
                    </p>
                  )}
                </div>
              </div>
            </Card>

            {/* Type & Upload Info */}
            <Card className="p-4 bg-muted/30">
              <div className="flex items-center gap-3">
                <div className="p-2 rounded-lg bg-primary/10">
                  <FileText className="h-4 w-4 text-primary" />
                </div>
                <div className="flex-1">
                  <p className="text-xs text-muted-foreground uppercase tracking-wide font-medium">
                    Type & Date
                  </p>
                  <p className="text-lg font-semibold">
                    {formatTraceType(trace.trace_type)}
                  </p>
                  <p className="text-sm text-muted-foreground">
                    {new Date(
                      trace.upload_timestamp || trace.timestamp || ""
                    ).toLocaleDateString()}
                  </p>
                </div>
              </div>
            </Card>
          </div>

          {/* Description */}
          {trace.description && (
            <div className="space-y-2">
              <p className="text-sm font-medium flex items-center gap-2">
                <FileText className="h-4 w-4 text-muted-foreground" />
                Description
              </p>
              <div className="p-4 rounded-lg bg-muted/30 border-l-4 border-primary">
                <p className="text-sm text-muted-foreground leading-relaxed">
                  {trace.description}
                </p>
              </div>
            </div>
          )}

          {/* Error Message */}
          {trace.error_message && (
            <div className="space-y-2">
              <p className="text-sm font-medium text-destructive flex items-center gap-2">
                <AlertCircle className="h-4 w-4" />
                Error Message
              </p>
              <div className="p-4 rounded-lg bg-destructive/10 border border-destructive/20">
                <p className="text-sm text-destructive font-mono">
                  {trace.error_message}
                </p>
              </div>
            </div>
          )}

          {/* Tags */}
          {trace.tags && trace.tags.length > 0 && (
            <div className="space-y-3">
              <p className="text-sm font-medium flex items-center gap-2">
                <Hash className="h-4 w-4 text-muted-foreground" />
                Tags
              </p>
              <div className="flex flex-wrap gap-2">
                {trace.tags.map((tag) => (
                  <Badge
                    key={tag}
                    variant="secondary"
                    className="text-xs px-3 py-1"
                  >
                    {tag}
                  </Badge>
                ))}
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Context Documents Section */}
      <ContextDocumentsSection traceId={trace.trace_id} />

      {/* Knowledge Graphs using KnowledgeGraphTree */}
      {knowledgeGraphs.length > 0 ? (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Activity className="h-5 w-5" />
                Agent Graphs ({totalKGs})
              </div>
              <div className="flex items-center gap-2">
                <Button
                  onClick={handleGenerateKG}
                  disabled={isGenerating || isPolling}
                  size="sm"
                  className="bg-primary hover:bg-primary/90"
                >
                  {isGenerating || isPolling ? (
                    <>
                      <div className="w-3 h-3 border-2 border-white border-t-transparent rounded-full animate-spin mr-2" />
                      {generationProgress > 0
                        ? `${Math.round(generationProgress)}%`
                        : "Generating..."}
                    </>
                  ) : (
                    <>
                      <Plus className="h-3 w-3 mr-2" />
                      Generate
                    </>
                  )}
                </Button>
                <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  <span>{finalKGs} Final</span>
                  <span>•</span>
                  <span>{completedPipelines} Completed</span>
                </div>
              </div>
            </CardTitle>
          </CardHeader>
          <CardContent className="pt-0">
            <KnowledgeGraphTree
              knowledgeGraphs={knowledgeGraphs}
              _onViewKg={handleViewKnowledgeGraph}
              onDeleteKg={handleDeleteKnowledgeGraph}
              onReplayKg={handleReplayKg}
              onViewSegment={handleViewSegment}
              currentTraceId={trace.trace_id}
            />
          </CardContent>
        </Card>
      ) : (
        <Card>
          <CardContent className="p-6 text-center empty-state">
            <div className="text-muted-foreground">
              <Activity className="h-8 w-8 mx-auto mb-3 empty-state-icon" />
              <p className="font-medium mb-2">Ready to analyze this trace</p>
              <p className="text-sm text-muted-foreground mb-1">
                Transform your trace data into an interactive agent graph.
              </p>
              <p className="text-xs text-muted-foreground mb-4">
                Choose from different chunking strategies for optimal analysis.
              </p>
            </div>
            <Button
              onClick={handleGenerateKG}
              className="mt-2 bg-primary hover:bg-primary/90"
              size="sm"
            >
              <Plus className="h-4 w-4 mr-2" />
              Generate Agent Graph
            </Button>
          </CardContent>
        </Card>
      )}

      {/* Metadata */}
      {trace.metadata && Object.keys(trace.metadata).length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle>Metadata</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="space-y-2">
              {Object.entries(trace.metadata).map(([key, value]) => (
                <div key={key} className="flex justify-between">
                  <span className="text-sm font-medium">{key}:</span>
                  <span className="text-sm text-muted-foreground">
                    {typeof value === "object"
                      ? JSON.stringify(value, null, 2)
                      : String(value)}
                  </span>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      )}

      {/* Actions */}
      <div className="flex gap-2 pt-4 border-t action-button-group">
        <Button onClick={handleViewContent}>
          <FileText className="h-4 w-4 mr-2" />
          View Content
        </Button>
        <Button variant="outline" onClick={handleGenerateKG}>
          <Activity className="h-4 w-4 mr-2" />
          Generate Knowledge Graph
        </Button>
        <Button variant="outline" onClick={handleDownloadTrace}>
          <Download className="h-4 w-4 mr-2" />
          Download Trace
        </Button>
        <Button variant="destructive" onClick={handleDeleteTrace}>
          <Trash2 className="h-4 w-4 mr-2" />
          Delete Trace
        </Button>
      </div>

      <SplitterSelectionModal
        open={isSplitterModalOpen}
        onOpenChange={setIsSplitterModalOpen}
        onConfirm={handleSplitterConfirm}
        isLoading={isGenerating}
      />
    </div>
  );
}
