'use client';

import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  SplitSquareHorizontal, MessageSquare, Lightbulb, BarChart3,
  ChevronDown, ChevronUp, ChevronRight, Zap, ArrowRight,
  FileCode2, Folder, FolderOpen, CheckCircle2
} from 'lucide-react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { Play } from 'lucide-react';
import type { Project } from '../data/projectsData';
import { applyMarker } from '@/lib/ai-marker';

interface FileEntry {
  id: string;
  sourceFile: string;
  targetFile: string;
  sourceCode: string;
  targetCode: string;
  sourceLangId: string;
  targetLangId: string;
  confidence: number;
  linesSource: number;
  linesTarget: number;
  confidenceScores: { block: string; score: number; lines: string }[];
  businessRules: { id: string; description: string; source: string; target: string; confidence: number }[];
  explanations: string[];
  reasonings: string[];
}

interface TreeNode {
  name: string;
  path: string;
  isDir: boolean;
  children?: TreeNode[];
  fileId?: string;
}

function buildTree(files: FileEntry[], side: 'source' | 'target'): TreeNode[] {
  const root: TreeNode[] = [];
  for (const f of files) {
    const path = side === 'source' ? f.sourceFile : f.targetFile;
    const parts = path.split('/');
    let current = root;
    for (let i = 0; i < parts.length; i++) {
      const name = parts[i];
      const isLast = i === parts.length - 1;
      const fullPath = parts.slice(0, i + 1).join('/');
      let existing = current.find(n => n.name === name);
      if (!existing) {
        existing = { name, path: fullPath, isDir: !isLast, children: isLast ? undefined : [], fileId: isLast ? f.id : undefined };
        current.push(existing);
      }
      if (!isLast) current = existing.children!;
    }
  }
  return root;
}

function TreeItem({ node, selectedId, onSelect, depth = 0 }: { node: TreeNode; selectedId: string; onSelect: (id: string) => void; depth?: number }) {
  const [open, setOpen] = useState(true);
  const isSelected = node.fileId === selectedId;

  if (node.isDir) {
    return (
      <div>
        <button
          onClick={() => setOpen(!open)}
          className="w-full flex items-center gap-1.5 py-1 px-1 text-[11px] text-muted hover:text-foreground transition-colors cursor-pointer"
          style={{ paddingLeft: `${depth * 12 + 4}px` }}
        >
          {open ? <FolderOpen className="w-3.5 h-3.5 text-accent-light shrink-0" /> : <Folder className="w-3.5 h-3.5 text-accent-light/60 shrink-0" />}
          <span className="truncate font-medium">{node.name}</span>
          <ChevronRight className={`w-3 h-3 ml-auto text-muted/50 transition-transform ${open ? 'rotate-90' : ''}`} />
        </button>
        <AnimatePresence>
          {open && node.children && (
            <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} className="overflow-hidden">
              {node.children.map(child => (
                <TreeItem key={child.path} node={child} selectedId={selectedId} onSelect={onSelect} depth={depth + 1} />
              ))}
            </motion.div>
          )}
        </AnimatePresence>
      </div>
    );
  }

  return (
    <button
      onClick={() => node.fileId && onSelect(node.fileId)}
      className={`w-full flex items-center gap-1.5 py-1.5 px-1 text-[11px] transition-all cursor-pointer rounded-md ${
        isSelected ? 'bg-accent/15 text-accent-light font-semibold' : 'text-muted hover:text-foreground hover:bg-white/5'
      }`}
      style={{ paddingLeft: `${depth * 12 + 4}px` }}
    >
      <FileCode2 className={`w-3.5 h-3.5 shrink-0 ${isSelected ? 'text-accent-light' : 'text-muted/60'}`} />
      <span className="truncate">{node.name}</span>
    </button>
  );
}

export default function CodeComparison({ onNavigate, projectId, maxReachedStep = 0, project: propProject }: { onNavigate: (s: string) => void; projectId?: string; maxReachedStep?: number; project?: Project | null }) {
  const [showExplanation, setShowExplanation] = useState(false);
  const [showReasoning, setShowReasoning] = useState(false);
  const [showHeatmap, setShowHeatmap] = useState(true);
  const [selectedRule, setSelectedRule] = useState<string | null>(null);
  const [selectedFileId, setSelectedFileId] = useState<string>('');

  const project = propProject;
  const projConfig = (project?.config ?? {}) as Record<string, unknown>;
  const analysisResults = (projConfig.analysisResults ?? {}) as Record<string, any>;
  const translation = analysisResults?.translation;

  const isDraft = project ? project.status === 'draft' && maxReachedStep < 4 : false;

  // Support multi-file: translation.files array or single-file fallback
  const files: FileEntry[] = (() => {
    if (!translation) return [];
    if (Array.isArray(translation.files) && translation.files.length > 0) return translation.files;
    // fallback: single file from legacy shape
    if (translation.sourceCode) {
      return [{
        id: 'f0',
        sourceFile: translation.sourceFile || 'source',
        targetFile: translation.targetFile || 'target',
        sourceCode: translation.sourceCode,
        targetCode: translation.targetCode,
        sourceLangId: translation.sourceLangId || project?.sourceLanguage || '',
        targetLangId: translation.targetLangId || project?.targetLanguage || '',
        confidence: 0,
        linesSource: (translation.sourceCode as string).split('\n').length,
        linesTarget: (translation.targetCode as string).split('\n').length,
        confidenceScores: translation.confidenceScores || [],
        businessRules: translation.businessRules || [],
        explanations: translation.explanations || [],
        reasonings: translation.reasonings || [],
      }];
    }
    return [];
  })();

  const hasTranslation = files.length > 0;

  // Auto-open both panels when real content is available
  useEffect(() => {
    const activeFile = files.find(f => f.id === (selectedFileId || files[0]?.id));
    if ((activeFile?.explanations.length ?? 0) > 0) setShowExplanation(true);
    if ((activeFile?.reasonings.length ?? 0) > 0) setShowReasoning(true);
  }, [files, selectedFileId]);

  // Auto-select first file
  const activeId = selectedFileId || (files[0]?.id ?? '');
  const activeFile = files.find(f => f.id === activeId) || files[0];
  const targetPreview = activeFile
    ? applyMarker(activeFile.targetFile, activeFile.targetCode, {
      conversionId: project?.id ?? 'preview',
      sourceLanguage: project?.sourceLanguage ?? activeFile.sourceLangId ?? 'unknown',
      targetLanguage: project?.targetLanguage ?? activeFile.targetLangId ?? 'unknown',
      timestamp: new Date().toISOString(),
      platformVersion: process.env.NEXT_PUBLIC_APP_VERSION ?? '1.0.0',
    })
    : null;

  const sourceTree = buildTree(files, 'source');
  const targetTree = buildTree(files, 'target');

  // Stats
  const totalSourceLines = files.reduce((s, f) => s + f.linesSource, 0);
  const totalTargetLines = files.reduce((s, f) => s + f.linesTarget, 0);
  const avgConfidence = files.length > 0 ? Math.round(files.reduce((s, f) => s + f.confidence, 0) / files.length * 10) / 10 : 0;

  if (isDraft) {
    return (
      <div className="space-y-5">
        <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} className="flex items-center justify-between">
          <div>
            <h2 className="text-2xl font-bold text-foreground flex items-center gap-2">
              <SplitSquareHorizontal className="w-6 h-6 text-accent-light" /> Code Comparison
            </h2>
            <p className="text-sm text-muted mt-1">Source and target code comparison</p>
          </div>
        </motion.div>
        <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="glass-light rounded-lg p-12 text-center">
          <div className="w-20 h-20 rounded-full gradient-accent flex items-center justify-center mx-auto mb-6">
            <Play className="w-10 h-10 text-white" />
          </div>
          <h3 className="text-xl font-semibold text-foreground mb-3">Code Not Generated Yet</h3>
          <p className="text-sm text-muted mb-8 max-w-md mx-auto">
            Connect a repository and run the migration to see source and target code comparison, confidence heatmaps, and business rule extraction.
          </p>
          <button onClick={() => onNavigate('repository')} className="px-8 py-3 rounded-lg gradient-accent text-white text-sm font-semibold hover:opacity-90 transition-opacity flex items-center justify-center gap-2 cursor-pointer mx-auto glow-accent">
            <Play className="w-5 h-5" /> Connect Repository
          </button>
        </motion.div>
      </div>
    );
  }

  if (!hasTranslation) {
    return (
      <div className="space-y-5">
        <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }}>
          <h2 className="text-2xl font-bold text-foreground flex items-center gap-2">
            <SplitSquareHorizontal className="w-6 h-6 text-accent-light" /> Code Comparison
          </h2>
          <p className="text-sm text-muted mt-1">Source and target code comparison</p>
        </motion.div>
        <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="glass-light rounded-lg p-12 text-center">
          <SplitSquareHorizontal className="w-12 h-12 text-muted/40 mx-auto mb-4" />
          <h3 className="text-lg font-semibold text-foreground mb-2">No Translation Data Yet</h3>
          <p className="text-sm text-muted max-w-md mx-auto">Run the migration pipeline to generate code comparison results.</p>
        </motion.div>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Header */}
      <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} className="flex items-center justify-between">
        <div>
          <h2 className="text-2xl font-bold text-foreground flex items-center gap-2">
            <SplitSquareHorizontal className="w-6 h-6 text-accent-light" /> Code Comparison
          </h2>
          <p className="text-sm text-muted mt-1">{files.length} file{files.length !== 1 ? 's' : ''} translated &middot; {totalSourceLines.toLocaleString()} → {totalTargetLines.toLocaleString()} lines &middot; avg {avgConfidence}% confidence</p>
        </div>
        <div className="flex gap-2">
          <button
            onClick={() => setShowHeatmap(!showHeatmap)}
            className={`px-3 py-1.5 rounded-lg text-xs font-medium flex items-center gap-1.5 transition-all cursor-pointer ${
              showHeatmap ? 'bg-accent/15 text-accent-light border border-accent/30' : 'glass-light text-muted hover:text-foreground'
            }`}
          >
            <BarChart3 className="w-3.5 h-3.5" /> Confidence
          </button>
          <button
            onClick={() => onNavigate('verification')}
            className="px-4 py-1.5 rounded-lg gradient-accent text-white text-xs font-semibold hover:opacity-90 transition-opacity cursor-pointer flex items-center gap-1.5"
          >
            Verification & QA <ArrowRight className="w-3.5 h-3.5" />
          </button>
        </div>
      </motion.div>

      {/* Main layout: file tree + code panels */}
      <div className="flex gap-3" style={{ minHeight: '520px' }}>
        {/* File Tree Sidebar */}
        <motion.div initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} className="glass rounded-xl w-56 shrink-0 overflow-hidden flex flex-col">
          <div className="px-3 py-2.5 border-b border-border">
            <p className="text-[10px] text-muted uppercase tracking-wider font-semibold">Source Files</p>
          </div>
          <div className="flex-1 overflow-y-auto p-1.5 space-y-0.5">
            {sourceTree.map(node => (
              <TreeItem key={node.path} node={node} selectedId={activeId} onSelect={setSelectedFileId} />
            ))}
          </div>
          <div className="px-3 py-2 border-t border-border">
            <div className="flex items-center gap-1.5 text-[10px] text-muted">
              <CheckCircle2 className="w-3 h-3 text-success" />
              <span>{files.length} / {files.length} translated</span>
            </div>
          </div>
        </motion.div>

        {/* Code Panels */}
        {activeFile && (
          <div className="flex-1 grid grid-cols-2 gap-3 min-w-0">
            <motion.div key={`src-${activeFile.id}`} initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="glass rounded-xl overflow-hidden flex flex-col">
              <div className="px-4 py-2 border-b border-border flex items-center gap-2 shrink-0">
                <div className="w-2.5 h-2.5 rounded-full bg-red-500/60" />
                <div className="w-2.5 h-2.5 rounded-full bg-amber-500/60" />
                <div className="w-2.5 h-2.5 rounded-full bg-green-500/60" />
                <span className="text-[11px] text-muted ml-1.5 font-mono truncate">{activeFile.sourceFile}</span>
                <span className="ml-auto text-[10px] px-2 py-0.5 rounded-full bg-accent/15 text-accent-light font-medium shrink-0">{(activeFile.sourceLangId || '—').toUpperCase()}</span>
              </div>
              <div className="flex-1 overflow-auto">
                <SyntaxHighlighter
                  language={(activeFile.sourceLangId || 'text').toLowerCase()}
                  style={vscDarkPlus}
                  showLineNumbers
                  customStyle={{ margin: 0, padding: '12px', background: 'transparent', fontSize: '11px', minHeight: '100%' }}
                  lineNumberStyle={{ color: '#4a4a6a', fontSize: '10px', minWidth: '2.5em' }}
                >
                  {activeFile.sourceCode}
                </SyntaxHighlighter>
              </div>
              <div className="px-3 py-1.5 border-t border-border text-[10px] text-muted flex justify-between">
                <span>{activeFile.linesSource} lines</span>
                <span className="font-mono">{activeFile.sourceLangId}</span>
              </div>
            </motion.div>

            <motion.div key={`tgt-${activeFile.id}`} initial={{ opacity: 0 }} animate={{ opacity: 1 }} className="glass rounded-xl overflow-hidden flex flex-col">
              <div className="px-4 py-2 border-b border-border flex items-center gap-2 shrink-0">
                <div className="w-2.5 h-2.5 rounded-full bg-red-500/60" />
                <div className="w-2.5 h-2.5 rounded-full bg-amber-500/60" />
                <div className="w-2.5 h-2.5 rounded-full bg-green-500/60" />
                <span className="text-[11px] text-muted ml-1.5 font-mono truncate">{activeFile.targetFile}</span>
                <span className="ml-auto text-[10px] px-2 py-0.5 rounded-full bg-orange-500/15 text-orange-400 font-medium shrink-0">{activeFile.targetLangId ? activeFile.targetLangId.charAt(0).toUpperCase() + activeFile.targetLangId.slice(1) : '—'}</span>
              </div>
              <div className="flex-1 overflow-auto">
                <SyntaxHighlighter
                  language={activeFile.targetLangId || 'text'}
                  style={vscDarkPlus}
                  showLineNumbers
                  customStyle={{ margin: 0, padding: '12px', background: 'transparent', fontSize: '11px', minHeight: '100%' }}
                  lineNumberStyle={{ color: '#4a4a6a', fontSize: '10px', minWidth: '2.5em' }}
                >
                  {targetPreview?.marked ?? activeFile.targetCode}
                </SyntaxHighlighter>
              </div>
              {targetPreview?.usedSidecar && targetPreview.sidecarPath && (
                <div className="px-3 pt-2 text-[10px] text-amber-300">
                  Sidecar marker file: <span className="font-mono">{targetPreview.sidecarPath}</span>
                </div>
              )}
              <div className="px-3 py-1.5 border-t border-border text-[10px] text-muted flex justify-between">
                <span>{activeFile.linesTarget} lines</span>
                <span className={`font-bold ${activeFile.confidence >= 95 ? 'text-success' : activeFile.confidence >= 90 ? 'text-warning' : 'text-danger'}`}>{activeFile.confidence}% confidence</span>
              </div>
            </motion.div>
          </div>
        )}
      </div>

      {/* Confidence Heatmap for active file */}
      {showHeatmap && activeFile && activeFile.confidenceScores.length > 0 && (
        <motion.div initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} className="glass rounded-xl p-4">
          <h3 className="text-sm font-semibold text-foreground mb-3 flex items-center gap-2">
            <BarChart3 className="w-4 h-4 text-accent-light" /> AI Confidence Heatmap — {activeFile.sourceFile.split('/').pop()}
          </h3>
          <div className="grid grid-cols-4 gap-2">
            {activeFile.confidenceScores.map((cs, csIdx) => (
              <div
                key={`${activeFile.id}-cs-${csIdx}-${cs.block}`}
                className="glass-light rounded-lg p-3 hover:border-accent/30 transition-all cursor-pointer"
                style={{ borderLeft: `3px solid ${cs.score >= 96 ? '#22c55e' : cs.score >= 92 ? '#f59e0b' : '#ef4444'}` }}
              >
                <div className="flex items-center justify-between mb-1">
                  <span className={`text-xs font-bold ${cs.score >= 96 ? 'text-success' : cs.score >= 92 ? 'text-warning' : 'text-danger'}`}>{cs.score}%</span>
                  <span className="text-[10px] text-muted font-mono">L{cs.lines}</span>
                </div>
                <p className="text-[11px] text-muted leading-snug">{cs.block}</p>
              </div>
            ))}
          </div>
        </motion.div>
      )}

      {/* Explanations & Reasoning for active file */}
      {activeFile && (
        <div className="grid grid-cols-2 gap-4">
          <div className="glass rounded-xl p-4">
            <button onClick={() => setShowExplanation(!showExplanation)} className="w-full flex items-center gap-2 text-sm font-semibold text-foreground cursor-pointer">
              <Lightbulb className="w-4 h-4 text-amber-400" />
              Explain this Transformation
              {showExplanation ? <ChevronUp className="w-4 h-4 ml-auto text-muted" /> : <ChevronDown className="w-4 h-4 ml-auto text-muted" />}
            </button>
            <AnimatePresence>
              {showExplanation && (
                <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} className="overflow-hidden">
                  <div className="mt-3 space-y-2 text-xs text-muted leading-relaxed">
                    {activeFile.explanations.length > 0 ? activeFile.explanations.map((e, i) => <p key={i}>{e}</p>) : <p>Transformation explanations will appear after the engine completes the migration.</p>}
                  </div>
                </motion.div>
              )}
            </AnimatePresence>
          </div>

          <div className="glass rounded-xl p-4">
            <button onClick={() => setShowReasoning(!showReasoning)} className="w-full flex items-center gap-2 text-sm font-semibold text-foreground cursor-pointer">
              <MessageSquare className="w-4 h-4 text-purple-400" />
              Why this Code?
              {showReasoning ? <ChevronUp className="w-4 h-4 ml-auto text-muted" /> : <ChevronDown className="w-4 h-4 ml-auto text-muted" />}
            </button>
            <AnimatePresence>
              {showReasoning && (
                <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} className="overflow-hidden">
                  <div className="mt-3 space-y-2 text-xs text-muted leading-relaxed">
                    {activeFile.reasonings.length > 0 ? activeFile.reasonings.map((r, i) => <p key={i}>{r}</p>) : <p>Design reasoning will appear after the engine completes the migration.</p>}
                  </div>
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        </div>
      )}

      {/* Business Rules for active file */}
      {activeFile && activeFile.businessRules.length > 0 && (
        <div className="glass rounded-xl p-4">
          <h3 className="text-sm font-semibold text-foreground mb-3 flex items-center gap-2">
            <Zap className="w-4 h-4 text-accent-light" /> Business Rule Extraction — {activeFile.sourceFile.split('/').pop()}
          </h3>
          <div className="space-y-2">
            {activeFile.businessRules.map((rule) => (
              <div
                key={rule.id}
                onClick={() => setSelectedRule(selectedRule === rule.id ? null : rule.id)}
                className={`glass-light rounded-lg p-3 cursor-pointer transition-all ${selectedRule === rule.id ? 'border-accent/40' : 'hover:border-accent/20'}`}
              >
                <div className="flex items-center gap-3">
                  <span className="text-[10px] font-bold text-accent-light bg-accent/15 px-2 py-0.5 rounded">{rule.id}</span>
                  <span className="text-xs text-foreground flex-1">{rule.description}</span>
                  <span className={`text-xs font-bold ${rule.confidence >= 95 ? 'text-success' : 'text-warning'}`}>{rule.confidence}%</span>
                </div>
                <AnimatePresence>
                  {selectedRule === rule.id && (
                    <motion.div initial={{ height: 0, opacity: 0 }} animate={{ height: 'auto', opacity: 1 }} exit={{ height: 0, opacity: 0 }} className="overflow-hidden">
                      <div className="mt-2 pt-2 border-t border-border grid grid-cols-2 gap-2 text-[11px]">
                        <div><span className="text-muted">Source:</span><span className="text-accent-light ml-1 font-mono">{rule.source}</span></div>
                        <div><span className="text-muted">Target:</span><span className="text-orange-400 ml-1 font-mono">{rule.target}</span></div>
                      </div>
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}
