import { useState, useMemo } from "react";
import { Link } from "@inertiajs/react";
import {
  ArrowLeft, Download, ChevronRight, Clock, PoundSterling,
  Package, Milestone as MilestoneIcon, Layers,
  Server, Monitor, Database, TestTube, BookOpen, Cloud,
  AlertTriangle, Lightbulb, ArrowRightLeft, Users
} from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { phases, PROJECT_META, GANTT_MONTHS } from "./buildProgrammeData";
import {
  CONTINGENCY_PERCENT, COST_CATEGORIES, ROLE_RATES,
  wpCost, type Phase, type CostCategoryKey,
} from "./types";
import jsPDF from "jspdf";
import autoTable from "jspdf-autotable";
import { toast } from "sonner";

/* ── helpers ─────────────────────────────────────── */

const fmt = (n: number) => `£${n.toLocaleString("en-GB")}`;

function phaseCost(p: Phase) {
  return p.workPackages.reduce((s, w) => s + wpCost(w), 0);
}

const totalHours = phases.reduce((s, p) => s + p.workPackages.reduce((a, w) => a + w.hours, 0), 0);
const totalDevCost = phases.reduce((s, p) => s + phaseCost(p), 0);
const contingency = Math.round(totalDevCost * CONTINGENCY_PERCENT / 100);
const grandTotal = totalDevCost + contingency;
const totalWPs = phases.reduce((s, p) => s + p.workPackages.length, 0);

function hoursForCategory(cat: CostCategoryKey) {
  return phases.reduce((s, p) => s + p.workPackages.filter((w) => w.category === cat).reduce((a, w) => a + w.hours, 0), 0);
}
function costForCategory(cat: CostCategoryKey) {
  return phases.reduce((s, p) => s + p.workPackages.filter((w) => w.category === cat).reduce((a, w) => a + wpCost(w), 0), 0);
}

function phaseCostForCategory(phase: Phase, cat: CostCategoryKey) {
  return phase.workPackages.filter((w) => w.category === cat).reduce((a, w) => a + wpCost(w), 0);
}

const categoryIcon: Record<CostCategoryKey, React.ElementType> = {
  backend: Server, frontend: Monitor, database: Database,
  testing: TestTube, documentation: BookOpen, devops: Cloud,
};

/* ── PDF export ──────────────────────────────────── */

function sanitise(s: string) {
  return s
    .replace(/[‘’]/g, "'")
    .replace(/[“”]/g, '"')
    .replace(/—/g, "--")
    .replace(/–/g, "-")
    .replace(/…/g, "...")
    .replace(/£/g, "GBP ")
    .replace(/·/g, "-")
    .replace(/×/g, "x")
    .replace(/→/g, "->");
}

const MODULE_CONVERSION = [
  { module: "Authentication & RBAC", approach: "Breeze/Fortify for auth scaffolding, Spatie Permission for RBAC, custom OTP via Mail.", phase: 1 },
  { module: "Course Management", approach: "Eloquent models with sluggable trait, Media Library for images, Blade CRUD views with Livewire for inline editing.", phase: 2 },
  { module: "Availability Engine", approach: "Custom service class replacing Supabase Edge Functions. Pure PHP date arithmetic with Carbon library, bank holiday integration.", phase: 2 },
  { module: "Booking & Payments", approach: "Cashier for Stripe integration, replacing client-side Stripe Elements with server-side payment intents. Queue-based email dispatch.", phase: 3 },
  { module: "Multi-Tenancy", approach: "Stancl/Tenancy package or custom middleware for subdomain resolution. Tenant-scoped Eloquent global scopes. Dynamic Blade layout theming.", phase: 4 },
  { module: "Company Portal", approach: "Dedicated route group with company-scoped middleware. Blade dashboards replacing React components. Credit system as a service class.", phase: 4 },
  { module: "Compliance & Certificates", approach: "Server-side certificate tracking with scheduled Artisan commands for expiry monitoring. DomPDF for certificate/form PDF generation.", phase: 5 },
  { module: "AI Services", approach: "PHP HTTP client wrapping AI vision APIs. Queue-based processing for video frame analysis. Results stored in MySQL with JSON columns.", phase: 5 },
];

const RISK_REGISTER = [
  { risk: "Schema migration data loss", impact: "High", likelihood: "Low", mitigation: "Automated migration scripts with rollback, staging validation, parallel-run period" },
  { risk: "Stripe API version incompatibility", impact: "Medium", likelihood: "Low", mitigation: "Pin Stripe API version, comprehensive payment test suite, sandbox testing" },
  { risk: "Multi-tenancy performance degradation", impact: "High", likelihood: "Medium", mitigation: "Database indexing strategy, Redis caching, query profiling from Phase 2 onwards" },
  { risk: "AI service API availability", impact: "Medium", likelihood: "Medium", mitigation: "Queue-based async processing, graceful degradation, fallback to manual input" },
  { risk: "Scope creep from prototype features", impact: "High", likelihood: "High", mitigation: "Frozen prototype baseline, formal change request process, contingency budget" },
  { risk: "Browser compatibility (Blade vs React)", impact: "Low", likelihood: "Medium", mitigation: "Progressive enhancement, E2E cross-browser testing, polyfill strategy" },
];

const INNOVATION_NARRATIVE: { heading: string; body: string }[] = [
  { heading: "Technological Uncertainty", body: "This project addresses significant technological uncertainty in converting an AI-assisted rapid prototype into a production-grade, multi-tenant training management platform. The prototype, built using Lovable's AI-powered development environment, demonstrates functional requirements but cannot be directly deployed as a commercial product due to architectural constraints of the prototyping framework." },
  { heading: "Advance in Technology", body: "The programme seeks to advance the state of the art in several areas: (1) AI-powered workplace risk assessment using computer vision to analyse site photographs and video, identifying hazards and generating compliance documentation; (2) Augmented reality remote mentoring for field engineers, enabling real-time expert guidance during complex utility installations; (3) Automated compliance matrix management across a multi-company training ecosystem with dynamic skills gap analysis." },
  { heading: "Competent Professional", body: "These challenges cannot be readily resolved by a competent professional in the field. The integration of AI vision services with real-time risk scoring, combined with multi-tenant data isolation and regulatory compliance requirements (NRSWA, EUSR, Smart Metering), requires novel approaches to architecture, data security, and user experience design." },
  { heading: "R&D Activities", body: "The programme includes systematic investigation through prototyping (Phase 1-2), iterative development with controlled experimentation (Phase 3-4), and validation through structured testing (Phase 5-6). Each phase produces measurable deliverables that advance understanding of the technical challenges and inform subsequent development decisions." },
];

function exportPdf() {
  const doc = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" });
  const pageW = doc.internal.pageSize.getWidth();
  const pageH = doc.internal.pageSize.getHeight();
  const margin = 18;
  const contentW = pageW - margin * 2;

  const drawFooter = () => {
    const total = doc.getNumberOfPages();
    for (let i = 1; i <= total; i++) {
      doc.setPage(i);
      doc.setFontSize(8);
      doc.setTextColor(120);
      doc.text(sanitise(`${PROJECT_META.applicant} - ${PROJECT_META.title}`), margin, pageH - 8);
      doc.text(`Page ${i} of ${total}`, pageW - margin, pageH - 8, { align: "right" });
      doc.setTextColor(0);
    }
  };

  const sectionHeading = (title: string, y: number) => {
    doc.setFillColor(30, 64, 175);
    doc.rect(margin, y - 6, contentW, 9, "F");
    doc.setTextColor(255);
    doc.setFontSize(12);
    doc.setFont("helvetica", "bold");
    doc.text(sanitise(title), margin + 3, y);
    doc.setTextColor(0);
    doc.setFont("helvetica", "normal");
  };

  const ensureSpace = (currentY: number, needed: number) => {
    if (currentY + needed > pageH - 18) {
      doc.addPage();
      return margin + 6;
    }
    return currentY;
  };

  /* ───── Cover page ───── */
  doc.setFillColor(15, 23, 42);
  doc.rect(0, 0, pageW, pageH, "F");
  doc.setTextColor(255);
  doc.setFont("helvetica", "bold");
  doc.setFontSize(26);
  const titleLines = doc.splitTextToSize(sanitise(PROJECT_META.title), contentW);
  doc.text(titleLines, pageW / 2, 70, { align: "center" });
  doc.setFont("helvetica", "normal");
  doc.setFontSize(14);
  doc.text(sanitise(PROJECT_META.subtitle), pageW / 2, 95, { align: "center" });

  doc.setDrawColor(96, 165, 250);
  doc.setLineWidth(0.4);
  doc.line(pageW / 2 - 30, 105, pageW / 2 + 30, 105);

  doc.setFontSize(11);
  doc.setTextColor(203, 213, 225);
  const meta = [
    ["Applicant", PROJECT_META.applicant],
    ["Grant Reference", PROJECT_META.grantRef],
    ["Programme Window", `${PROJECT_META.programmeStart} - ${PROJECT_META.programmeEnd} (48 weeks)`],
    ["Current Stack", PROJECT_META.currentStack],
    ["Target Stack", PROJECT_META.targetStack],
    ["Total Effort", `${totalHours.toLocaleString()} hours across ${totalWPs} work packages`],
    ["Total Cost", `${fmt(grandTotal)} (inc. ${CONTINGENCY_PERCENT}% contingency)`],
  ];
  let cy = 125;
  meta.forEach(([k, v]) => {
    doc.setFont("helvetica", "bold");
    doc.setTextColor(148, 163, 184);
    doc.text(sanitise(k.toUpperCase()), margin, cy);
    doc.setFont("helvetica", "normal");
    doc.setTextColor(241, 245, 249);
    const lines = doc.splitTextToSize(sanitise(String(v)), contentW - 50);
    doc.text(lines, margin + 50, cy);
    cy += 6 + (lines.length - 1) * 5;
  });

  doc.setFontSize(9);
  doc.setTextColor(148, 163, 184);
  doc.text(sanitise(`Generated ${new Date().toLocaleDateString("en-GB", { day: "numeric", month: "long", year: "numeric" })}`), pageW / 2, pageH - 25, { align: "center" });
  doc.setTextColor(0);

  /* ───── Executive summary ───── */
  doc.addPage();
  let y = margin + 6;
  sectionHeading("Executive Summary", y);
  y += 10;
  doc.setFontSize(10);
  const summary = `${PROJECT_META.applicant} has developed a functional prototype of the ${PROJECT_META.title} using AI-assisted rapid prototyping. This document specifies a ${48}-week, 6-phase build programme to convert that prototype into a production-grade, multi-tenant ${PROJECT_META.targetStack.split(",")[0]} application. The programme comprises ${totalWPs} discrete work packages totalling ${totalHours.toLocaleString()} hours of effort, structured across ${phases.length} milestone-gated phases with payment release tied to deliverable acceptance.`;
  const sumLines = doc.splitTextToSize(sanitise(summary), contentW);
  doc.text(sumLines, margin, y);
  y += sumLines.length * 5 + 6;

  autoTable(doc, {
    startY: y,
    head: [["Phase", "Theme", "Weeks", "WPs", "Hours", "Cost", "Milestone Payment"]],
    body: phases.map((p) => {
      const hrs = p.workPackages.reduce((a, w) => a + w.hours, 0);
      return [
        p.label,
        sanitise(p.theme),
        String(p.weeks),
        String(p.workPackages.length),
        hrs.toLocaleString(),
        fmt(phaseCost(p)),
        `${p.milestone.paymentPercent}% (${fmt(Math.round(grandTotal * p.milestone.paymentPercent / 100))})`,
      ];
    }).concat([["Total", "", "48", String(totalWPs), totalHours.toLocaleString(), fmt(totalDevCost), ""]]),
    styles: { fontSize: 8, cellPadding: 2 },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    foot: [["", "", "", "", "Inc. contingency", fmt(grandTotal), "100%"]],
    footStyles: { fillColor: [219, 234, 254], textColor: [30, 64, 175], fontStyle: "bold" },
    margin: { left: margin, right: margin },
  });

  /* ───── Resource rates ───── */
  doc.addPage();
  y = margin + 6;
  sectionHeading("Resource Rates & Allocation", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Role", "Rate / hr", "Total Hours", "Total Cost", "% of Hours"]],
    body: ROLE_RATES.map((r) => {
      const roleHrs = phases.reduce((s, p) => s + p.workPackages.reduce((a, w) => a + (w.roleHours[r.key] || 0), 0), 0);
      return [
        sanitise(r.label),
        fmt(r.rate),
        roleHrs.toLocaleString(),
        fmt(roleHrs * r.rate),
        `${Math.round((roleHrs / totalHours) * 100)}%`,
      ];
    }),
    foot: [["Total (blended)", "", totalHours.toLocaleString(), fmt(totalDevCost), "100%"]],
    styles: { fontSize: 9 },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    footStyles: { fillColor: [219, 234, 254], textColor: [30, 64, 175], fontStyle: "bold" },
    margin: { left: margin, right: margin },
  });

  /* ───── Phase deep-dive (full WP detail) ───── */
  phases.forEach((phase) => {
    doc.addPage();
    y = margin + 6;
    sectionHeading(`${phase.label}: ${phase.theme}`, y);
    y += 10;

    doc.setFontSize(9);
    const phaseHrs = phase.workPackages.reduce((a, w) => a + w.hours, 0);
    doc.setFont("helvetica", "bold");
    doc.text(`Duration: `, margin, y);
    doc.setFont("helvetica", "normal");
    doc.text(`${phase.weeks} weeks`, margin + 18, y);
    doc.setFont("helvetica", "bold");
    doc.text(`Effort: `, margin + 55, y);
    doc.setFont("helvetica", "normal");
    doc.text(`${phaseHrs.toLocaleString()} hrs`, margin + 68, y);
    doc.setFont("helvetica", "bold");
    doc.text(`Cost: `, margin + 100, y);
    doc.setFont("helvetica", "normal");
    doc.text(fmt(phaseCost(phase)), margin + 112, y);
    y += 7;

    // Detailed WP entries (mirror the on-page card)
    phase.workPackages.forEach((wp) => {
      const descLines = doc.splitTextToSize(sanitise(wp.description), contentW - 4);
      const delivStr = "Deliverables: " + wp.deliverables.join("; ");
      const delivLines = doc.splitTextToSize(sanitise(delivStr), contentW - 4);
      const roleParts = ROLE_RATES.filter((r) => wp.roleHours[r.key] > 0).map((r) => `${r.label.split(" ")[0]} ${wp.roleHours[r.key]}h`);
      const metaStr = `Hours: ${wp.hours}  |  Cost: ${fmt(wpCost(wp))}  |  Roles: ${roleParts.join(", ")}  |  Category: ${COST_CATEGORIES.find((c) => c.key === wp.category)?.label || wp.category}  |  Deps: ${wp.dependencies.join(", ") || "none"}`;
      const metaLines = doc.splitTextToSize(sanitise(metaStr), contentW - 4);

      const blockH = 6 + descLines.length * 4 + delivLines.length * 4 + metaLines.length * 4 + 6;
      y = ensureSpace(y, blockH);

      // Header bar
      doc.setFillColor(241, 245, 249);
      doc.rect(margin, y - 4, contentW, 6, "F");
      doc.setFont("helvetica", "bold");
      doc.setFontSize(9);
      doc.setTextColor(30, 64, 175);
      doc.text(sanitise(`${wp.id}  ${wp.title}`), margin + 2, y);
      doc.setTextColor(0);
      y += 5;

      doc.setFont("helvetica", "normal");
      doc.setFontSize(8);
      doc.text(descLines, margin + 2, y);
      y += descLines.length * 4;

      doc.setTextColor(71, 85, 105);
      doc.text(delivLines, margin + 2, y);
      y += delivLines.length * 4;

      doc.setFont("helvetica", "italic");
      doc.setTextColor(100, 116, 139);
      doc.text(metaLines, margin + 2, y);
      y += metaLines.length * 4 + 4;
      doc.setFont("helvetica", "normal");
      doc.setTextColor(0);
    });

    // Milestone block
    y = ensureSpace(y, 50);
    y += 4;
    doc.setFillColor(219, 234, 254);
    doc.setDrawColor(96, 165, 250);
    const mY = y;
    doc.setFont("helvetica", "bold");
    doc.setFontSize(10);
    doc.setTextColor(30, 64, 175);
    const titleStr = sanitise(`Milestone: ${phase.milestone.title}`);
    const critLines = doc.splitTextToSize(sanitise(`Criteria: ${phase.milestone.criteria}`), contentW - 6);
    const evidLines = doc.splitTextToSize(sanitise(`Evidence: ${phase.milestone.evidence}`), contentW - 6);
    const payStr = `Payment Release: ${phase.milestone.paymentPercent}% of grand total = ${fmt(Math.round(grandTotal * phase.milestone.paymentPercent / 100))}`;
    const blockH = 8 + critLines.length * 4 + evidLines.length * 4 + 8;
    doc.rect(margin, mY - 4, contentW, blockH, "FD");
    doc.text(titleStr, margin + 3, mY);
    doc.setFont("helvetica", "normal");
    doc.setFontSize(8);
    doc.setTextColor(15, 23, 42);
    doc.text(critLines, margin + 3, mY + 5);
    doc.text(evidLines, margin + 3, mY + 5 + critLines.length * 4);
    doc.setFont("helvetica", "bold");
    doc.setTextColor(30, 64, 175);
    doc.text(sanitise(payStr), margin + 3, mY + 5 + critLines.length * 4 + evidLines.length * 4 + 2);
    doc.setTextColor(0);
    doc.setFont("helvetica", "normal");
  });

  /* ───── Milestone payment schedule ───── */
  doc.addPage();
  y = margin + 6;
  sectionHeading("Milestone Payment Schedule", y);
  y += 10;
  let cum = 0;
  autoTable(doc, {
    startY: y,
    head: [["Milestone", "Completion Criteria", "Evidence Required", "%", "Payment", "Cumulative"]],
    body: phases.map((p) => {
      const pay = Math.round(grandTotal * p.milestone.paymentPercent / 100);
      cum += pay;
      return [
        sanitise(p.milestone.title),
        sanitise(p.milestone.criteria),
        sanitise(p.milestone.evidence),
        `${p.milestone.paymentPercent}%`,
        fmt(pay),
        fmt(cum),
      ];
    }),
    styles: { fontSize: 8, cellPadding: 2, valign: "top" },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    columnStyles: {
      0: { cellWidth: 32, fontStyle: "bold" },
      1: { cellWidth: 50 },
      2: { cellWidth: 50 },
      3: { cellWidth: 12, halign: "right" },
      4: { cellWidth: 22, halign: "right" },
      5: { cellWidth: 22, halign: "right", fontStyle: "bold" },
    },
    margin: { left: margin, right: margin },
  });

  /* ───── Cost by category ───── */
  doc.addPage();
  y = margin + 6;
  sectionHeading("Cost Summary by Category", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Category", "Hours", "Cost", "% of Total"]],
    body: COST_CATEGORIES.map((c) => {
      const h = hoursForCategory(c.key);
      const cost = costForCategory(c.key);
      return [sanitise(c.label), h.toLocaleString(), fmt(cost), `${Math.round((cost / totalDevCost) * 100)}%`];
    }),
    foot: [
      ["Subtotal", totalHours.toLocaleString(), fmt(totalDevCost), "100%"],
      [`Contingency (${CONTINGENCY_PERCENT}%)`, "-", fmt(contingency), ""],
      ["Grand Total", totalHours.toLocaleString(), fmt(grandTotal), ""],
    ],
    styles: { fontSize: 9 },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    footStyles: { fillColor: [219, 234, 254], textColor: [30, 64, 175], fontStyle: "bold" },
    margin: { left: margin, right: margin },
  });

  /* ───── Cost by phase × category matrix ───── */
  y = (doc as any).lastAutoTable?.finalY + 12 || y + 60;
  y = ensureSpace(y, 60);
  sectionHeading("Cost by Phase x Category", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Phase", ...COST_CATEGORIES.map((c) => c.label.split(" ")[0]), "Total"]],
    body: phases.map((p) => [
      p.label,
      ...COST_CATEGORIES.map((c) => {
        const v = phaseCostForCategory(p, c.key);
        return v > 0 ? fmt(v) : "-";
      }),
      fmt(phaseCost(p)),
    ]),
    foot: [["Total", ...COST_CATEGORIES.map((c) => fmt(costForCategory(c.key))), fmt(totalDevCost)]],
    styles: { fontSize: 8, halign: "right" },
    headStyles: { fillColor: [30, 41, 59], textColor: 255, halign: "right" },
    footStyles: { fillColor: [219, 234, 254], textColor: [30, 64, 175], fontStyle: "bold", halign: "right" },
    columnStyles: { 0: { halign: "left", fontStyle: "bold" } },
    margin: { left: margin, right: margin },
  });

  /* ───── Assumptions ───── */
  y = (doc as any).lastAutoTable?.finalY + 12 || y + 60;
  y = ensureSpace(y, 80);
  sectionHeading("Assumptions & Basis of Estimate", y);
  y += 10;
  doc.setFontSize(9);
  const assumptions = [
    `Senior Developer: ${fmt(ROLE_RATES[0].rate)}/hour - PHP, frontend, and database development`,
    `CTO / Technical Lead: ${fmt(ROLE_RATES[1].rate)}/hour - Architecture decisions, code review, technical risk management, security oversight`,
    `Project Manager: ${fmt(ROLE_RATES[2].rate)}/hour - Sprint planning, stakeholder communication, milestone tracking, documentation coordination`,
    "Working week: 5 days x 8 hours = 40 hours/week",
    `Programme duration: 48 weeks (12 months) across ${phases.length} phases`,
    `Contingency: ${CONTINGENCY_PERCENT}% applied to base cost to cover scope refinement, technical risk, and integration complexity`,
    "Estimates derived from detailed prototype analysis - each work package scoped against the functional prototype built in Lovable",
    "All prices exclude VAT",
    "Blended team: 1 CTO (part-time oversight), 1 PM (part-time coordination), 2 Senior Developers (full-time delivery)",
  ];
  assumptions.forEach((a) => {
    const lines = doc.splitTextToSize(sanitise("- " + a), contentW);
    y = ensureSpace(y, lines.length * 4 + 2);
    doc.text(lines, margin, y);
    y += lines.length * 4 + 2;
  });

  /* ───── Architecture conversion ───── */
  doc.addPage();
  y = margin + 6;
  sectionHeading("Technical Approach - Architecture Conversion", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Current Stack (Prototype)", "Target Stack (Production)"]],
    body: [
      ["React 18 with TypeScript", "PHP 8.3"],
      ["Supabase (PostgreSQL, Auth, Edge Functions, Storage)", "MySQL 8 relational database"],
      ["Vite build tooling", "HTML5 Blade templates + Tailwind CSS"],
      ["Tailwind CSS + shadcn/ui", "JSON REST APIs for async features"],
      ["Client-side rendering (SPA)", "Server-side rendering with Alpine.js interactivity"],
      ["-", "Redis caching, Queue, Horizon"],
    ],
    styles: { fontSize: 9, cellPadding: 2 },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    margin: { left: margin, right: margin },
  });

  y = (doc as any).lastAutoTable?.finalY + 12 || y + 60;
  y = ensureSpace(y, 40);
  sectionHeading("Module Conversion Strategy", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Phase", "Module", "Conversion Approach"]],
    body: MODULE_CONVERSION.map((m) => [`P${m.phase}`, sanitise(m.module), sanitise(m.approach)]),
    styles: { fontSize: 8, cellPadding: 2, valign: "top" },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    columnStyles: { 0: { cellWidth: 14, halign: "center" }, 1: { cellWidth: 50, fontStyle: "bold" } },
    margin: { left: margin, right: margin },
  });

  /* ───── Risk register ───── */
  doc.addPage();
  y = margin + 6;
  sectionHeading("Risk Register", y);
  y += 10;
  autoTable(doc, {
    startY: y,
    head: [["Risk", "Impact", "Likelihood", "Mitigation"]],
    body: RISK_REGISTER.map((r) => [sanitise(r.risk), r.impact, r.likelihood, sanitise(r.mitigation)]),
    styles: { fontSize: 9, cellPadding: 2, valign: "top" },
    headStyles: { fillColor: [30, 41, 59], textColor: 255 },
    columnStyles: {
      0: { cellWidth: 50, fontStyle: "bold" },
      1: { cellWidth: 22, halign: "center" },
      2: { cellWidth: 24, halign: "center" },
    },
    margin: { left: margin, right: margin },
  });

  /* ───── Innovation narrative ───── */
  y = (doc as any).lastAutoTable?.finalY + 12 || y + 60;
  y = ensureSpace(y, 60);
  sectionHeading("Innovation Narrative (R&D Justification)", y);
  y += 10;
  doc.setFontSize(9);
  INNOVATION_NARRATIVE.forEach((n) => {
    const headLines = doc.splitTextToSize(sanitise(n.heading), contentW);
    const bodyLines = doc.splitTextToSize(sanitise(n.body), contentW);
    y = ensureSpace(y, (headLines.length + bodyLines.length) * 5 + 4);
    doc.setFont("helvetica", "bold");
    doc.setTextColor(30, 64, 175);
    doc.text(headLines, margin, y);
    y += headLines.length * 5;
    doc.setFont("helvetica", "normal");
    doc.setTextColor(0);
    doc.text(bodyLines, margin, y);
    y += bodyLines.length * 4 + 4;
  });

  drawFooter();
  doc.save("UTC-Build-Programme.pdf");
  toast.success("PDF exported successfully");
}

/* ── component ───────────────────────────────────── */

const BuildProgrammePage = () => {
  const [activePhase, setActivePhase] = useState(1);

  const phaseStats = useMemo(() => phases.map((p) => {
    const hrs = p.workPackages.reduce((a, w) => a + w.hours, 0);
    const cost = phaseCost(p);
    return { ...p, totalHours: hrs, totalCost: cost, pct: Math.round((hrs / totalHours) * 100) };
  }), []);

  const activePhaseData = phaseStats.find((p) => p.id === activePhase) || phaseStats[0];

  const cumulativePayment = useMemo(() => {
    let cum = 0;
    return phases.map((p) => {
      cum += Math.round(grandTotal * p.milestone.paymentPercent / 100);
      return cum;
    });
  }, []);

  return (
    <div
      className="min-h-screen light"
      data-theme="light"
      style={{
        colorScheme: 'light',
        '--background': '0 0% 100%',
        '--foreground': '222 47% 11%',
        '--card': '0 0% 100%',
        '--card-foreground': '222 47% 11%',
        '--popover': '0 0% 100%',
        '--popover-foreground': '222 47% 11%',
        '--primary': '221 83% 53%',
        '--primary-foreground': '0 0% 100%',
        '--secondary': '210 40% 96%',
        '--secondary-foreground': '222 47% 11%',
        '--muted': '210 40% 96%',
        '--muted-foreground': '215 16% 47%',
        '--accent': '210 40% 96%',
        '--accent-foreground': '222 47% 11%',
        '--destructive': '0 84% 60%',
        '--destructive-foreground': '0 0% 100%',
        '--border': '214 32% 91%',
        '--input': '214 32% 91%',
        '--ring': '221 83% 53%',
        backgroundColor: 'white',
        color: '#0f172a',
      } as React.CSSProperties}
    >
      {/* Header */}
      <header className="border-b border-slate-200 bg-white/90 backdrop-blur sticky top-0 z-30">
        <div className="max-w-[1600px] mx-auto px-4 py-3 flex items-center justify-between gap-4 flex-wrap">
          <div className="flex items-center gap-3">
            <Link href="/project-plan">
              <Button variant="ghost" size="icon" className="text-slate-900 hover:bg-slate-100"><ArrowLeft className="w-4 h-4" /></Button>
            </Link>
            <div>
              <h1 className="text-lg font-bold leading-tight text-slate-900">R&D Build Programme</h1>
              <p className="text-xs text-slate-800">{PROJECT_META.applicant} — {PROJECT_META.grantRef}</p>
            </div>
          </div>
          <div className="flex items-center gap-2 flex-wrap">
            <Badge variant="outline" className="gap-1 text-[10px] border-slate-300 text-slate-900"><Clock className="w-3 h-3" />{totalHours.toLocaleString()} hrs</Badge>
            <Badge variant="outline" className="gap-1 text-[10px] border-slate-300 text-slate-900"><PoundSterling className="w-3 h-3" />{fmt(grandTotal)}</Badge>
            <Badge variant="outline" className="gap-1 text-[10px] border-slate-300 text-slate-900"><Package className="w-3 h-3" />{totalWPs} WPs</Badge>
            <Badge variant="outline" className="gap-1 text-[10px] border-slate-300 text-slate-900"><MilestoneIcon className="w-3 h-3" />6 Milestones</Badge>
            <Button size="sm" onClick={exportPdf} className="gap-1"><Download className="w-3.5 h-3.5" />Export PDF</Button>
          </div>
        </div>
      </header>

      <div className="max-w-[1600px] mx-auto flex">
        {/* Sidebar */}
        <aside className="hidden lg:block w-56 shrink-0 border-r border-slate-200 p-3 sticky top-[57px] h-[calc(100vh-57px)] bg-slate-50">
          <ScrollArea className="h-full">
            <p className="text-[10px] font-semibold text-slate-700 uppercase tracking-wider mb-2">Phases</p>
            {phaseStats.map((p) => (
              <button
                key={p.id}
                onClick={() => setActivePhase(p.id)}
                className={cn(
                  "w-full text-left rounded-md px-2.5 py-2 mb-1 text-xs transition-colors",
                  activePhase === p.id
                    ? "bg-blue-50 text-blue-700 font-semibold border border-blue-200"
                    : "hover:bg-slate-100 text-slate-800 border border-transparent"
                )}
              >
                <div className="flex items-center justify-between">
                  <span>{p.label}</span>
                  <ChevronRight className={cn("w-3 h-3 transition-transform", activePhase === p.id && "rotate-90")} />
                </div>
                <p className="text-[10px] opacity-70 mt-0.5 line-clamp-1">{p.theme}</p>
                <div className="w-full bg-slate-200 rounded-full h-1 mt-1">
                  <div className="bg-blue-500 h-1 rounded-full" style={{ width: `${p.pct}%` }} />
                </div>
              </button>
            ))}

            {/* Role rates */}
            <div className="mt-4 border-t border-slate-200 pt-3">
              <p className="text-[10px] font-semibold text-slate-700 uppercase tracking-wider mb-1">Resource Rates</p>
              {ROLE_RATES.map((r) => (
                <div key={r.key} className="flex justify-between text-[10px] text-slate-800 py-0.5">
                  <span>{r.label}</span>
                  <span className="font-mono">{fmt(r.rate)}/hr</span>
                </div>
              ))}
            </div>

            <div className="mt-4 border-t border-slate-200 pt-3">
              <p className="text-[10px] font-semibold text-slate-700 uppercase tracking-wider mb-1">Quick Links</p>
              <Link href="/system-requirements" className="block text-[10px] text-blue-600 hover:underline py-0.5">System Requirements</Link>
              <Link href="/project-plan" className="block text-[10px] text-blue-600 hover:underline py-0.5">12-Month Project Plan</Link>
              <Link href="/resource-docs" className="block text-[10px] text-blue-600 hover:underline py-0.5">Resource Management</Link>
            </div>
          </ScrollArea>
        </aside>

        {/* Main */}
        <main className="flex-1 min-w-0 p-4 md:p-6 bg-white">
          <Tabs defaultValue="programme" className="space-y-4">
            <TabsList className="flex-wrap h-auto gap-1 bg-slate-100">
              <TabsTrigger value="programme" className="text-xs data-[state=active]:bg-white">Build Programme</TabsTrigger>
              <TabsTrigger value="milestones" className="text-xs data-[state=active]:bg-white">Milestone Schedule</TabsTrigger>
              <TabsTrigger value="costs" className="text-xs data-[state=active]:bg-white">Cost Breakdown</TabsTrigger>
              <TabsTrigger value="technical" className="text-xs data-[state=active]:bg-white">Technical Approach</TabsTrigger>
            </TabsList>

            {/* ── TAB 1: Build Programme ─────────── */}
            <TabsContent value="programme" className="space-y-6">
              <Card className="border-slate-200 shadow-sm ring-1 ring-blue-100">
                <CardHeader className="pb-2">
                  <div className="flex items-center justify-between flex-wrap gap-2">
                    <CardTitle className="text-sm flex items-center gap-2 text-slate-900">
                      <Badge className="text-[10px] bg-blue-600">{activePhaseData.label}</Badge>
                      {activePhaseData.theme}
                    </CardTitle>
                    <div className="flex items-center gap-2 text-[10px] text-slate-800">
                      <span>{activePhaseData.weeks} weeks</span>
                      <span>·</span>
                      <span>{activePhaseData.totalHours} hrs</span>
                      <span>·</span>
                      <span className="font-semibold text-slate-900">{fmt(activePhaseData.totalCost)}</span>
                    </div>
                  </div>
                  <div className="w-full bg-slate-200 rounded-full h-1.5 mt-2">
                    <div className="bg-blue-500 h-1.5 rounded-full" style={{ width: `${activePhaseData.pct}%` }} />
                  </div>
                  <p className="text-[10px] text-slate-700 mt-1">{activePhaseData.pct}% of total programme effort</p>
                </CardHeader>
                <CardContent>
                  <div className="overflow-x-auto">
                    <Table>
                      <TableHeader>
                        <TableRow className="border-slate-200">
                          <TableHead className="text-[10px] w-12 text-slate-800">ID</TableHead>
                          <TableHead className="text-[10px] text-slate-800">Work Package</TableHead>
                          <TableHead className="text-[10px] w-16 text-slate-800">Cat.</TableHead>
                          <TableHead className="text-[10px] w-14 text-right text-slate-800">Hours</TableHead>
                          <TableHead className="text-[10px] w-20 text-right text-slate-800">Cost</TableHead>
                          <TableHead className="text-[10px] w-20 text-slate-800">Deps</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {activePhaseData.workPackages.map((wp) => {
                          const Icon = categoryIcon[wp.category];
                          return (
                            <TableRow key={wp.id} className="group border-slate-100 hover:bg-slate-50">
                              <TableCell className="text-[10px] font-mono text-slate-900">{wp.id}</TableCell>
                              <TableCell>
                                <p className="text-xs font-medium text-slate-800">{wp.title}</p>
                                <p className="text-[10px] text-slate-800 mt-0.5 line-clamp-2">{wp.description}</p>
                                <div className="flex flex-wrap gap-1 mt-1">
                                  {wp.deliverables.map((d, i) => (
                                    <Badge key={i} variant="outline" className="text-[9px] py-0 border-slate-200 text-slate-800">{d}</Badge>
                                  ))}
                                </div>
                                <div className="flex gap-2 mt-1 text-[9px] text-slate-700">
                                  {ROLE_RATES.map((r) => wp.roleHours[r.key] > 0 && (
                                    <span key={r.key}>{r.label.split(" ")[0]}: {wp.roleHours[r.key]}h</span>
                                  ))}
                                </div>
                              </TableCell>
                              <TableCell><Icon className="w-3.5 h-3.5 text-slate-700" /></TableCell>
                              <TableCell className="text-[10px] text-right font-mono text-slate-900">{wp.hours}</TableCell>
                              <TableCell className="text-[10px] text-right font-mono text-slate-800">{fmt(wpCost(wp))}</TableCell>
                              <TableCell className="text-[10px] font-mono text-slate-700">{wp.dependencies.join(", ") || "—"}</TableCell>
                            </TableRow>
                          );
                        })}
                      </TableBody>
                    </Table>
                  </div>

                  {/* Milestone */}
                  <div className="mt-4 p-3 rounded-md bg-blue-50 border border-blue-200">
                    <p className="text-xs font-semibold flex items-center gap-1.5 text-blue-800"><MilestoneIcon className="w-3.5 h-3.5 text-blue-600" />{activePhaseData.milestone.title}</p>
                    <p className="text-[10px] text-slate-900 mt-1"><strong>Criteria:</strong> {activePhaseData.milestone.criteria}</p>
                    <p className="text-[10px] text-slate-900 mt-0.5"><strong>Evidence:</strong> {activePhaseData.milestone.evidence}</p>
                    <p className="text-[10px] font-medium text-blue-700 mt-1">Payment Release: {activePhaseData.milestone.paymentPercent}% → {fmt(Math.round(grandTotal * activePhaseData.milestone.paymentPercent / 100))}</p>
                  </div>
                </CardContent>
              </Card>
            </TabsContent>

            {/* ── TAB 2: Milestone Schedule ──────── */}
            <TabsContent value="milestones" className="space-y-6">
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm text-slate-900">Programme Timeline</CardTitle></CardHeader>
                <CardContent>
                  <div className="overflow-x-auto">
                    <div className="min-w-[700px]">
                      <div className="grid grid-cols-[140px_repeat(12,1fr)] gap-px text-[9px] text-slate-700 mb-1">
                        <div />
                        {GANTT_MONTHS.map((m) => <div key={m} className="text-center border-b border-slate-200 pb-1">{m}</div>)}
                      </div>
                      {phases.map((p) => {
                        const startMonth = (p.id - 1) * 2;
                        const spanMonths = 2;
                        return (
                          <div key={p.id} className="grid grid-cols-[140px_repeat(12,1fr)] gap-px items-center h-9">
                            <div className="text-[10px] font-medium truncate pr-1 text-slate-700">{p.label}: {p.theme.split(" ")[0]}</div>
                            {Array.from({ length: 12 }).map((_, i) => (
                              <div key={i} className="h-6 flex items-center">
                                {i >= startMonth && i < startMonth + spanMonths && (
                                  <div className="w-full h-5 rounded-sm bg-blue-500 flex items-center justify-center">
                                    {i === startMonth + spanMonths - 1 && (
                                      <span className="text-[8px] text-white font-bold">M{p.id}</span>
                                    )}
                                  </div>
                                )}
                              </div>
                            ))}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                </CardContent>
              </Card>

              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm text-slate-900">Milestone Payment Schedule</CardTitle></CardHeader>
                <CardContent>
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200">
                        <TableHead className="text-[10px] text-slate-800">Milestone</TableHead>
                        <TableHead className="text-[10px] text-slate-800">Completion Criteria</TableHead>
                        <TableHead className="text-[10px] text-slate-800">Evidence Required</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">%</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Payment</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Cumulative</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {phases.map((p, i) => (
                        <TableRow key={p.id} className="border-slate-100">
                          <TableCell className="text-xs font-medium text-slate-800">{p.milestone.title}</TableCell>
                          <TableCell className="text-[10px] max-w-[200px] text-slate-900">{p.milestone.criteria}</TableCell>
                          <TableCell className="text-[10px] max-w-[180px] text-slate-900">{p.milestone.evidence}</TableCell>
                          <TableCell className="text-[10px] text-right font-mono text-slate-900">{p.milestone.paymentPercent}%</TableCell>
                          <TableCell className="text-[10px] text-right font-mono text-slate-700">{fmt(Math.round(grandTotal * p.milestone.paymentPercent / 100))}</TableCell>
                          <TableCell className="text-[10px] text-right font-mono font-semibold text-slate-900">{fmt(cumulativePayment[i])}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </CardContent>
              </Card>
            </TabsContent>

            {/* ── TAB 3: Cost Breakdown ──────────── */}
            <TabsContent value="costs" className="space-y-6">
              {/* Role rates summary */}
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm flex items-center gap-2 text-slate-900"><Users className="w-4 h-4" />Resource Rates & Allocation</CardTitle></CardHeader>
                <CardContent>
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200">
                        <TableHead className="text-[10px] text-slate-800">Role</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Rate/hr</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Total Hours</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Total Cost</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">% of Hours</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {ROLE_RATES.map((r) => {
                        const roleHrs = phases.reduce((s, p) => s + p.workPackages.reduce((a, w) => a + (w.roleHours[r.key] || 0), 0), 0);
                        return (
                          <TableRow key={r.key} className="border-slate-100">
                            <TableCell className="text-xs font-medium text-slate-800">{r.label}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-900">{fmt(r.rate)}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-900">{roleHrs}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-800">{fmt(roleHrs * r.rate)}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-800">{Math.round((roleHrs / totalHours) * 100)}%</TableCell>
                          </TableRow>
                        );
                      })}
                      <TableRow className="font-semibold border-t-2 border-slate-300">
                        <TableCell className="text-xs text-slate-900">Total</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-800">blended</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-900">{totalHours}</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-900">{fmt(totalDevCost)}</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-800">100%</TableCell>
                      </TableRow>
                    </TableBody>
                  </Table>
                </CardContent>
              </Card>

              {/* By category */}
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm text-slate-900">Cost by Category</CardTitle></CardHeader>
                <CardContent>
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200">
                        <TableHead className="text-[10px] text-slate-800">Category</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Hours</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">Cost</TableHead>
                        <TableHead className="text-[10px] text-right text-slate-800">% of Total</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {COST_CATEGORIES.map((c) => {
                        const h = hoursForCategory(c.key);
                        const cost = costForCategory(c.key);
                        return (
                          <TableRow key={c.key} className="border-slate-100">
                            <TableCell className="text-xs flex items-center gap-2 text-slate-800">
                              {(() => { const I = categoryIcon[c.key]; return <I className="w-3.5 h-3.5 text-slate-700" />; })()}
                              {c.label}
                            </TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-900">{h}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-800">{fmt(cost)}</TableCell>
                            <TableCell className="text-[10px] text-right font-mono text-slate-800">{Math.round((cost / totalDevCost) * 100)}%</TableCell>
                          </TableRow>
                        );
                      })}
                      <TableRow className="font-semibold border-t-2 border-slate-300">
                        <TableCell className="text-xs text-slate-900">Subtotal</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-900">{totalHours}</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-900">{fmt(totalDevCost)}</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-slate-800">100%</TableCell>
                      </TableRow>
                      <TableRow className="text-slate-800">
                        <TableCell className="text-xs">Contingency ({CONTINGENCY_PERCENT}%)</TableCell>
                        <TableCell className="text-[10px] text-right font-mono">—</TableCell>
                        <TableCell className="text-[10px] text-right font-mono">{fmt(contingency)}</TableCell>
                        <TableCell />
                      </TableRow>
                      <TableRow className="font-bold border-t-2 border-slate-300">
                        <TableCell className="text-xs text-blue-700">Grand Total</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-blue-700">{totalHours}</TableCell>
                        <TableCell className="text-[10px] text-right font-mono text-blue-700">{fmt(grandTotal)}</TableCell>
                        <TableCell />
                      </TableRow>
                    </TableBody>
                  </Table>
                </CardContent>
              </Card>

              {/* Per-phase breakdown */}
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm text-slate-900">Cost by Phase & Category</CardTitle></CardHeader>
                <CardContent>
                  <div className="overflow-x-auto">
                    <Table>
                      <TableHeader>
                        <TableRow className="border-slate-200">
                          <TableHead className="text-[10px] text-slate-800">Phase</TableHead>
                          {COST_CATEGORIES.map((c) => <TableHead key={c.key} className="text-[10px] text-right text-slate-800">{c.label.split(" ")[0]}</TableHead>)}
                          <TableHead className="text-[10px] text-right font-semibold text-slate-700">Total</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {phases.map((p) => {
                          return (
                            <TableRow key={p.id} className="border-slate-100">
                              <TableCell className="text-[10px] font-medium text-slate-800">{p.label}</TableCell>
                              {COST_CATEGORIES.map((c) => (
                                <TableCell key={c.key} className="text-[10px] text-right font-mono text-slate-900">
                                  {phaseCostForCategory(p, c.key) > 0 ? fmt(phaseCostForCategory(p, c.key)) : "—"}
                                </TableCell>
                              ))}
                              <TableCell className="text-[10px] text-right font-mono font-semibold text-slate-900">{fmt(phaseCost(p))}</TableCell>
                            </TableRow>
                          );
                        })}
                      </TableBody>
                    </Table>
                  </div>
                </CardContent>
              </Card>

              {/* Assumptions */}
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm text-slate-900">Assumptions & Basis of Estimate</CardTitle></CardHeader>
                <CardContent className="space-y-2 text-xs text-slate-900">
                  <p>• <strong>Senior Developer:</strong> {fmt(ROLE_RATES[0].rate)}/hour — PHP, frontend, and database development</p>
                  <p>• <strong>CTO / Technical Lead:</strong> {fmt(ROLE_RATES[1].rate)}/hour — Architecture decisions, code review, technical risk management, security oversight</p>
                  <p>• <strong>Project Manager:</strong> {fmt(ROLE_RATES[2].rate)}/hour — Sprint planning, stakeholder communication, milestone tracking, documentation coordination</p>
                  <p>• Working week: 5 days × 8 hours = 40 hours/week</p>
                  <p>• Programme duration: 48 weeks (12 months) across 6 phases of 8 weeks each</p>
                  <p>• Contingency: {CONTINGENCY_PERCENT}% applied to base cost to cover scope refinement, technical risk, and integration complexity</p>
                  <p>• Estimates derived from detailed prototype analysis — each work package scoped against the functional prototype built in Lovable</p>
                  <p>• All prices exclude VAT</p>
                  <p>• Blended team: 1 CTO (part-time oversight), 1 PM (part-time coordination), 2 Senior Developers (full-time delivery)</p>
                </CardContent>
              </Card>
            </TabsContent>

            {/* ── TAB 4: Technical Approach ──────── */}
            <TabsContent value="technical" className="space-y-6">
              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm flex items-center gap-2 text-slate-900"><ArrowRightLeft className="w-4 h-4" />Architecture Conversion</CardTitle></CardHeader>
                <CardContent className="space-y-4">
                  <div className="grid md:grid-cols-2 gap-4">
                    <div className="p-3 rounded-md border border-red-200 bg-red-50">
                      <p className="text-xs font-semibold text-red-700 mb-2">Current Stack (Prototype)</p>
                      <ul className="text-[10px] space-y-1 text-slate-900">
                        <li>• React 18 with TypeScript</li>
                        <li>• Supabase (PostgreSQL, Auth, Edge Functions, Storage)</li>
                        <li>• Vite build tooling</li>
                        <li>• Tailwind CSS + shadcn/ui</li>
                        <li>• Client-side rendering (SPA)</li>
                      </ul>
                    </div>
                    <div className="p-3 rounded-md border border-blue-200 bg-blue-50">
                      <p className="text-xs font-semibold text-blue-700 mb-2">Target Stack (Production)</p>
                      <ul className="text-[10px] space-y-1 text-slate-900">
                        <li>• PHP 8.3</li>
                        <li>• MySQL 8 relational database</li>
                        <li>• HTML5 Blade templates + Tailwind CSS</li>
                        <li>• JSON REST APIs for async features</li>
                        <li>• Server-side rendering with Alpine.js interactivity</li>
                        <li>• Redis caching, Queue, Horizon</li>
                      </ul>
                    </div>
                  </div>
                </CardContent>
              </Card>

              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm flex items-center gap-2 text-slate-900"><Layers className="w-4 h-4" />Module Conversion Strategy</CardTitle></CardHeader>
                <CardContent>
                  <div className="space-y-3">
                    {[
                      { module: "Authentication & RBAC", approach: "Breeze/Fortify for auth scaffolding, Spatie Permission for RBAC, custom OTP via Mail.", phase: 1 },
                      { module: "Course Management", approach: "Eloquent models with sluggable trait, Media Library for images, Blade CRUD views with Livewire for inline editing.", phase: 2 },
                      { module: "Availability Engine", approach: "Custom service class replacing Supabase Edge Functions. Pure PHP date arithmetic with Carbon library, bank holiday integration.", phase: 2 },
                      { module: "Booking & Payments", approach: "Cashier for Stripe integration, replacing client-side Stripe Elements with server-side payment intents. Queue-based email dispatch.", phase: 3 },
                      { module: "Multi-Tenancy", approach: "Stancl/Tenancy package or custom middleware for subdomain resolution. Tenant-scoped Eloquent global scopes. Dynamic Blade layout theming.", phase: 4 },
                      { module: "Company Portal", approach: "Dedicated route group with company-scoped middleware. Blade dashboards replacing React components. Credit system as a service class.", phase: 4 },
                      { module: "Compliance & Certificates", approach: "Server-side certificate tracking with scheduled Artisan commands for expiry monitoring. DomPDF for certificate/form PDF generation.", phase: 5 },
                      { module: "AI Services", approach: "PHP HTTP client wrapping AI vision APIs. Queue-based processing for video frame analysis. Results stored in MySQL with JSON columns.", phase: 5 },
                    ].map((m) => (
                      <div key={m.module} className="flex items-start gap-3 p-2 rounded-md hover:bg-slate-50">
                        <Badge variant="outline" className="text-[9px] shrink-0 mt-0.5 border-slate-300">P{m.phase}</Badge>
                        <div>
                          <p className="text-xs font-medium text-slate-800">{m.module}</p>
                          <p className="text-[10px] text-slate-800 mt-0.5">{m.approach}</p>
                        </div>
                      </div>
                    ))}
                  </div>
                </CardContent>
              </Card>

              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm flex items-center gap-2 text-slate-900"><AlertTriangle className="w-4 h-4" />Risk Register</CardTitle></CardHeader>
                <CardContent>
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200">
                        <TableHead className="text-[10px] text-slate-800">Risk</TableHead>
                        <TableHead className="text-[10px] text-slate-800">Impact</TableHead>
                        <TableHead className="text-[10px] text-slate-800">Likelihood</TableHead>
                        <TableHead className="text-[10px] text-slate-800">Mitigation</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {[
                        { risk: "Schema migration data loss", impact: "High", likelihood: "Low", mitigation: "Automated migration scripts with rollback, staging validation, parallel-run period" },
                        { risk: "Stripe API version incompatibility", impact: "Medium", likelihood: "Low", mitigation: "Pin Stripe API version, comprehensive payment test suite, sandbox testing" },
                        { risk: "Multi-tenancy performance degradation", impact: "High", likelihood: "Medium", mitigation: "Database indexing strategy, Redis caching, query profiling from Phase 2 onwards" },
                        { risk: "AI service API availability", impact: "Medium", likelihood: "Medium", mitigation: "Queue-based async processing, graceful degradation, fallback to manual input" },
                        { risk: "Scope creep from prototype features", impact: "High", likelihood: "High", mitigation: "Frozen prototype baseline, formal change request process, contingency budget" },
                        { risk: "Browser compatibility (Blade vs React)", impact: "Low", likelihood: "Medium", mitigation: "Progressive enhancement, E2E cross-browser testing, polyfill strategy" },
                      ].map((r, i) => (
                        <TableRow key={i} className="border-slate-100">
                          <TableCell className="text-[10px] font-medium text-slate-800">{r.risk}</TableCell>
                          <TableCell><Badge variant={r.impact === "High" ? "destructive" : "secondary"} className="text-[9px]">{r.impact}</Badge></TableCell>
                          <TableCell><Badge variant="outline" className="text-[9px] border-slate-300">{r.likelihood}</Badge></TableCell>
                          <TableCell className="text-[10px] max-w-[250px] text-slate-900">{r.mitigation}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </CardContent>
              </Card>

              <Card className="border-slate-200 shadow-sm">
                <CardHeader><CardTitle className="text-sm flex items-center gap-2 text-slate-900"><Lightbulb className="w-4 h-4" />Innovation Narrative (R&D Justification)</CardTitle></CardHeader>
                <CardContent className="space-y-3 text-xs text-slate-900">
                  <p><strong>Technological Uncertainty:</strong> This project addresses significant technological uncertainty in converting an AI-assisted rapid prototype into a production-grade, multi-tenant training management platform. The prototype, built using Lovable's AI-powered development environment, demonstrates functional requirements but cannot be directly deployed as a commercial product due to architectural constraints of the prototyping framework.</p>
                  <p><strong>Advance in Technology:</strong> The programme seeks to advance the state of the art in several areas: (1) AI-powered workplace risk assessment using computer vision to analyse site photographs and video, identifying hazards and generating compliance documentation; (2) Augmented reality remote mentoring for field engineers, enabling real-time expert guidance during complex utility installations; (3) Automated compliance matrix management across a multi-company training ecosystem with dynamic skills gap analysis.</p>
                  <p><strong>Competent Professional:</strong> These challenges cannot be readily resolved by a competent professional in the field. The integration of AI vision services with real-time risk scoring, combined with multi-tenant data isolation and regulatory compliance requirements (NRSWA, EUSR, Smart Metering), requires novel approaches to architecture, data security, and user experience design.</p>
                  <p><strong>R&D Activities:</strong> The programme includes systematic investigation through prototyping (Phase 1-2), iterative development with controlled experimentation (Phase 3-4), and validation through structured testing (Phase 5-6). Each phase produces measurable deliverables that advance understanding of the technical challenges and inform subsequent development decisions.</p>
                </CardContent>
              </Card>
            </TabsContent>
          </Tabs>
        </main>
      </div>
    </div>
  );
};

export default BuildProgrammePage;
