"use client" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { BrainCircuit, Play, CheckCircle2, Download, Filter, Lock, FileText, Eye, ShieldAlert, X, Sparkles } from "lucide-react" import { useEffect, useState } from "react" import Link from "next/link" import { useActiveUser } from "@/hooks/useActiveUser" export default function PrepPilotAIPage() { const { user, userId } = useActiveUser() const [dpps, setDpps] = useState([]) const [attempts, setAttempts] = useState([]) const [loading, setLoading] = useState(true) const [dateFilter, setDateFilter] = useState("") const [selectedPdfDpp, setSelectedPdfDpp] = useState(null) useEffect(() => { async function fetchDpps() { if (!user) return; // Wait for user to be available try { const pattern = user.target_exam || "JEE_Main"; // Also fetch from the correct Next.js proxied route instead of localhost:8000 const res = await fetch(`/api/tests?type=DPS&exam_pattern=${pattern}`); if (res.ok) { const data = await res.json() setDpps(data) } if (userId) { const attemptsRes = await fetch(`/api/users/${userId}/attempts`); if (attemptsRes.ok) { const attemptsData = await attemptsRes.json(); setAttempts(attemptsData); } } } catch (err) { console.error("Failed to fetch DPPs", err) } finally { setLoading(false) } } fetchDpps() }, [user]) const getDifficultyColor = (diff: string) => { switch(diff) { case 'Easy': return 'text-emerald-500 bg-emerald-500/10 border-emerald-500/20'; case 'Medium': return 'text-amber-500 bg-amber-500/10 border-amber-500/20'; case 'Hard': return 'text-destructive bg-destructive/10 border-destructive/20'; default: return 'text-primary bg-primary/10 border-primary/20'; } } const attemptsByTest = attempts.reduce((acc, curr) => { // Isolate analytics to first attempt only - ignore retakes if (curr.is_retake) return acc; if (!acc[curr.source_id] || acc[curr.source_id].score < curr.score) { acc[curr.source_id] = curr; } return acc; }, {} as Record); const filteredDpps = dpps.filter(dpp => { if (dateFilter) { if (!dpp.scheduled_date) return false; const scheduledDate = new Date(dpp.scheduled_date).toISOString().split('T')[0]; if (scheduledDate !== dateFilter) return false; } return true; }); const formatDate = (dateStr: string) => { return new Date(dateStr).toLocaleDateString("en-US", { year: 'numeric', month: 'short', day: 'numeric' }); } const getPdfUrl = (title: string) => { const t = title.toLowerCase(); if (t.includes('phys')) return '/dpps/dps-phy-ch4-20260707.pdf#toolbar=0&navpanes=0&scrollbar=0'; if (t.includes('chem')) return '/dpps/dps-che-ch4-20260707.pdf#toolbar=0&navpanes=0&scrollbar=0'; if (t.includes('math')) return '/dpps/dps-mth-ch4-20260707.pdf#toolbar=0&navpanes=0&scrollbar=0'; if (t.includes('bio')) return '/dpps/dps-bio-ch4-20260707.pdf#toolbar=0&navpanes=0&scrollbar=0'; return '/dpps/dps-phy-ch4-20260707.pdf#toolbar=0&navpanes=0&scrollbar=0'; }; // Strip ugly ExamEnum. prefix from seeded test titles const cleanTitle = (title: string) => title.replace(/\s*\(ExamEnum\.[^)]+\)/, ''); return (

PrepPilot AI & CBT Simulator

Select an interactive Target DPP to launch the AI-powered CBT examination simulator.

setDateFilter(e.target.value)} className="px-3 py-1.5 bg-background border border-border rounded-lg text-xs font-bold focus:ring-2 focus:ring-[#00F0FF] outline-none text-muted-foreground mr-2" /> Difficulty: {['Mixed', 'Easy', 'Medium', 'Hard'].map((diff) => ( ))}
Pro
{loading ? (
Loading AI-generated DPPs...
) : filteredDpps.length === 0 ? (
No DPPs available for the selected criteria.
) : filteredDpps.map((dpp, i) => { // Calculate total questions dynamically from sections let count = 0; if (dpp.sections) { Object.values(dpp.sections).forEach((s: any) => { count += (s.questions?.length || 0) }); } const attempt = attemptsByTest[dpp.id]; const isAttempted = !!attempt; // Date logic const now = new Date(); const scheduledTime = dpp.scheduled_date ? new Date(dpp.scheduled_date) : now; const endTime = dpp.end_date ? new Date(dpp.end_date) : null; const isUpcoming = scheduledTime > now; const isExpired = endTime ? now > endTime : false; return (
{isAttempted ? :
}
{user?.target_exam?.replace("_", " ") || "JEE/NEET"} • {dpp.difficulty} Level {isUpcoming ? ( <> • Upcoming ) : isExpired ? ( <> • Expired ) : null}

{cleanTitle(dpp.title)} {dpp.difficulty}

{count} Questions • {dpp.total_time} mins {dpp.scheduled_date && ( {isUpcoming ? `Available on ${formatDate(dpp.scheduled_date)}` : isExpired ? `Expired on ${formatDate(dpp.end_date!)}` : 'Available Now'} )}
{isUpcoming ? ( ) : isExpired && !isAttempted ? ( ) : isAttempted ? ( <> {!isExpired && ( )} ) : ( )}
)})}
{/* ── PROTECTED PDF READER MODAL (FREE TIER) ── */} {selectedPdfDpp && (
{/* Modal Header */}

{selectedPdfDpp.title} Protected In-App PDF View

{selectedPdfDpp.difficulty} Level • {user?.target_exam?.replace("_", " ") || "JEE/NEET"} Practice Sheet

{/* Security Notice Banner */}
Read-Only Mode (Free Tier) — Downloads, text copying, and sharing are restricted.
{/* Protected PDF Document Sheet Content (select-none) */}
e.preventDefault()} className="flex-1 w-full h-full min-h-[60vh] select-none bg-[#525659]" >
{/* Modal Footer */}
📄 PragatiVeer Protected PDF Reader v2.0
)}
) }