'use client';

import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import {
  Target, Layers, GitBranch, AlertCircle, CheckCircle2,
  Save, ArrowRight, Shield, Sparkles, SlidersHorizontal, Circle
} from 'lucide-react';
import type { Project } from '../data/projectsData';
import { api } from '../lib/api';
import { ARCH_PATTERNS } from '../lib/platform-run';
import { getEnabledPluginSet, isPluginEnabled } from '../lib/pipeline-plugins';

const ARCH_LABEL: Record<string, string> = Object.fromEntries(ARCH_PATTERNS.map((p) => [p.value, p.label]));

interface Props {
  projectId: string;
  onNavigate?: (section: string, projectId?: string) => void;
  project?: Project | null;
  onProjectUpdate?: () => void;
}

const QUALITY_LABEL: Record<number, string> = {
  0: 'Off — no gate',
  1: 'Compile-clean (Q1 ≥ 70)',
  2: 'Idiomatic (Q2 ≥ 85)',
  3: 'Production (Q3 ≥ 92)',
};

type Field = { label: string; value: string };
type Phase = { title: string; desc: string; active: boolean };

const str = (v: unknown) => (v ? String(v) : '');

function deriveScope(project: Project): Field[] {
  const c = (project.config ?? {}) as Record<string, unknown>;
  const src = str(project.sourceLanguage);
  const tgt = str(project.targetLanguage);
  const sv = str(c.sourceVersion);
  const tv = str(c.targetVersion);
  return ([
    { label: 'Project', value: project.name },
    { label: 'Migration path', value: `${src}${sv ? ` ${sv}` : ''} → ${tgt}${tv ? ` ${tv}` : ''}` },
    project.repoUrl ? { label: 'Repository', value: project.repoUrl } : null,
    c.estimatedLOC ? { label: 'Estimated LOC', value: str(c.estimatedLOC) } : null,
    c.deadline ? { label: 'Deadline', value: str(c.deadline) } : null,
    c.businessUnit ? { label: 'Business unit', value: str(c.businessUnit) } : null,
  ].filter(Boolean)) as Field[];
}

function deriveStack(project: Project): Field[] {
  const c = (project.config ?? {}) as Record<string, unknown>;
  const tgt = str(project.targetLanguage);
  const tv = str(c.targetVersion);
  const addons = [
    c.addDocker ? 'Docker' : null,
    c.addKubernetes ? 'Kubernetes' : null,
    c.addCI ? 'CI/CD' : null,
    c.addTests ? 'Tests' : null,
    c.addDocs ? 'Docs' : null,
  ].filter(Boolean);
  return ([
    { label: 'Target language', value: `${tgt}${tv ? ` ${tv}` : ''}` },
    c.architecturePattern ? { label: 'Architecture', value: ARCH_LABEL[str(c.architecturePattern)] ?? str(c.architecturePattern) } : null,
    c.intent ? { label: 'Intent', value: str(c.intent) } : null,
    typeof c.qualityLevel === 'number' ? { label: 'Quality gate', value: QUALITY_LABEL[c.qualityLevel as number] ?? str(c.qualityLevel) } : null,
    c.errorHandling ? { label: 'Error handling', value: str(c.errorHandling) } : null,
    c.namingConvention ? { label: 'Naming', value: str(c.namingConvention) } : null,
    c.targetBuild ? { label: 'Build system', value: str(c.targetBuild) } : null,
    c.packageManager ? { label: 'Package manager', value: str(c.packageManager) } : null,
    c.apiFramework ? { label: 'Framework', value: str(c.apiFramework) } : null,
    c.testingFramework ? { label: 'Testing', value: str(c.testingFramework) } : null,
    addons.length ? { label: 'Add-ons', value: addons.join(', ') } : null,
  ].filter(Boolean)) as Field[];
}

function deriveAssumptions(project: Project): string[] {
  const c = (project.config ?? {}) as Record<string, unknown>;
  const src = str(project.sourceLanguage);
  const sv = str(c.sourceVersion);
  return ([
    `Source code is well-formed ${src}${sv ? ` (version ${sv})` : ''}.`,
    c.preserveBusinessLogic !== false ? 'Business logic is preserved verbatim by the engine.' : null,
    c.preserveApiSignatures !== false ? 'Public API signatures are preserved where the target language allows.' : null,
    c.preserveComments !== false ? 'Inline comments are carried over to the generated code.' : null,
    'Network access is available for dependency resolution during build.',
    'Team members listed on the project have read access to the legacy codebase.',
  ].filter(Boolean)) as string[];
}

function derivePhases(project: Project): Phase[] {
  const c = (project.config ?? {}) as Record<string, unknown>;
  const set = getEnabledPluginSet(c);
  const on = (id: string) => isPluginEnabled(id, set);
  const src = str(project.sourceLanguage);
  const tgt = str(project.targetLanguage);
  return [
    { title: 'Pre-Analysis & Repository Scanning', desc: 'Scan structure, measure files and LOC, identify entry points and the dependency graph.', active: true },
    { title: 'Dependency Mapping & Risk Assessment', desc: 'Map internal and external dependencies and flag high-complexity modules.', active: true },
    { title: 'Automated Code Migration', desc: `Translate ${src} → ${tgt} with the Scriba Engine, applying the configured rules and quality gate.`, active: true },
    { title: 'Code Review & Side-by-side Comparison', desc: 'Human review of generated code against the original; accept or override each decision.', active: true },
    { title: 'Testing & Verification', desc: 'Generate and run unit/integration tests; verify behavioural parity with the source.', active: on('test-generation') || on('functional-validation') },
    { title: 'Security & Compliance', desc: 'Static vulnerability analysis and licence audit on the converted codebase.', active: on('security-scan') },
    { title: 'Artifact Generation & Export', desc: 'Package deliverables, generate the migration report, export to the target repository.', active: true },
  ];
}

export default function MigrationStrategyReview({ projectId, onNavigate, project, onProjectUpdate }: Props) {
  const [confirming, setConfirming] = useState(false);
  const [saving, setSaving] = useState(false);
  const [directives, setDirectives] = useState('');
  const [savedDirectives, setSavedDirectives] = useState('');

  const isConfirmed = !!(project?.config as Record<string, unknown> | undefined)?.strategyConfirmed;

  useEffect(() => {
    if (!project) return;
    const cr = str((project.config as Record<string, unknown> | undefined)?.customRules);
    setDirectives(cr);
    setSavedDirectives(cr);
    // Keyed on project.id so a parent re-fetch does not wipe in-progress edits.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [project?.id]);

  if (!project) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-accent" />
      </div>
    );
  }

  const scope = deriveScope(project);
  const stack = deriveStack(project);
  const assumptions = deriveAssumptions(project);
  const phases = derivePhases(project);
  const dirty = directives.trim() !== savedDirectives.trim();

  const saveDirectives = async () => {
    setSaving(true);
    try {
      await api.updateProject(projectId, { config: { customRules: directives.trim() } });
      setSavedDirectives(directives.trim());
      onProjectUpdate?.();
    } catch {
      // keep current edits on error
    } finally {
      setSaving(false);
    }
  };

  const confirmStrategy = async () => {
    setConfirming(true);
    try {
      await api.updateProject(projectId, {
        config: { customRules: directives.trim(), strategyConfirmed: true },
      });
      setSavedDirectives(directives.trim());
      onProjectUpdate?.();
      setTimeout(() => onNavigate?.('pre-analysis', projectId), 600);
    } catch {
      setConfirming(false);
    }
  };

  const KV = ({ icon: Icon, title, hint, fields }: { icon: React.ElementType; title: string; hint: string; fields: Field[] }) => (
    <div className="glass rounded-xl p-5 border border-border/30">
      <div className="flex items-center gap-2.5 mb-4">
        <div className="w-7 h-7 rounded-lg bg-accent/15 flex items-center justify-center flex-shrink-0">
          <Icon className="w-3.5 h-3.5 text-accent-light" />
        </div>
        <div>
          <h2 className="text-sm font-semibold text-foreground">{title}</h2>
          <p className="text-xs text-muted">{hint}</p>
        </div>
      </div>
      <dl className="space-y-2">
        {fields.map(f => (
          <div key={f.label} className="flex items-baseline justify-between gap-4 text-sm">
            <dt className="text-muted flex-shrink-0">{f.label}</dt>
            <dd className="text-foreground font-medium text-right break-all">{f.value}</dd>
          </div>
        ))}
      </dl>
    </div>
  );

  return (
    <div className="space-y-6 pb-10">
      {/* Header */}
      <motion.div
        initial={{ opacity: 0, y: -8 }}
        animate={{ opacity: 1, y: 0 }}
        className="flex items-start justify-between gap-4"
      >
        <div>
          <h1 className="text-xl font-semibold text-foreground">Migration Strategy</h1>
          <p className="text-sm text-muted mt-1 max-w-2xl">
            Last review before the pipeline starts. The summary below is generated from your project configuration — to change it, edit the configuration. Add <strong className="text-foreground/80">engine directives</strong> to steer the translation, then confirm to proceed.
          </p>
        </div>

        <div className="flex items-center gap-2 flex-shrink-0">
          {isConfirmed && (
            <span className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium bg-green-500/15 text-green-400 border border-green-500/20">
              <CheckCircle2 className="w-3.5 h-3.5" />
              Confirmed
            </span>
          )}
          <button
            onClick={() => onNavigate?.('conversion-dashboard', projectId)}
            className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium bg-surface-light hover:bg-surface-lighter text-foreground transition-colors cursor-pointer border border-border/40"
            title="Edit the full project configuration"
          >
            <SlidersHorizontal className="w-3.5 h-3.5" />
            Edit configuration
          </button>
        </div>
      </motion.div>

      {/* Gate notice */}
      {!isConfirmed && (
        <motion.div
          initial={{ opacity: 0, y: 4 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ delay: 0.05 }}
          className="flex items-start gap-3 p-4 rounded-xl border border-amber-500/25 bg-amber-500/8"
        >
          <AlertCircle className="w-4 h-4 text-amber-400 flex-shrink-0 mt-0.5" />
          <p className="text-sm text-amber-300/90">
            This is a required gate. Review the plan, optionally add engine directives, then click <strong>Confirm &amp; Continue</strong> to unlock the analysis pipeline.
          </p>
        </motion.div>
      )}

      {/* Summary: scope + stack */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        <KV icon={Target} title="Scope" hint="Project boundary and migration path" fields={scope} />
        <KV icon={Layers} title="Target Stack" hint="Languages, architecture, and tooling" fields={stack} />
      </div>

      {/* Phases */}
      <div className="glass rounded-xl p-5 border border-border/30">
        <div className="flex items-center gap-2.5 mb-4">
          <div className="w-7 h-7 rounded-lg bg-accent/15 flex items-center justify-center flex-shrink-0">
            <GitBranch className="w-3.5 h-3.5 text-accent-light" />
          </div>
          <div>
            <h2 className="text-sm font-semibold text-foreground">Pipeline Phases</h2>
            <p className="text-xs text-muted">Derived from the modules enabled for this project</p>
          </div>
        </div>
        <ol className="space-y-3">
          {phases.map((p, i) => (
            <li key={p.title} className={`flex items-start gap-3 ${p.active ? '' : 'opacity-45'}`}>
              {p.active
                ? <CheckCircle2 className="w-4 h-4 text-accent-light flex-shrink-0 mt-0.5" />
                : <Circle className="w-4 h-4 text-muted flex-shrink-0 mt-0.5" />}
              <div className="min-w-0">
                <p className="text-sm font-medium text-foreground flex items-center gap-2">
                  <span className="text-muted tabular-nums">{i + 1}.</span>
                  {p.title}
                  {!p.active && <span className="text-[10px] uppercase tracking-wider text-muted border border-border/50 rounded px-1.5 py-0.5">skipped</span>}
                </p>
                <p className="text-xs text-muted mt-0.5">{p.desc}</p>
              </div>
            </li>
          ))}
        </ol>
      </div>

      {/* Engine directives — these actually reach the engine */}
      <div className="glass rounded-xl p-5 border border-accent/20">
        <div className="flex items-center justify-between gap-3 mb-3">
          <div className="flex items-center gap-2.5">
            <div className="w-7 h-7 rounded-lg bg-accent/15 flex items-center justify-center flex-shrink-0">
              <Sparkles className="w-3.5 h-3.5 text-accent-light" />
            </div>
            <div>
              <h2 className="text-sm font-semibold text-foreground">Engine directives</h2>
              <p className="text-xs text-muted">Sent to the Scriba Engine as mandatory instructions for every file. One directive per line.</p>
            </div>
          </div>
          <button
            onClick={saveDirectives}
            disabled={saving || !dirty}
            className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium bg-accent hover:bg-accent/90 text-white transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0"
          >
            {saving ? <div className="w-3.5 h-3.5 border border-white/40 border-t-white rounded-full animate-spin" /> : <Save className="w-3.5 h-3.5" />}
            {dirty ? 'Save directives' : 'Saved'}
          </button>
        </div>
        <textarea
          value={directives}
          onChange={e => setDirectives(e.target.value)}
          rows={5}
          placeholder={'e.g.\nUse the repository pattern for all data access.\nMap COBOL PIC X(n) to a fixed-length String of length n.\nKeep monetary amounts as BigDecimal, never double.'}
          className="w-full bg-surface-light border border-border/40 rounded-lg px-3 py-2.5 text-sm text-foreground font-mono leading-relaxed resize-y focus:outline-none focus:border-accent/50 focus:ring-1 focus:ring-accent/20 transition-colors"
          spellCheck={false}
        />
      </div>

      {/* Assumptions */}
      <div className="glass rounded-xl p-5 border border-border/30">
        <div className="flex items-center gap-2.5 mb-3">
          <div className="w-7 h-7 rounded-lg bg-accent/15 flex items-center justify-center flex-shrink-0">
            <Shield className="w-3.5 h-3.5 text-accent-light" />
          </div>
          <div>
            <h2 className="text-sm font-semibold text-foreground">Assumptions</h2>
            <p className="text-xs text-muted">Pre-conditions for this migration</p>
          </div>
        </div>
        <ul className="space-y-1.5">
          {assumptions.map(a => (
            <li key={a} className="flex items-start gap-2 text-sm text-foreground/85">
              <span className="text-accent-light mt-1.5 w-1 h-1 rounded-full bg-accent-light flex-shrink-0" />
              {a}
            </li>
          ))}
        </ul>
      </div>

      {/* Confirm / Continue footer */}
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ delay: 0.25 }}
        className="flex items-center justify-between pt-2 border-t border-border/30"
      >
        <div className="text-sm text-muted">
          {dirty
            ? 'You have unsaved directives — they will be saved when you confirm.'
            : isConfirmed
              ? 'Strategy confirmed — you may continue to the next step.'
              : 'Confirm the strategy to unlock the analysis pipeline.'}
        </div>
        <div className="flex items-center gap-3">
          {isConfirmed && !dirty && (
            <button
              onClick={() => onNavigate?.('pre-analysis', projectId)}
              className="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium bg-surface-light hover:bg-surface-lighter text-foreground transition-colors cursor-pointer border border-border/40"
            >
              Continue
              <ArrowRight className="w-4 h-4" />
            </button>
          )}
          <button
            onClick={confirmStrategy}
            disabled={confirming}
            className="inline-flex items-center gap-2 px-5 py-2 rounded-lg text-sm font-semibold bg-accent hover:bg-accent/90 text-white transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed shadow-lg shadow-accent/20"
          >
            {confirming ? (
              <div className="w-4 h-4 border border-white/40 border-t-white rounded-full animate-spin" />
            ) : (
              <CheckCircle2 className="w-4 h-4" />
            )}
            {isConfirmed ? 'Re-confirm & Continue' : 'Confirm & Continue'}
          </button>
        </div>
      </motion.div>
    </div>
  );
}
