import React, { useEffect, useRef, useState, useMemo } from "react";
import {
  ChevronLeft,
  ChevronRight,
  ChevronUp,
  ChevronDown,
  Info,
  Database,
  BarChart3,
  Cpu,
  GitBranch,
  Clock,
  Layers,
} from "lucide-react";
import { Button } from "../ui/button";
import { Card, CardContent } from "../ui/card";
import Editor from "@monaco-editor/react";
import type { editor } from "monaco-editor";
import { KnowledgeGraph } from "@/types";

interface Range {
  start: number; // 0-based inclusive
  end: number; // 0-based inclusive
}

interface TraceViewerSidebarProps {
  numberedLines: string[]; // each already prefixed with <L#>
  highlightRanges: Range[];
  widthClass?: string; // tailwind width override (default w-80)
  knowledgeGraph?: KnowledgeGraph; // optional knowledge graph data for system tab
  showTraceTab?: boolean; // whether to show the trace tab (default true)
}

interface LineMapping {
  originalLineNumber: number;
  startChar: number;
  endChar: number;
  content: string;
}

export const TraceViewerSidebar: React.FC<TraceViewerSidebarProps> = ({
  numberedLines,
  highlightRanges,
  widthClass = "w-80",
  knowledgeGraph,
  showTraceTab = true,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null);
  const [isCollapsed, setIsCollapsed] = useState(false);
  const [currentHighlightIndex, setCurrentHighlightIndex] = useState(0);
  const [decorations, setDecorations] = useState<string[]>([]);
  const [activeTab, setActiveTab] = useState<"system" | "trace">("system");

  // Parse numbered lines and reconstruct original content
  const { reconstructedContent, characterRanges } = useMemo(() => {
    const mapping: LineMapping[] = [];

    // Parse each numbered line and extract line numbers
    const parsedLines: {
      lineNumber: number;
      content: string;
      index: number;
    }[] = [];

    for (let i = 0; i < numberedLines.length; i++) {
      const line = numberedLines[i];
      if (!line) continue;

      const match = line.match(/^<L(\d+)>\s*(.*)$/);
      if (!match) continue;

      const [, lineNumber, content] = match;
      if (!lineNumber || content === undefined) continue;

      parsedLines.push({
        lineNumber: parseInt(lineNumber),
        content,
        index: i,
      });
    }

    // Sort by line number to ensure proper order
    parsedLines.sort((a, b) => a.lineNumber - b.lineNumber);

    // Simple concatenation - just join all content together
    let rawContent = "";
    for (let i = 0; i < parsedLines.length; i++) {
      const currentLine = parsedLines[i];
      if (!currentLine) continue;

      // Track character mapping for highlighting
      const startChar = rawContent.length;
      rawContent += currentLine.content;
      const endChar = rawContent.length;

      mapping.push({
        originalLineNumber: currentLine.lineNumber,
        startChar,
        endChar,
        content: currentLine.content,
      });
    }

    // Process the raw content for better formatting
    let processedContent = rawContent;

    // Convert literal \\n to actual line breaks
    processedContent = processedContent.replace(/\\n/g, "\n");

    // Convert literal \\t to actual tabs
    processedContent = processedContent.replace(/\\t/g, "\t");

    // Try to detect and format JSON content (handle multiple JSON objects)
    const jsonRegex = /\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}/g;
    const jsonMatches = processedContent.match(jsonRegex);

    if (jsonMatches) {
      jsonMatches.forEach((jsonStr) => {
        try {
          const parsed = JSON.parse(jsonStr);
          const formatted = JSON.stringify(parsed, null, 2);
          processedContent = processedContent.replace(jsonStr, formatted);
        } catch (e) {
          // If JSON parsing fails, keep original content
        }
      });
    }

    // Clean up excessive whitespace but preserve intentional formatting
    processedContent = processedContent
      .replace(/[ \t]+/g, " ") // Multiple spaces/tabs to single space
      .replace(/\n\s*\n\s*\n/g, "\n\n") // Multiple newlines to double newline max
      .trim(); // Remove leading/trailing whitespace

    // Update character mapping based on content transformation
    const contentLengthDiff = processedContent.length - rawContent.length;

    // Convert line-based ranges to character-based ranges
    const charRanges = highlightRanges
      .map((range) => {
        const startMapping = mapping.find(
          (m) => m.originalLineNumber === range.start + 1
        );
        const endMapping = mapping.find(
          (m) => m.originalLineNumber === range.end + 1
        );

        if (!startMapping || !endMapping) {
          return { startChar: 0, endChar: 0 };
        }

        // Adjust for content transformation
        let adjustedStartChar = startMapping.startChar;
        let adjustedEndChar = endMapping.endChar;

        // Simple adjustment - this might need refinement for complex cases
        if (contentLengthDiff > 0) {
          const adjustmentRatio = processedContent.length / rawContent.length;
          adjustedStartChar = Math.floor(
            startMapping.startChar * adjustmentRatio
          );
          adjustedEndChar = Math.floor(endMapping.endChar * adjustmentRatio);
        }

        return {
          startChar: adjustedStartChar,
          endChar: adjustedEndChar,
        };
      })
      .filter((range) => range.startChar !== range.endChar);

    return {
      reconstructedContent: processedContent,
      characterRanges: charRanges,
    };
  }, [numberedLines, highlightRanges]);

  // Sort ranges by start position for navigation
  const sortedRanges = [...characterRanges].sort(
    (a, b) => a.startChar - b.startChar
  );

  // Scroll to specific highlighted range in Monaco Editor
  const scrollToHighlight = (rangeIndex: number) => {
    if (!editorRef.current || sortedRanges.length === 0) return;

    const range = sortedRanges[rangeIndex];
    if (!range) return;

    const startPosition = editorRef.current
      .getModel()!
      .getPositionAt(range.startChar);

    // Scroll to the position
    editorRef.current.revealPositionInCenter(startPosition);

    // Update decorations to highlight current range
    updateHighlightDecorations();
  };

  // Navigation handlers
  const goToNextHighlight = () => {
    if (sortedRanges.length === 0) return;
    const nextIndex = (currentHighlightIndex + 1) % sortedRanges.length;
    setCurrentHighlightIndex(nextIndex);
    scrollToHighlight(nextIndex);
  };

  const goToPreviousHighlight = () => {
    if (sortedRanges.length === 0) return;
    const prevIndex =
      currentHighlightIndex === 0
        ? sortedRanges.length - 1
        : currentHighlightIndex - 1;
    setCurrentHighlightIndex(prevIndex);
    scrollToHighlight(prevIndex);
  };

  // Keyboard navigation
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (
        e.target instanceof HTMLInputElement ||
        e.target instanceof HTMLTextAreaElement
      ) {
        return; // Don't interfere with input fields
      }

      if (e.key === ">" || (e.key === "ArrowDown" && e.ctrlKey)) {
        e.preventDefault();
        goToNextHighlight();
      } else if (e.key === "<" || (e.key === "ArrowUp" && e.ctrlKey)) {
        e.preventDefault();
        goToPreviousHighlight();
      }
    };

    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [currentHighlightIndex, sortedRanges.length]);

  // Scroll first highlighted range into view on initial load
  useEffect(() => {
    if (sortedRanges.length > 0) {
      setCurrentHighlightIndex(0);
      scrollToHighlight(0);
    }
  }, [highlightRanges]);

  // Update decorations when current highlight changes
  useEffect(() => {
    updateHighlightDecorations();
  }, [currentHighlightIndex, characterRanges]);

  // Handle Monaco Editor mount
  const handleEditorDidMount = (editor: editor.IStandaloneCodeEditor) => {
    editorRef.current = editor;

    // Apply initial decorations for highlights
    updateHighlightDecorations();

    // Configure editor options
    editor.updateOptions({
      readOnly: true,
      minimap: { enabled: false },
      scrollBeyondLastLine: false,
      wordWrap: "on",
      lineNumbers: "on",
      folding: false,
      renderWhitespace: "selection",
      fontSize: 12,
      fontFamily: "'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace",
      lineHeight: 18,
      letterSpacing: 0.5,
      fontWeight: "400",
      renderLineHighlight: "none",
      cursorStyle: "line",
      cursorBlinking: "blink",
      smoothScrolling: true,
    });
  };

  // Update highlight decorations in Monaco Editor
  const updateHighlightDecorations = () => {
    if (!editorRef.current) return;

    // Clear all existing decorations first to prevent old highlights from persisting
    if (decorations.length > 0) {
      editorRef.current.deltaDecorations(decorations, []);
      setDecorations([]);
    }

    const newDecorations: editor.IModelDeltaDecoration[] = [];

    characterRanges.forEach((range, index) => {
      const startPosition = editorRef
        .current!.getModel()!
        .getPositionAt(range.startChar);
      const endPosition = editorRef
        .current!.getModel()!
        .getPositionAt(range.endChar);

      const isCurrentHighlight = index === currentHighlightIndex;

      newDecorations.push({
        range: {
          startLineNumber: startPosition.lineNumber,
          startColumn: startPosition.column,
          endLineNumber: endPosition.lineNumber,
          endColumn: endPosition.column,
        },
        options: {
          className: isCurrentHighlight
            ? "current-highlight-decoration"
            : "highlight-decoration",
          isWholeLine: false,
        },
      });
    });

    // Apply new decorations
    const decorationIds = editorRef.current.deltaDecorations(
      [],
      newDecorations
    );
    setDecorations(decorationIds);
  };

  // Detect language for syntax highlighting
  const detectLanguage = (content: string): string => {
    // Check for JSON content
    if (content.trim().startsWith("{") && content.trim().endsWith("}")) {
      try {
        JSON.parse(content);
        return "json";
      } catch {
        // Not valid JSON, continue checking
      }
    }

    // Check for Python code patterns
    if (/^(import|from|def|class|if __name__|print\()/m.test(content)) {
      return "python";
    }

    // Check for JavaScript/TypeScript patterns
    if (/^(import|export|function|const|let|var|console\.log)/m.test(content)) {
      return "javascript";
    }

    // Check for shell/bash patterns
    if (
      /^(#!\/bin\/|cd |ls |mkdir |rm |pip install|npm install)/m.test(content)
    ) {
      return "shell";
    }

    // Check for SQL patterns
    if (/^(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/im.test(content)) {
      return "sql";
    }

    // Default to plain text
    return "text";
  };

  const detectedLanguage = useMemo(
    () => detectLanguage(reconstructedContent),
    [reconstructedContent]
  );

  if (isCollapsed) {
    return (
      <div className="w-4 flex-shrink-0 border-r bg-muted/10 flex items-center justify-center transition-all duration-300">
        <button
          className="p-1 hover:bg-muted/20 rounded"
          onClick={() => setIsCollapsed(false)}
          title="Expand Trace"
        >
          <ChevronRight className="h-4 w-4" />
        </button>
      </div>
    );
  }

  return (
    <div
      className={`${widthClass} flex-shrink-0 border-r bg-muted/10 flex flex-col transition-all duration-300`}
    >
      {/* Header */}
      <div className="flex items-center justify-between h-10 px-2 border-b text-xs font-semibold text-muted-foreground shrink-0">
        <div className="flex items-center gap-2">
          <div className="flex items-center gap-2">
            <button
              className={`px-2 py-1 rounded text-xs font-medium transition-colors ${
                activeTab === "system"
                  ? "bg-primary/10 text-primary"
                  : "hover:bg-muted/20"
              }`}
              onClick={() => setActiveTab("system")}
            >
              System
            </button>
            {showTraceTab && (
              <button
                className={`px-2 py-1 rounded text-xs font-medium transition-colors ${
                  activeTab === "trace"
                    ? "bg-primary/10 text-primary"
                    : "hover:bg-muted/20"
                }`}
                onClick={() => setActiveTab("trace")}
              >
                Trace
              </button>
            )}
          </div>
        </div>
        <div className="flex items-center gap-1">
          <button
            className="p-1 hover:bg-muted/20 rounded"
            onClick={() => setIsCollapsed(true)}
            title="Collapse Trace"
          >
            <ChevronLeft className="h-3 w-3" />
          </button>
        </div>
      </div>

      {/* Content */}
      <div className="flex-1 overflow-hidden" ref={containerRef}>
        {activeTab === "system" ? (
          <div className="flex flex-col h-full p-3 space-y-3 overflow-y-auto">
            {knowledgeGraph ? (
              <>
                {/* System Hero Section */}
                <div className="relative overflow-hidden rounded-lg bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 dark:from-blue-950/20 dark:via-indigo-950/20 dark:to-purple-950/20 p-4 border border-blue-200/50 dark:border-blue-800/50">
                  <div className="relative z-10">
                    {knowledgeGraph.system_name && (
                      <div className="mb-3">
                        <h2 className="text-base font-semibold text-gray-900 dark:text-gray-100 leading-tight">
                          {knowledgeGraph.system_name}
                        </h2>
                      </div>
                    )}
                    {knowledgeGraph.system_summary && (
                      <p className="text-xs text-gray-600 dark:text-gray-300 leading-relaxed">
                        {knowledgeGraph.system_summary}
                      </p>
                    )}
                  </div>
                  {/* Subtle background pattern */}
                  <div className="absolute top-0 right-0 opacity-5">
                    <Cpu className="h-16 w-16" />
                  </div>
                </div>

                {/* Stats Grid */}
                <div className="grid grid-cols-2 gap-2">
                  {/* Entities Card */}
                  <Card className="border border-emerald-200/50 dark:border-emerald-800/50 bg-gradient-to-br from-emerald-50 to-green-50 dark:from-emerald-950/20 dark:to-green-950/20">
                    <CardContent className="p-3">
                      <div className="flex items-center gap-2">
                        <div className="p-1 rounded-md bg-emerald-100 dark:bg-emerald-900/50">
                          <Database className="h-3 w-3 text-emerald-600 dark:text-emerald-400" />
                        </div>
                        <div className="flex-1 min-w-0">
                          <p className="text-xs text-emerald-600 dark:text-emerald-400 font-medium">
                            Entities
                          </p>
                          <p className="text-lg font-bold text-emerald-700 dark:text-emerald-300 leading-none">
                            {knowledgeGraph.entity_count || 0}
                          </p>
                        </div>
                      </div>
                    </CardContent>
                  </Card>

                  {/* Relations Card */}
                  <Card className="border border-blue-200/50 dark:border-blue-800/50 bg-gradient-to-br from-blue-50 to-cyan-50 dark:from-blue-950/20 dark:to-cyan-950/20">
                    <CardContent className="p-3">
                      <div className="flex items-center gap-2">
                        <div className="p-1 rounded-md bg-blue-100 dark:bg-blue-900/50">
                          <GitBranch className="h-3 w-3 text-blue-600 dark:text-blue-400" />
                        </div>
                        <div className="flex-1 min-w-0">
                          <p className="text-xs text-blue-600 dark:text-blue-400 font-medium">
                            Relations
                          </p>
                          <p className="text-lg font-bold text-blue-700 dark:text-blue-300 leading-none">
                            {knowledgeGraph.relation_count || 0}
                          </p>
                        </div>
                      </div>
                    </CardContent>
                  </Card>
                </div>

                {/* Processing Details */}
                <Card className="border border-gray-200/50 dark:border-gray-800/50">
                  <CardContent className="p-3">
                    {/* Processing Information */}
                    {knowledgeGraph.processing_metadata && (
                      <div className="space-y-2">
                        <div className="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
                          <BarChart3 className="h-4 w-4" />
                          Processing Details
                        </div>

                        {knowledgeGraph.processing_metadata.method_name && (
                          <div className="flex items-center justify-between py-1">
                            <div className="flex items-center gap-2">
                              <Cpu className="h-3 w-3 text-gray-500" />
                              <span className="text-xs text-gray-600 dark:text-gray-400">
                                Method
                              </span>
                            </div>
                            <span className="text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded text-gray-700 dark:text-gray-300">
                              {knowledgeGraph.processing_metadata.method_name}
                            </span>
                          </div>
                        )}

                        {knowledgeGraph.processing_metadata.splitter_type && (
                          <div className="flex items-center justify-between py-1">
                            <div className="flex items-center gap-2">
                              <Layers className="h-3 w-3 text-gray-500" />
                              <span className="text-xs text-gray-600 dark:text-gray-400">
                                Splitter
                              </span>
                            </div>
                            <span className="text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded text-gray-700 dark:text-gray-300">
                              {knowledgeGraph.processing_metadata.splitter_type}
                            </span>
                          </div>
                        )}

                        {knowledgeGraph.window_total && (
                          <div className="flex items-center justify-between py-1">
                            <div className="flex items-center gap-2">
                              <Clock className="h-3 w-3 text-gray-500" />
                              <span className="text-xs text-gray-600 dark:text-gray-400">
                                Windows
                              </span>
                            </div>
                            <span className="text-xs bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded text-gray-700 dark:text-gray-300">
                              {knowledgeGraph.window_total}
                            </span>
                          </div>
                        )}
                      </div>
                    )}
                  </CardContent>
                </Card>
              </>
            ) : (
              <div className="flex items-center justify-center h-full text-center">
                <div>
                  <Info className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
                  <h3 className="text-lg font-medium mb-2">
                    System Information
                  </h3>
                  <p className="text-sm text-muted-foreground">
                    No system data available for this view
                  </p>
                </div>
              </div>
            )}
          </div>
        ) : activeTab === "trace" ? (
          <div className="flex flex-col h-full">
            {/* Navigation controls for trace */}
            {sortedRanges.length > 0 && (
              <div className="flex items-center justify-center gap-2 p-2 border-b bg-muted/10">
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-6 w-6 p-0"
                  onClick={goToPreviousHighlight}
                  title="Previous highlight (<)"
                >
                  <ChevronUp className="h-3 w-3" />
                </Button>
                <span className="text-xs text-muted-foreground">
                  {currentHighlightIndex + 1} / {sortedRanges.length}
                </span>
                <Button
                  variant="ghost"
                  size="sm"
                  className="h-6 w-6 p-0"
                  onClick={goToNextHighlight}
                  title="Next highlight (>)"
                >
                  <ChevronDown className="h-3 w-3" />
                </Button>
              </div>
            )}
            <div className="flex-1">
              <Editor
                height="100%"
                defaultLanguage={detectedLanguage}
                value={reconstructedContent}
                onMount={handleEditorDidMount}
                theme="vs-dark"
                options={{
                  readOnly: true,
                  minimap: { enabled: false },
                  scrollBeyondLastLine: false,
                  wordWrap: "on",
                  lineNumbers: "on",
                  folding: false,
                  renderWhitespace: "selection",
                  fontSize: 12,
                  fontFamily:
                    "'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace",
                  padding: { top: 10, bottom: 10 },
                }}
              />
            </div>
          </div>
        ) : null}
      </div>

      {/* Footer with navigation hint */}
      {activeTab === "trace" && sortedRanges.length > 0 && (
        <div className="px-2 py-1 border-t text-xs text-muted-foreground/80 shrink-0">
          <div className="flex items-center justify-center gap-1">
            <span>Press</span>
            <kbd className="px-1 py-0.5 bg-muted/50 rounded text-xs">{"<"}</kbd>
            <kbd className="px-1 py-0.5 bg-muted/50 rounded text-xs">{">"}</kbd>
            <span>to navigate</span>
          </div>
        </div>
      )}
    </div>
  );
};
