"use client"

import { useState, useEffect } from "react"
import {
  parseLineProfilerResults,
  getHeatLevel,
  formatTime,
  type LineProfilerReport,
  type LineProfilerFunction,
} from "@/lib/lineProfilerParser"
import { ChevronDown, ChevronRight, Flame, Snowflake, Clock, Zap } from "lucide-react"
import { cn } from "@/lib/utils"
import { Highlight, themes } from "prism-react-renderer"

// Sanitize line contents to prevent XSS (defense in depth - Prism should escape, but be safe)
const sanitizeCode = (code: string): string =>
  code.replace(/[<>&]/g, c => ({ "<": "&lt;", ">": "&gt;", "&": "&amp;" })[c] || c)

interface LineProfilerViewProps {
  originalProfiler?: string
  optimizedProfiler?: string
  functionName?: string
  originalRuntime?: string
  optimizedRuntime?: string
}

interface ProfilerPanelProps {
  report: LineProfilerReport | null
  variant: "original" | "optimized"
  runtime?: string
  isDarkMode: boolean
}

function ProfilerPanel({ report, variant, runtime, isDarkMode }: ProfilerPanelProps) {
  const [collapsedFunctions, setCollapsedFunctions] = useState<Set<string>>(new Set())

  const toggleFunction = (funcName: string) => {
    setCollapsedFunctions(prev => {
      const next = new Set(prev)
      if (next.has(funcName)) {
        next.delete(funcName)
      } else {
        next.add(funcName)
      }
      return next
    })
  }

  const isOriginal = variant === "original"
  const headerBg = isOriginal
    ? "bg-red-500/10 border-red-500/20"
    : "bg-green-500/10 border-green-500/20"
  const headerText = isOriginal
    ? "text-red-700 dark:text-red-400"
    : "text-green-700 dark:text-green-400"
  const headerIcon = isOriginal ? <Clock className="w-4 h-4" /> : <Zap className="w-4 h-4" />

  if (!report || report.functions.length === 0) {
    return (
      <div className="flex-1 flex flex-col min-w-0">
        <div className={cn("px-4 py-3 border-b flex items-center justify-between", headerBg)}>
          <div className={cn("flex items-center gap-2 font-semibold text-sm", headerText)}>
            {headerIcon}
            {isOriginal ? "Original" : "Optimized"}
          </div>
          {runtime && <span className={cn("text-xs font-mono", headerText)}>{runtime}</span>}
        </div>
        <div className="flex-1 flex items-center justify-center text-muted-foreground text-sm p-8">
          No profiler data available
        </div>
      </div>
    )
  }

  return (
    <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
      {/* Header */}
      <div
        className={cn(
          "px-4 py-2.5 border-b flex items-center justify-between flex-shrink-0",
          headerBg,
        )}
      >
        <div className={cn("flex items-center gap-2 font-semibold text-sm", headerText)}>
          {headerIcon}
          {isOriginal ? "Original" : "Optimized"}
        </div>
        <div className="flex items-center gap-3">
          {runtime && (
            <span className={cn("text-xs font-mono font-medium", headerText)}>{runtime}</span>
          )}
        </div>
      </div>

      {/* Scrollable content */}
      <div className="flex-1 overflow-auto">
        {report.functions.map((func, funcIndex) => (
          <FunctionBlock
            key={`${func.functionName}-${funcIndex}`}
            func={func}
            timerUnit={report.timerUnit}
            isCollapsed={collapsedFunctions.has(func.functionName)}
            onToggle={() => toggleFunction(func.functionName)}
            variant={variant}
            isDarkMode={isDarkMode}
          />
        ))}
      </div>
    </div>
  )
}

interface FunctionBlockProps {
  func: LineProfilerFunction
  timerUnit: string
  isCollapsed: boolean
  onToggle: () => void
  variant: "original" | "optimized"
  isDarkMode: boolean
}

function FunctionBlock({
  func,
  timerUnit,
  isCollapsed,
  onToggle,
  variant,
  isDarkMode,
}: FunctionBlockProps) {
  const isOriginal = variant === "original"
  const accentColor = isOriginal ? "hover:bg-red-500/5" : "hover:bg-green-500/5"

  return (
    <div className="border-b border-border last:border-b-0">
      {/* Function header */}
      <button
        onClick={onToggle}
        className={cn(
          "w-full px-4 py-2.5 flex items-center gap-3 text-left transition-colors",
          "bg-muted/30 hover:bg-muted/50",
          accentColor,
        )}
      >
        <div className="flex items-center gap-2 flex-1 min-w-0">
          {isCollapsed ? (
            <ChevronRight className="h-4 w-4 flex-shrink-0 text-muted-foreground" />
          ) : (
            <ChevronDown className="h-4 w-4 flex-shrink-0 text-muted-foreground" />
          )}
          <code className="font-mono text-sm font-medium truncate text-foreground">
            {func.functionName}
          </code>
        </div>
        {func.totalTime && (
          <span className="text-xs text-muted-foreground font-mono flex-shrink-0">
            {func.totalTime}
          </span>
        )}
      </button>

      {/* Code content - Respects light/dark mode */}
      {!isCollapsed && (
        <div className={cn("overflow-x-auto", isDarkMode ? "bg-[#1e1e1e]" : "bg-[#f5f5f5]")}>
          {/* Column headers */}
          <div
            className={cn(
              "flex text-[10px] font-medium border-b",
              isDarkMode
                ? "bg-[#252526] text-[#858585] border-[#333]"
                : "bg-[#e8e8e8] text-[#666] border-[#d0d0d0]",
            )}
          >
            <div className="w-12 flex-shrink-0 text-right pr-3 py-1 border-r border-inherit">
              Line
            </div>
            <div className="flex-shrink-0 flex border-r border-inherit">
              <div className="w-14 text-right px-2 py-1">Hits</div>
              <div className="w-20 text-right px-2 py-1">Time</div>
              <div className="w-16 text-right px-2 py-1">Per Hit</div>
              <div className="w-14 text-right px-2 py-1">% Time</div>
            </div>
            <div className="flex-1 px-4 py-1">Code</div>
          </div>
          <div className="min-w-fit">
            {func.entries.map((entry, entryIndex) => {
              const heatLevel = getHeatLevel(entry.percentTime)
              const lineNum = entryIndex + 1

              return (
                <div
                  key={entryIndex}
                  className={cn(
                    "flex",
                    isDarkMode ? "border-b border-[#333]" : "border-b border-[#e0e0e0]",
                    "last:border-b-0",
                    heatLevel === "hot-4" && "bg-red-500/25",
                    heatLevel === "hot-3" && "bg-orange-500/20",
                    heatLevel === "hot-2" && "bg-amber-500/15",
                    heatLevel === "hot-1" && "bg-yellow-500/10",
                    heatLevel === "cold" && (isDarkMode ? "hover:bg-white/5" : "hover:bg-black/5"),
                  )}
                >
                  {/* Line number */}
                  <div
                    className={cn(
                      "w-12 flex-shrink-0 text-right pr-3 py-0.5 text-xs font-mono select-none border-r",
                      isDarkMode ? "text-[#858585] border-[#333]" : "text-[#999] border-[#e0e0e0]",
                    )}
                  >
                    {lineNum}
                  </div>

                  {/* Stats columns */}
                  <div
                    className={cn(
                      "flex-shrink-0 flex text-[11px] font-mono border-r",
                      isDarkMode ? "border-[#333]" : "border-[#e0e0e0]",
                    )}
                  >
                    <div
                      className={cn(
                        "w-14 text-right px-2 py-0.5",
                        isDarkMode ? "text-[#858585]" : "text-[#666]",
                      )}
                    >
                      {entry.hits || ""}
                    </div>
                    <div
                      className={cn(
                        "w-20 text-right px-2 py-0.5",
                        isDarkMode ? "text-[#d4d4d4]" : "text-[#333]",
                      )}
                    >
                      {entry.time ? formatTime(entry.time, timerUnit) : ""}
                    </div>
                    <div
                      className={cn(
                        "w-16 text-right px-2 py-0.5",
                        isDarkMode ? "text-[#858585]" : "text-[#666]",
                      )}
                    >
                      {entry.perHit ? formatTime(entry.perHit, timerUnit) : ""}
                    </div>
                    <div
                      className={cn(
                        "w-14 text-right px-2 py-0.5 font-medium",
                        heatLevel === "hot-4" && "text-red-600 dark:text-red-400",
                        heatLevel === "hot-3" && "text-orange-600 dark:text-orange-400",
                        heatLevel === "hot-2" && "text-amber-600 dark:text-amber-400",
                        heatLevel === "hot-1" && "text-yellow-600 dark:text-yellow-500",
                        heatLevel === "cold" && (isDarkMode ? "text-[#858585]" : "text-[#666]"),
                      )}
                    >
                      {entry.percentTime > 0 ? `${entry.percentTime.toFixed(1)}%` : ""}
                    </div>
                  </div>

                  {/* Code with syntax highlighting */}
                  <div className="flex-1 min-w-0 overflow-hidden">
                    <Highlight
                      theme={isDarkMode ? themes.vsDark : themes.vsLight}
                      code={sanitizeCode(entry.lineContents)}
                      language="python"
                    >
                      {({ tokens, getTokenProps }) => (
                        <code
                          className="block py-0.5 px-4 text-[13px] leading-[1.5] font-mono"
                          style={{
                            background: "transparent",
                            whiteSpace: "pre",
                            tabSize: 4,
                          }}
                        >
                          {tokens.map((line, i) => (
                            <span key={i}>
                              {line.map((token, key) => (
                                <span key={key} {...getTokenProps({ token })} />
                              ))}
                            </span>
                          ))}
                        </code>
                      )}
                    </Highlight>
                  </div>
                </div>
              )
            })}
          </div>
        </div>
      )}
    </div>
  )
}

export function LineProfilerView({
  originalProfiler,
  optimizedProfiler,
  functionName,
  originalRuntime,
  optimizedRuntime,
}: LineProfilerViewProps) {
  const [isDarkMode, setIsDarkMode] = useState(false)
  const [mounted, setMounted] = useState(false)

  useEffect(() => {
    setMounted(true)

    const updateTheme = () => {
      const isDark = document.documentElement.classList.contains("dark")
      setIsDarkMode(isDark)
    }

    updateTheme()

    // Use matchMedia for system preference changes (better performance than MutationObserver)
    const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)")
    darkModeQuery.addEventListener("change", updateTheme)

    // Also observe class changes for manual theme toggles (e.g., next-themes)
    const observer = new MutationObserver(() => updateTheme())
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"], // Only observe class changes
    })

    return () => {
      darkModeQuery.removeEventListener("change", updateTheme)
      observer.disconnect()
    }
  }, [])

  const originalReport = originalProfiler ? parseLineProfilerResults(originalProfiler) : null
  const optimizedReport = optimizedProfiler ? parseLineProfilerResults(optimizedProfiler) : null

  const hasOriginal = originalReport && originalReport.functions.length > 0
  const hasOptimized = optimizedReport && optimizedReport.functions.length > 0

  if (!mounted) {
    return null
  }

  if (!hasOriginal && !hasOptimized) {
    return (
      <div className="flex items-center justify-center h-full text-muted-foreground p-8">
        <div className="text-center">
          <Flame className="w-12 h-12 mx-auto mb-4 opacity-20" />
          <p className="text-lg font-medium">No line profiler data available</p>
          <p className="text-sm mt-1">
            Run an optimization with line profiling enabled to see results here.
          </p>
        </div>
      </div>
    )
  }

  return (
    <div className="flex flex-col h-full bg-background border border-border rounded-lg overflow-hidden shadow-sm">
      {/* Top header */}
      <div className="flex items-center justify-between px-4 py-2.5 bg-gradient-to-r from-muted/50 to-muted/30 border-b border-border flex-shrink-0">
        <div className="flex items-center gap-4">
          {functionName && (
            <div className="flex items-center gap-2">
              <Flame className="w-5 h-5 text-orange-500" />
              <span className="font-semibold text-sm text-foreground">
                Line Profile: <code className="font-mono text-primary">{functionName}()</code>
              </span>
            </div>
          )}
          {originalRuntime && optimizedRuntime && (
            <div className="flex items-center gap-2 text-sm text-muted-foreground pl-4 border-l border-border">
              <span className="text-red-600 dark:text-red-400 font-mono text-xs">
                {originalRuntime}
              </span>
              <span className="text-xs">→</span>
              <span className="text-green-600 dark:text-green-400 font-mono text-xs">
                {optimizedRuntime}
              </span>
            </div>
          )}
        </div>

        {/* Heat legend */}
        <div className="flex items-center gap-3 text-xs">
          <span className="text-muted-foreground font-medium">Heat:</span>
          <div className="flex items-center gap-1">
            <Snowflake className="h-3 w-3 text-green-500" />
            <span className="text-muted-foreground">&lt;5%</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-2.5 h-2.5 rounded-sm bg-yellow-500" />
            <span className="text-muted-foreground">5-15%</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-2.5 h-2.5 rounded-sm bg-amber-500" />
            <span className="text-muted-foreground">15-30%</span>
          </div>
          <div className="flex items-center gap-1">
            <div className="w-2.5 h-2.5 rounded-sm bg-orange-500" />
            <span className="text-muted-foreground">30-50%</span>
          </div>
          <div className="flex items-center gap-1">
            <Flame className="h-3 w-3 text-red-500" />
            <span className="text-muted-foreground">&gt;50%</span>
          </div>
        </div>
      </div>

      {/* Side-by-side panels */}
      <div className="flex flex-1 overflow-hidden">
        <ProfilerPanel
          report={originalReport}
          variant="original"
          runtime={originalRuntime}
          isDarkMode={isDarkMode}
        />

        <div className="w-px bg-border flex-shrink-0" />

        <ProfilerPanel
          report={optimizedReport}
          variant="optimized"
          runtime={optimizedRuntime}
          isDarkMode={isDarkMode}
        />
      </div>
    </div>
  )
}

export default LineProfilerView
