"use client"

import { useState, useEffect, useMemo, memo } from "react"
import {
  FileText,
  Code,
  GitCompare,
  Columns2,
} from "lucide-react"
import { CodeHighlighter, CODE_STYLE } from "./code-highlighter"
import { parseAllCodeBlocks, findMatchingFile } from "./timeline-helpers"
import { DiffView, SideBySideDiffView } from "./diff-views"
import type { TimelineSectionContent } from "./timeline-types"

interface CandidateContentProps {
  content: Extract<TimelineSectionContent, { type: "candidate" | "refinement" }>
  isActive: boolean
}

export const CandidateContent = memo(function CandidateContent({
  content,
  isActive,
}: CandidateContentProps) {
  const [viewMode, setViewMode] = useState<"code" | "diff" | "side-by-side">("diff")
  const [selectedFileIndex, setSelectedFileIndex] = useState(0)
  const [unifiedDiff, setUnifiedDiff] = useState<string | null>(null)
  const [diffLoading, setDiffLoading] = useState(false)

  const originalCode =
    content.type === "refinement" ? content.parentCode : content.originalCode

  const candidateFiles = useMemo(() => parseAllCodeBlocks(content.code), [content.code])
  const originalFiles = useMemo(
    () => (originalCode ? parseAllCodeBlocks(originalCode) : []),
    [originalCode]
  )

  const selectedCandidateFile = useMemo(
    () => candidateFiles[selectedFileIndex] || candidateFiles[0],
    [candidateFiles, selectedFileIndex]
  )

  const matchingOriginalFile = useMemo(() => {
    if (!selectedCandidateFile || originalFiles.length === 0) return null
    return findMatchingFile(originalFiles, selectedCandidateFile.path)
  }, [selectedCandidateFile, originalFiles])

  useEffect(() => {
    setUnifiedDiff(null)
    setDiffLoading(false)

    if (viewMode !== "diff" || !matchingOriginalFile || !selectedCandidateFile) {
      return
    }

    setDiffLoading(true)
    let cancelled = false

    import("diff")
      .then(({ createTwoFilesPatch }) => {
        if (cancelled) return

        const filename =
          selectedCandidateFile.filename ||
          matchingOriginalFile.filename ||
          "code.py"

        const diff = createTwoFilesPatch(
          `a/${filename}`,
          `b/${filename}`,
          matchingOriginalFile.code,
          selectedCandidateFile.code,
          "",
          "",
          { context: 3 }
        )

        const lines = diff.split("\n")
        const hunkStartIndex = lines.findIndex(line => line.startsWith("@@"))
        const processedDiff = hunkStartIndex > 0
          ? lines.slice(hunkStartIndex).join("\n")
          : diff

        setUnifiedDiff(processedDiff)
        setDiffLoading(false)
      })
      .catch(error => {
        if (cancelled) return
        console.error("Failed to load diff library:", error)
        setDiffLoading(false)
      })

    return () => { cancelled = true }
  }, [viewMode, matchingOriginalFile, selectedCandidateFile])

  const hasDiff = matchingOriginalFile !== null
  const hasMultipleFiles = candidateFiles.length > 1

  const codeContainerStyle = useMemo(
    () => ({ maxHeight: isActive ? "80vh" : "200px" }),
    [isActive]
  )

  return (
    <div className="space-y-3">
      <div className="flex items-center gap-2 flex-wrap">
        {content.rank != null && (
          <span className="text-xs px-1.5 py-0.5 bg-zinc-100 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300 rounded">
            #{content.rank}
          </span>
        )}
        {content.isBest && (
          <span className="text-xs px-1.5 py-0.5 bg-zinc-200 dark:bg-zinc-600 text-zinc-700 dark:text-zinc-200 rounded font-medium">
            Best
          </span>
        )}
      </div>

      {content.explanation && (
        <p className="text-sm text-zinc-600 dark:text-zinc-400 leading-relaxed">
          {content.explanation}
        </p>
      )}

      <div className="flex items-center gap-2 flex-wrap">
        {hasDiff && (
          <div className="flex items-center gap-1">
            <button
              onClick={() => setViewMode("code")}
              className={`px-3 py-1.5 text-xs rounded-md flex items-center gap-1.5 transition-colors ${
                viewMode === "code"
                  ? "bg-zinc-800 text-white"
                  : "bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700"
              }`}
            >
              <Code className="h-3.5 w-3.5" />
              Code
            </button>
            <button
              onClick={() => setViewMode("diff")}
              className={`px-3 py-1.5 text-xs rounded-md flex items-center gap-1.5 transition-colors ${
                viewMode === "diff"
                  ? "bg-zinc-800 text-white"
                  : "bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700"
              }`}
            >
              <GitCompare className="h-3.5 w-3.5" />
              Diff
            </button>
            <button
              onClick={() => setViewMode("side-by-side")}
              className={`px-3 py-1.5 text-xs rounded-md flex items-center gap-1.5 transition-colors ${
                viewMode === "side-by-side"
                  ? "bg-zinc-800 text-white"
                  : "bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-zinc-200 dark:hover:bg-zinc-700"
              }`}
            >
              <Columns2 className="h-3.5 w-3.5" />
              Split
            </button>
          </div>
        )}

        {hasMultipleFiles && (
          <select
            value={selectedFileIndex}
            onChange={(e) => setSelectedFileIndex(Number(e.target.value))}
            className="px-2 py-1.5 text-xs rounded-md bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-300 border border-zinc-200 dark:border-zinc-700"
          >
            {candidateFiles.map((file, index) => (
              <option key={index} value={index}>
                {file.filename || file.path || `File ${index + 1}`}
              </option>
            ))}
          </select>
        )}
      </div>

      {viewMode === "code" ? (
        selectedCandidateFile ? (
          <div className="rounded-md border border-zinc-200 dark:border-zinc-700 overflow-hidden">
            <div className="px-3 py-2 bg-zinc-100 dark:bg-zinc-800 flex items-center justify-between">
              <div className="flex items-center gap-2">
                <FileText className="h-3.5 w-3.5 text-zinc-400" />
                <span className="text-sm font-mono font-medium text-zinc-700 dark:text-zinc-300">
                  {selectedCandidateFile.filename || "Code"}
                </span>
                {selectedCandidateFile.path && selectedCandidateFile.path !== selectedCandidateFile.filename && (
                  <span className="text-xs text-zinc-500 dark:text-zinc-400">
                    ({selectedCandidateFile.path})
                  </span>
                )}
              </div>
              <span className="text-xs text-zinc-500">
                {selectedCandidateFile.lineCount} lines
              </span>
            </div>
            <div
              className="overflow-y-auto"
              style={codeContainerStyle}
            >
              <CodeHighlighter language={selectedCandidateFile.language} code={selectedCandidateFile.code} customStyle={CODE_STYLE} />
            </div>
          </div>
        ) : (
          <div className="text-sm text-zinc-500 dark:text-zinc-400 italic p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-md">
            No code available
          </div>
        )
      ) : viewMode === "side-by-side" ? (
        matchingOriginalFile && selectedCandidateFile ? (
          <div
            className="rounded-md border border-zinc-200 dark:border-zinc-700 overflow-hidden overflow-y-auto"
            style={codeContainerStyle}
          >
            <SideBySideDiffView
              originalCode={matchingOriginalFile.code}
              candidateCode={selectedCandidateFile.code}
              language={selectedCandidateFile.language}
            />
          </div>
        ) : (
          <div className="text-sm text-zinc-500 dark:text-zinc-400 italic p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-md">
            No original code available for comparison
          </div>
        )
      ) : diffLoading ? (
        <div className="rounded-md border border-zinc-200 dark:border-zinc-700 overflow-hidden">
          <div className="p-4 bg-zinc-900 animate-pulse">
            <div className="h-4 bg-zinc-700 rounded w-3/4 mb-2" />
            <div className="h-4 bg-zinc-700 rounded w-1/2 mb-2" />
            <div className="h-4 bg-zinc-700 rounded w-2/3" />
          </div>
        </div>
      ) : unifiedDiff ? (
        <div
          className="rounded-md border border-zinc-200 dark:border-zinc-700 overflow-hidden overflow-y-auto"
          style={codeContainerStyle}
        >
          <DiffView diff={unifiedDiff} />
        </div>
      ) : (
        <div className="text-sm text-zinc-500 dark:text-zinc-400 italic p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-md">
          No original code available for comparison
        </div>
      )}
    </div>
  )
})
