import { Award, BookOpen, Check, ChevronLeft, ChevronRight, ClipboardList, Clock3, Crown, FileDown, LockKeyhole, Menu, Printer, Search, X } from 'lucide-react';
import React from 'react';
import { LearnitiveAccountPopover } from '../../components/account-popover';
import { getAuthState, type SaasAuthState } from '../../saas/saas-api';
import { usePageMetadata } from '../../saas/page-metadata';
import { enrollLearnCourse, getLearnAssignment, getLearnCertificate, getLearnCourse, getLearnCourseFiles, getLearnLesson, getLearnQuiz, listLearnCourses, saveItemProgress, startLearnQuizAttempt, submitLearnQuiz, submitLearnAssignment, uploadLearnAssignmentFile } from '../api';
import { LessonRenderer } from '../blocks/lesson-renderer';
import type { LearnCertificate, LearnCourseSummary, LearnMedia, PublicLearnAssignment, PublicLearnCourse, PublicLearnLesson, PublicLearnQuiz } from '../types';

function duration(minutes:number){if(!minutes)return'Self-paced';if(minutes<60)return`${minutes} min`;const h=Math.floor(minutes/60),m=minutes%60;return m?`${h}h ${m}m`:`${h}h`;}

function lockMessage(reason?:string){
  if(reason==='sequential')return 'Complete the earlier course items to unlock this content.';
  if(reason==='prerequisite')return 'Complete the course prerequisites to unlock this content.';
  if(reason==='upcoming')return 'This course is not open yet.';
  if(reason==='expired')return 'This course access period has ended.';
  if(reason==='drip')return 'This item is scheduled to unlock later.';
  if(reason==='enrollment')return 'Enroll in the course to open this content.';
  if(reason==='pro')return 'This content requires Learnitive Pro.';
  return 'This content is currently locked.';
}
function startLabel(course:PublicLearnCourse,busy:boolean){if(course.lockReason==='pro')return'Upgrade to start';if(course.lockReason==='prerequisite')return'Complete prerequisites';if(course.lockReason==='upcoming')return'Coming soon';if(course.lockReason==='expired')return'Course expired';if(busy)return'Opening…';if(course.progressPercent>=100)return'Review course';return course.progressPercent>0?'Continue course':'Start course';}
function CourseCard({course}:{course:LearnCourseSummary}){return <a href={`/learn/${encodeURIComponent(course.slug)}`} className="interactive-learn-course-card">{course.coverUrl?<img src={course.coverUrl} alt=""/>:<div className="interactive-learn-cover-placeholder"><BookOpen className="size-8"/></div>}<div className="interactive-learn-course-card-body"><div className="interactive-learn-card-meta"><span>{course.level}</span><span>{duration(course.estimatedMinutes)}</span>{course.accessTier==='pro'?<span className="interactive-learn-pro"><Crown className="size-3"/> Pro</span>:<span>Free</span>}</div><h2>{course.title}</h2><p>{course.shortDescription}</p><footer><span>{course.itemCount} lessons</span>{course.progressPercent>0?<span>{course.progressPercent}% complete</span>:<span>View course</span>}</footer>{course.progressPercent>0?<div className="interactive-learn-progress-bar"><i style={{width:`${course.progressPercent}%`}}/></div>:null}</div></a>}

export function LearnCatalogPage(){const [courses,setCourses]=React.useState<LearnCourseSummary[]>([]);const [query,setQuery]=React.useState('');const [error,setError]=React.useState('');const [loading,setLoading]=React.useState(true);React.useEffect(()=>{let active=true;setLoading(true);void listLearnCourses(query).then(rows=>{if(active){setCourses(rows);setError('')}}).catch(reason=>{if(active)setError(reason instanceof Error?reason.message:String(reason))}).finally(()=>{if(active)setLoading(false)});return()=>{active=false}},[query]);const featured=courses.filter(c=>c.featured);const continuing=courses.filter(c=>c.progressPercent>0&&c.progressPercent<100);return <main className="interactive-learn-catalog"><section className="interactive-page-container interactive-learn-catalog-hero"><span className="interactive-eyebrow">Learnitive Learn</span><h1 className="interactive-display">Learn by writing, researching and practising.</h1><p>Structured courses combine documents, research workflows, video, checkpoints and hands-on exercises inside Learnitive.</p><label className="interactive-learn-search"><Search className="size-5"/><input value={query} onChange={event=>setQuery(event.currentTarget.value)} placeholder="Search courses"/></label></section>{featured.length?<section className="interactive-page-container interactive-learn-course-section"><header><h2>Featured courses</h2><p>Start with a guided path.</p></header><div className="interactive-learn-course-grid">{featured.map(course=><CourseCard key={course.id} course={course}/>)}</div></section>:null}{continuing.length?<section className="interactive-page-container interactive-learn-course-section"><header><h2>Continue learning</h2></header><div className="interactive-learn-course-grid">{continuing.map(course=><CourseCard key={course.id} course={course}/>)}</div></section>:null}<section className="interactive-page-container interactive-learn-course-section"><header><h2>All courses</h2></header>{error?<p className="interactive-error-copy">{error}</p>:null}{loading?<p>Loading courses…</p>:courses.length?<div className="interactive-learn-course-grid">{courses.map(course=><CourseCard key={course.id} course={course}/>)}</div>:<div className="interactive-empty-state"><BookOpen className="size-7"/><h2>No courses yet</h2><p>The new Learn library is ready for courses created in Admin.</p></div>}</section></main>}

function Curriculum({course}:{course:PublicLearnCourse}){return <div className="interactive-learn-curriculum">{course.sections.map(section=><section key={section.id}><header><div><h3>{section.title}</h3>{section.description?<p>{section.description}</p>:null}</div><span>{section.items.length} items</span></header><div>{section.items.map(item=>{const content=<><span className="interactive-learn-item-icon">{item.completed?<Check className="size-4"/>:item.locked?<LockKeyhole className="size-4"/>:<BookOpen className="size-4"/>}</span><span><strong>{item.title}</strong><small>{item.type} · {duration(item.estimatedMinutes)}</small></span><ChevronRight className="size-4"/></>;return item.locked?<span key={item.id} className="is-locked" aria-disabled="true">{content}</span>:<a key={item.id} href={`/learn/${encodeURIComponent(course.slug)}/${encodeURIComponent(item.slug)}`}>{content}</a>})}</div></section>)}</div>}

export function LearnCoursePage({slug}:{slug:string}){
  const [course,setCourse]=React.useState<PublicLearnCourse>();
  const [materials,setMaterials]=React.useState<LearnMedia[]>([]);
  const [error,setError]=React.useState('');
  const [busy,setBusy]=React.useState(false);
  usePageMetadata({ title: course ? `${course.title} Course` : 'Learn', description: course?.shortDescription || 'Learnitive interactive course.', pathname: `/learn/${encodeURIComponent(slug)}`, image: course?.coverUrl || null, enabled: Boolean(course) });
  React.useEffect(()=>{let active=true;void getLearnCourse(slug).then(value=>{if(!active)return;setCourse(value);if(value.pageSettings.showMaterials)void getLearnCourseFiles(slug).then(files=>{if(active)setMaterials(files)}).catch(()=>undefined)}).catch(reason=>{if(active)setError(reason instanceof Error?reason.message:String(reason))});return()=>{active=false}},[slug]);
  if(error)return <section className="interactive-page-container interactive-page-heading"><h1>Course unavailable</h1><p>{error}</p></section>;
  if(!course)return <section className="interactive-page-container interactive-page-heading"><p>Loading course…</p></section>;
  const courseItems=course.sections.flatMap(section=>section.items);
  const first=courseItems.find(item=>!item.locked&&!item.completed)||courseItems.find(item=>!item.locked);
  const proUpgrade=course.locked&&course.lockReason==='pro';
  const completed=course.progressPercent>=100;
  const startCourse=async()=>{if(!first)return;setBusy(true);try{await enrollLearnCourse(course.slug).catch(()=>undefined);window.location.href=`/learn/${encodeURIComponent(course.slug)}/${encodeURIComponent(first.slug)}`;}finally{setBusy(false)}};
  const page=course.pageSettings;
  const primaryAction=proUpgrade
    ?<a className="interactive-button interactive-button-primary interactive-learn-course-primary-action" href="/pricing"><Crown className="size-4"/> Upgrade to start</a>
    :<button type="button" className="interactive-button interactive-button-primary interactive-learn-course-primary-action" disabled={!first||busy||course.locked} onClick={()=>void startCourse()}>{startLabel(course,busy)}</button>;
  return <main className={`interactive-learn-course-page is-${page.layout}`}>
    <section className="interactive-learn-course-hero"><div className="interactive-page-container"><div className="interactive-learn-course-hero-copy"><div className="interactive-learn-course-kicker"><span className="interactive-eyebrow">{course.level} course</span>{course.accessTier==='pro'?<span className="interactive-learn-access-pill"><Crown className="size-3"/> Pro</span>:<span className="interactive-learn-access-pill">Free</span>}</div><h1 className="interactive-display">{course.title}</h1><p>{course.shortDescription}</p><div className="interactive-learn-course-facts"><span><BookOpen className="size-4"/>{course.itemCount} items</span><span><Clock3 className="size-4"/>{duration(course.estimatedMinutes)}</span><span><Check className="size-4"/>Self-paced</span></div>{course.locked&&course.lockReason!=='pro'&&course.lockReason!=='prerequisite'?<p className="interactive-learn-course-lock-note">{lockMessage(course.lockReason)}{course.availableFrom&&course.lockReason==='upcoming'?` Opens ${new Date(course.availableFrom).toLocaleString()}.`:''}</p>:null}</div></div></section>
    <section className="interactive-page-container interactive-learn-course-columns">
      <div className="interactive-learn-course-content">
        <section className="interactive-learn-course-copy interactive-learn-course-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Overview</span><h2>About this course</h2></div></div><p>{String(course.description.text||course.shortDescription||'')}</p></section>
        {page.showOutcomes&&course.outcomes.length?<section className="interactive-learn-outcomes interactive-learn-course-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Course outcomes</span><h2>What you'll learn</h2></div></div><div className="interactive-learn-outcomes-grid">{course.outcomes.map(item=><span key={item}><Check className="size-4"/>{item}</span>)}</div></section>:null}
        {course.prerequisites?.length?<section className="interactive-learn-requirements interactive-learn-course-section is-prerequisites"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Before you begin</span><h2>Prerequisites</h2></div></div><ul>{course.prerequisites.map(item=><li key={item.id}>{item.completed?<Check className="size-4"/>:<LockKeyhole className="size-4"/>}<div><a href={`/learn/${encodeURIComponent(item.slug)}`}>{item.title}</a><span>{item.progressPercent||0}% complete · {item.passingPercentage||100}% required</span></div></li>)}</ul></section>:null}
        {course.notice?.text?<aside className="interactive-learn-course-notice"><strong>{String(course.notice.title||'Course notice')}</strong><p>{String(course.notice.text)}</p></aside>:null}
        <section className="interactive-learn-course-section interactive-learn-course-curriculum-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Course content</span><h2>Course curriculum</h2></div><small>{course.sections.length} {course.sections.length===1?'section':'sections'} · {course.itemCount} items</small></div><Curriculum course={course}/></section>
        {page.showRequirements&&course.requirements.length?<section className="interactive-learn-requirements interactive-learn-course-section is-course-requirements"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Recommended</span><h2>Requirements</h2></div></div><ul>{course.requirements.map(item=><li key={item}><Check className="size-4"/><span>{item}</span></li>)}</ul></section>:null}
        {course.customFields.length?<section className="interactive-learn-course-details interactive-learn-course-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">At a glance</span><h2>Course details</h2></div></div><dl>{course.customFields.map(field=><div key={`${field.label}-${field.value}`}><dt>{field.label}</dt><dd>{field.value}</dd></div>)}</dl></section>:null}
        {page.showMaterials&&materials.length?<section className="interactive-learn-course-materials interactive-learn-course-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Downloads</span><h2>Course materials</h2></div></div>{materials.map(file=><a key={file.id} href={file.url} target="_blank" rel="noreferrer"><FileDown className="size-4"/><span><strong>{file.originalName}</strong><small>{file.mimeType}</small></span></a>)}</section>:null}
        {page.showFaq&&course.faqs.length?<section className="interactive-learn-faq interactive-learn-course-section"><div className="interactive-learn-course-section-heading"><div><span className="interactive-eyebrow">Need to know</span><h2>FAQ</h2></div></div>{course.faqs.map(faq=><details key={faq.id}><summary>{faq.question}</summary><p>{String(faq.answer.text||'')}</p></details>)}</section>:null}
      </div>
      <aside className="interactive-learn-course-start-card">
        {course.coverUrl?<img src={course.coverUrl} alt=""/>:<div className="interactive-learn-cover-placeholder"><BookOpen className="size-8"/></div>}
        <div className="interactive-learn-course-start-card-body">
          <div className="interactive-learn-course-start-card-heading"><span className={`interactive-learn-start-access${course.accessTier==='pro'?' is-pro':''}`}>{course.accessTier==='pro'?<><Crown className="size-3"/> Pro course</>:'Free course'}</span><h2>{proUpgrade?'Unlock this course':completed?'Course completed':course.progressPercent>0?'Continue where you left off':'Start learning'}</h2><p>{proUpgrade?'Upgrade to Pro to open this course and continue learning across the Pro library.':'Learn at your own pace. Your progress is saved automatically.'}</p></div>
          {primaryAction}
          {course.progressPercent>0?<div className="interactive-learn-course-progress-summary"><div><strong>{course.progressPercent}% complete</strong><span>{course.completedCount} of {course.itemCount} items</span></div><div className="interactive-learn-progress-bar"><i style={{width:`${course.progressPercent}%`}}/></div></div>:null}
          <div className="interactive-learn-course-includes"><span><BookOpen className="size-4"/><b>{course.itemCount}</b> course items</span><span><Clock3 className="size-4"/><b>{duration(course.estimatedMinutes)}</b> total pace</span><span><Check className="size-4"/><b>Progress</b> saved automatically</span>{course.certificateEnabled?<span><Award className="size-4"/><b>Certificate</b> on completion</span>:null}</div>
          {course.certificateEnabled&&completed?<a className="interactive-button interactive-button-secondary interactive-learn-certificate-link" href={`/learn/${encodeURIComponent(course.slug)}/certificate`}><Award className="size-4"/> View certificate</a>:null}
        </div>
      </aside>
    </section>
  </main>;
}

export function LearnCertificatePage({slug}:{slug:string}){
  const [certificate,setCertificate]=React.useState<LearnCertificate>();
  const [error,setError]=React.useState('');
  usePageMetadata({ title: certificate ? `${certificate.courseTitle} Certificate` : 'Course Certificate', description: certificate ? `Learnitive course certificate for ${certificate.courseTitle}.` : 'Learnitive course certificate.', pathname: `/learn/${encodeURIComponent(slug)}/certificate`, robots: 'noindex,nofollow', enabled: Boolean(certificate) });
  React.useEffect(()=>{let active=true;void getLearnCertificate(slug).then(value=>{if(active)setCertificate(value)}).catch(reason=>{if(active)setError(reason instanceof Error?reason.message:String(reason))});return()=>{active=false}},[slug]);
  if(error)return <main className="interactive-learn-certificate-page"><section className="interactive-page-container interactive-page-heading"><Award className="size-8"/><h1>Certificate unavailable</h1><p>{error==='authentication_required'?'Sign in to view your certificate.':error==='learn_course_completion_required'?'Complete the course to unlock your certificate.':error}</p><a className="interactive-button interactive-button-secondary" href={`/learn/${encodeURIComponent(slug)}`}>Return to course</a></section></main>;
  if(!certificate)return <div className="interactive-learn-player-loading">Loading certificate…</div>;
  return <main className="interactive-learn-certificate-page"><div className="interactive-learn-certificate-actions"><a href={`/learn/${encodeURIComponent(slug)}`}><ChevronLeft className="size-4"/> Course</a><button type="button" className="interactive-button interactive-button-primary" onClick={()=>window.print()}><Printer className="size-4"/> Print certificate</button></div><article className="interactive-learn-certificate"><div className="interactive-learn-certificate-mark"><Award className="size-10"/></div><span>Learnitive</span><h1>{certificate.title}</h1><p>This certifies that</p><strong>{certificate.learnerName}</strong><p>has successfully completed</p><h2>{certificate.courseTitle}</h2>{certificate.subtitle?<p>{certificate.subtitle}</p>:null}<footer><div><small>Completed</small><b>{certificate.completedAt?new Date(certificate.completedAt).toLocaleDateString():''}</b></div><div><small>Course</small><b>{certificate.courseSlug}</b></div></footer></article></main>;
}

function PlayerCurriculum({course,active,onClose}:{course:PublicLearnCourse;active:string;onClose?:()=>void}){return <aside className="interactive-learn-player-sidebar"><header><div><strong>{course.title}</strong><small>{course.progressPercent}% complete</small></div>{onClose?<button type="button" aria-label="Close curriculum" onClick={onClose}><X className="size-5"/></button>:null}</header><div className="interactive-learn-progress-bar"><i style={{width:`${course.progressPercent}%`}}/></div><nav>{course.sections.map(section=><details key={section.id} open><summary>{section.title}<span>{section.items.length}</span></summary>{section.items.map(item=>{const content=<><span>{item.completed?<Check className="size-4"/>:item.locked?<LockKeyhole className="size-4"/>:<BookOpen className="size-4"/>}</span><span>{item.title}</span><small>{duration(item.estimatedMinutes)}</small></>;return item.locked?<span key={item.id} className={`interactive-learn-player-item${item.slug===active?' is-active':''} is-locked`} aria-disabled="true">{content}</span>:<a key={item.id} className={`interactive-learn-player-item${item.slug===active?' is-active':''}`} href={`/learn/${encodeURIComponent(course.slug)}/${encodeURIComponent(item.slug)}`} onClick={()=>onClose?.()}>{content}</a>})}</details>)}</nav></aside>}

function QuizPlayer({quiz,onPassed}:{quiz:PublicLearnQuiz;onPassed:()=>void}){
  const [answers,setAnswers]=React.useState<Record<string,unknown>>({});
  const answersRef=React.useRef<Record<string,unknown>>({});
  const [busy,setBusy]=React.useState(false);
  const [attempt,setAttempt]=React.useState<{id:number;attemptNumber:number;startedAt:string;expiresAt:string|null;timeLimitSeconds:number|null;questions?:PublicLearnQuiz['questions']}>();
  const [attemptQuestions,setAttemptQuestions]=React.useState(quiz.questions||[]);
  const [remaining,setRemaining]=React.useState<number|null>(null);
  const [attemptError,setAttemptError]=React.useState('');
  const [result,setResult]=React.useState<{scorePercentage:number;passed:boolean;feedback:Array<Record<string,unknown>>}>();
  const submittedRef=React.useRef(false);
  const updateAnswers=React.useCallback((next:Record<string,unknown>)=>{answersRef.current=next;setAnswers(next)},[]);
  const submit=React.useCallback(async(auto=false)=>{if(busy||result||!attempt||submittedRef.current)return;submittedRef.current=true;setBusy(true);try{const value=await submitLearnQuiz(quiz.course.slug,quiz.slug,answersRef.current,attempt.id);setResult(value);if(value.passed)onPassed();}catch(reason){setAttemptError(reason instanceof Error?reason.message:String(reason));if(!auto)submittedRef.current=false}finally{setBusy(false)}},[attempt,busy,onPassed,quiz.course.slug,quiz.slug,result]);
  React.useEffect(()=>{if(quiz.locked||!(quiz.questions||[]).length)return;let active=true;void startLearnQuizAttempt(quiz.course.slug,quiz.slug).then(value=>{if(active){setAttempt(value);if(value.questions?.length)setAttemptQuestions(value.questions);setAttemptError('')}}).catch(reason=>{if(active)setAttemptError(reason instanceof Error?reason.message:String(reason))});return()=>{active=false}},[quiz.course.slug,quiz.locked,quiz.questions,quiz.slug]);
  React.useEffect(()=>{if(!attempt?.expiresAt||result)return;const tick=()=>{const seconds=Math.max(0,Math.ceil((Date.parse(attempt.expiresAt!)-Date.now())/1000));setRemaining(seconds);if(seconds===0&&!submittedRef.current)void submit(true)};tick();const timer=window.setInterval(tick,1000);return()=>window.clearInterval(timer)},[attempt?.expiresAt,result,submit]);
  if(quiz.locked)return <div className="interactive-learn-player-lock"><LockKeyhole className="size-8"/><h1>{quiz.title}</h1><p>{lockMessage(quiz.lockReason)}</p>{quiz.lockReason==='pro'?<a className="interactive-button interactive-button-primary" href="/pricing">View Pro</a>:null}</div>;
  const questions=attemptQuestions.length?attemptQuestions:(quiz.questions||[]);
  return <article className="interactive-learn-quiz-player"><span className="interactive-eyebrow">Quiz</span><h1>{quiz.title}</h1><div className="interactive-learn-quiz-meta"><span>Pass mark: {quiz.passingPercentage}%</span>{attempt?<span>Attempt {attempt.attemptNumber}{quiz.attemptLimit?` of ${quiz.attemptLimit}`:''}</span>:null}{remaining!==null?<span className={remaining<=30?'is-urgent':''}>Time left: {Math.floor(remaining/60)}:{String(remaining%60).padStart(2,'0')}</span>:null}</div>{attemptError?<div className="interactive-learn-feedback is-incorrect"><strong>Quiz unavailable</strong><p>{attemptError==='learn_quiz_attempt_limit'?'You have used all allowed attempts.':attemptError==='learn_quiz_time_limit'?'The quiz time limit has expired.':attemptError}</p></div>:null}{questions.map((question,index)=>{const prompt=question.prompt;const baseOptions=Array.isArray(prompt.options)?prompt.options.map(String):[];const options=question.type==='true_false'?['True','False']:baseOptions;const optionValues=question.type==='true_false'?['true','false']:(Array.isArray(prompt.optionValues)?prompt.optionValues.map(Number):options.map((_,i)=>i));return <section key={question.id} className="interactive-learn-quiz-question"><span>Question {index+1}</span><h3>{String(prompt.text||'')}</h3>{options.length?<div className="interactive-learn-checkpoint-options">{options.map((option,optionIndex)=><label key={`${question.id}-${optionIndex}`}><input disabled={Boolean(result)||remaining===0} type={question.type==='multiple_choice'?'checkbox':'radio'} name={`quiz-${question.id}`} checked={question.type==='multiple_choice'?Array.isArray(answers[String(question.id)])&&(answers[String(question.id)] as Array<number|string>).includes(optionValues[optionIndex]):answers[String(question.id)]===optionValues[optionIndex]} onChange={()=>{const optionValue=optionValues[optionIndex];if(question.type==='multiple_choice'){const values=Array.isArray(answersRef.current[String(question.id)])?answersRef.current[String(question.id)] as Array<number|string>:[];updateAnswers({...answersRef.current,[String(question.id)]:values.includes(optionValue)?values.filter(value=>value!==optionValue):[...values,optionValue]})}else updateAnswers({...answersRef.current,[String(question.id)]:optionValue})}}/><span>{option}</span></label>)}</div>:<textarea disabled={Boolean(result)||remaining===0} value={String(answers[String(question.id)]||'')} onChange={event=>{const value=event.currentTarget.value;updateAnswers({...answersRef.current,[String(question.id)]:value})}}/>}</section>})}<button className="interactive-button interactive-button-primary" type="button" disabled={busy||!questions.length||!attempt||Boolean(result)||remaining===0||Boolean(attemptError)} onClick={()=>void submit(false)}>{busy?'Submitting…':'Submit quiz'}</button>{result?<div className={result.passed?'interactive-learn-feedback is-correct':'interactive-learn-feedback is-incorrect'}><strong>{result.passed?'Passed':'Not passed yet'}</strong><p>Score: {result.scorePercentage}%</p>{result.feedback.some(item=>'correctAnswer' in item||'explanation' in item)?<div className="interactive-learn-quiz-feedback-list">{result.feedback.map((item,index)=><div key={index}><b>Question {index+1}: {item.correct?'Correct':'Review'}</b>{'correctAnswer' in item?<p>Correct answer: {Array.isArray(item.correctAnswer)?item.correctAnswer.join(', '):String(item.correctAnswer??'')}</p>:null}{'explanation' in item?<p>{String((item.explanation as Record<string,unknown>)?.text||'')}</p>:null}</div>)}</div>:null}</div>:null}</article>;
}

function AssignmentPlayer({assignment,onCompleted}:{assignment:PublicLearnAssignment;onCompleted:()=>void}){const [text,setText]=React.useState('');const [projectId,setProjectId]=React.useState('');const [projectName,setProjectName]=React.useState('');const [file,setFile]=React.useState<File|null>(null);const [upload,setUpload]=React.useState<{percent:number;loaded:number;total:number}|null>(null);const [submission,setSubmission]=React.useState(assignment.submission||null);const [busy,setBusy]=React.useState(false);const [error,setError]=React.useState('');React.useEffect(()=>{setSubmission(assignment.submission||null)},[assignment.submission]);React.useEffect(()=>{if(submission?.status==='accepted')onCompleted()},[submission?.status,onCompleted]);if(assignment.locked)return <div className="interactive-learn-player-lock"><LockKeyhole className="size-8"/><h1>{assignment.title}</h1><p>{lockMessage(assignment.lockReason)}</p></div>;const manual=assignment.submissionMode==='manual-complete',canSubmit=!submission||submission.status==='rejected'||assignment.settings.allowResubmission!==false;const submit=async()=>{if(!canSubmit||busy)return;setBusy(true);setError('');try{let mediaId:number|undefined;if(assignment.submissionMode==='file'){if(!file)throw new Error('Choose a file first.');const media=await uploadLearnAssignmentFile(assignment.course.slug,assignment.slug,file,value=>setUpload(value));mediaId=media.id}const value=await submitLearnAssignment(assignment.course.slug,assignment.slug,assignment.submissionMode==='text'?{text}:assignment.submissionMode==='file'?{mediaId}:{project:{projectId,name:projectName}});setSubmission(value);if(value.status==='accepted')onCompleted()}catch(reason){setError(reason instanceof Error?reason.message:String(reason))}finally{setBusy(false)}};return <article className="interactive-learn-assignment-player"><span className="interactive-eyebrow">Assignment</span><h1>{assignment.title}</h1><p>{String(assignment.instructions.text||'')}</p><div className="interactive-learn-callout"><ClipboardList className="size-5"/><div><strong>Submission mode</strong><p>{assignment.submissionMode.replaceAll('-',' ')}</p></div></div>{manual?<button type="button" className="interactive-button interactive-button-primary" onClick={onCompleted}>Mark assignment complete</button>:<div className="interactive-learn-assignment-submit">{submission?<div className={`interactive-learn-feedback ${submission.status==='accepted'?'is-correct':submission.status==='rejected'?'is-incorrect':''}`}><strong>{submission.status==='accepted'?'Accepted':submission.status==='rejected'?'Changes requested':'Submitted for review'}</strong>{submission.feedback?.text?<p>{String(submission.feedback.text)}</p>:null}</div>:null}{canSubmit?<>{assignment.submissionMode==='text'?<textarea value={text} onChange={event=>setText(event.currentTarget.value)} placeholder="Write your response…"/>:assignment.submissionMode==='file'?<div><input type="file" onChange={event=>setFile(event.currentTarget.files?.[0]||null)}/>{upload?<div className="interactive-learn-upload-progress" role="progressbar" aria-valuemin={0} aria-valuemax={100} aria-valuenow={upload.percent}><i style={{width:`${upload.percent}%`}}/><span>{upload.percent}%</span></div>:null}</div>:<div className="interactive-learn-assignment-project"><input value={projectId} onChange={event=>setProjectId(event.currentTarget.value)} placeholder="Learnitive project ID"/><input value={projectName} onChange={event=>setProjectName(event.currentTarget.value)} placeholder="Project name (optional)"/></div>}<button type="button" className="interactive-button interactive-button-primary" disabled={busy} onClick={()=>void submit()}>{busy?'Submitting…':submission?.status==='rejected'?'Resubmit':'Submit assignment'}</button></>:null}{error?<p className="interactive-error-copy" role="alert">{error}</p>:null}</div>}</article>}

export function LearnPlayerPage({courseSlug,lessonSlug}:{courseSlug:string;lessonSlug:string}){const [auth,setAuth]=React.useState<SaasAuthState>({authenticated:false});const [course,setCourse]=React.useState<PublicLearnCourse>();const [lesson,setLesson]=React.useState<PublicLearnLesson>();const [quiz,setQuiz]=React.useState<PublicLearnQuiz>();const [assignment,setAssignment]=React.useState<PublicLearnAssignment>();const [error,setError]=React.useState('');const [drawer,setDrawer]=React.useState(false);const [saving,setSaving]=React.useState(false);
  const metadataTitle=lesson?.title||quiz?.title||assignment?.title;
  usePageMetadata({ title: metadataTitle&&course ? `${metadataTitle} · ${course.title}` : 'Learn', description: metadataTitle&&course ? `Study ${metadataTitle} in the ${course.title} course on Learnitive.` : 'Learnitive lesson player.', pathname: `/learn/${encodeURIComponent(courseSlug)}/${encodeURIComponent(lessonSlug)}`, robots: 'noindex,follow', enabled: Boolean(course&&metadataTitle) });
  const refreshCourse=React.useCallback(async()=>{const value=await getLearnCourse(courseSlug);setCourse(value);return value;},[courseSlug]);
  React.useEffect(()=>{let active=true;void getAuthState().then(value=>{if(active)setAuth(value)}).catch(()=>{});return()=>{active=false}},[]);
  React.useEffect(()=>{let active=true;setLesson(undefined);setQuiz(undefined);setAssignment(undefined);setError('');void getLearnCourse(courseSlug).then(async courseValue=>{if(!active)return;setCourse(courseValue);const item=courseValue.sections.flatMap(section=>section.items).find(candidate=>candidate.slug===lessonSlug);if(!item)throw new Error('learn_item_not_found');if(item.type==='lesson'){const value=await getLearnLesson(courseSlug,lessonSlug);if(active)setLesson(value)}else if(item.type==='quiz'){const value=await getLearnQuiz(courseSlug,lessonSlug);if(active)setQuiz(value)}else{const value=await getLearnAssignment(courseSlug,lessonSlug);if(active)setAssignment(value)}if(!item.locked&&!item.completed)void saveItemProgress(courseSlug,lessonSlug,'started').catch(()=>undefined);}).catch(reason=>{if(active)setError(reason instanceof Error?reason.message:String(reason))});return()=>{active=false}},[courseSlug,lessonSlug]);
  if(error)return <section className="interactive-page-container interactive-page-heading"><h1>Lesson unavailable</h1><p>{error}</p><a href={`/learn/${encodeURIComponent(courseSlug)}`}>Return to course</a></section>;if(!course||(!lesson&&!quiz&&!assignment))return <div className="interactive-learn-player-loading">Loading lesson…</div>;const ordered=course.sections.flatMap(s=>s.items),index=ordered.findIndex(item=>item.slug===lessonSlug),current=ordered[index],previous=index>0?ordered[index-1]:undefined,next=index>=0&&index<ordered.length-1?ordered[index+1]:undefined;
  const authoritativeCompleted=async()=>{try{await refreshCourse()}catch(reason){setError(reason instanceof Error?reason.message:String(reason))}};
  const manualCompletionAllowed=Boolean((lesson&&lesson.completionMode==='manual')||(assignment&&assignment.submissionMode==='manual-complete'));
  const complete=async()=>{if(saving||current.completed||!manualCompletionAllowed)return;setSaving(true);try{await saveItemProgress(courseSlug,lessonSlug,'completed');await refreshCourse()}catch(reason){setError(reason instanceof Error?reason.message:String(reason))}finally{setSaving(false)}};
  const locked=Boolean(lesson?.locked||quiz?.locked||assignment?.locked);const completionLabel=current.completed?'Completed':quiz?'Pass quiz to complete':lesson&&lesson.completionMode!=='manual'?'Complete required activities':assignment&&assignment.submissionMode!=='manual-complete'?'Submit assignment to complete':'Mark complete';
  return <div className="interactive-learn-player"><header className="interactive-learn-player-top"><a href={`/learn/${encodeURIComponent(courseSlug)}`}><ChevronLeft className="size-5"/><span>{course.title}</span></a><div className="interactive-learn-player-top-actions"><button type="button" onClick={()=>setDrawer(true)}><Menu className="size-5"/> Curriculum</button><LearnitiveAccountPopover auth={auth} logoutRedirect={`/learn/${encodeURIComponent(courseSlug)}`}/></div></header><div className="interactive-learn-player-body"><PlayerCurriculum course={course} active={lessonSlug}/>{drawer?<div className="interactive-learn-player-drawer"><button type="button" className="interactive-learn-player-drawer-backdrop" aria-label="Close curriculum" onClick={()=>setDrawer(false)}/><PlayerCurriculum course={course} active={lessonSlug} onClose={()=>setDrawer(false)}/></div>:null}<main className="interactive-learn-player-content">{lesson?<>{lesson.locked?<div className="interactive-learn-player-lock"><LockKeyhole className="size-8"/><h1>{lesson.title}</h1><p>{lockMessage(lesson.lockReason)}</p>{lesson.lockReason==='pro'?<a className="interactive-button interactive-button-primary" href="/pricing">View Pro</a>:null}</div>:<article><span className="interactive-eyebrow">Lesson {index+1} of {ordered.length}</span><h1>{lesson.title}</h1><div className="interactive-learn-player-meta"><span><Clock3 className="size-4"/>{duration(lesson.estimatedMinutes)}</span>{lesson.accessTier==='pro'?<span><Crown className="size-4"/>Pro</span>:null}</div>{course.notice?.text?<aside className="interactive-learn-course-notice"><strong>{String(course.notice.title||'Course notice')}</strong><p>{String(course.notice.text)}</p></aside>:null}{lesson.document?<LessonRenderer lesson={lesson} onLessonCompleted={()=>void authoritativeCompleted()}/>:null}</article>}</>:quiz?<QuizPlayer quiz={quiz} onPassed={()=>void authoritativeCompleted()}/>:assignment?<AssignmentPlayer assignment={assignment} onCompleted={()=>void complete()}/>:null}</main></div><footer className="interactive-learn-player-bottom">{previous&&!previous.locked?<a className="interactive-learn-player-nav previous" href={`/learn/${encodeURIComponent(courseSlug)}/${encodeURIComponent(previous.slug)}`}><ChevronLeft className="size-4"/><span><small>Previous</small><strong>{previous.title}</strong></span></a>:previous?<span className="interactive-learn-player-nav previous is-disabled" aria-disabled="true"><ChevronLeft className="size-4"/><span><small>Previous</small><strong>{previous.title}</strong></span></span>:<span/>}<button type="button" className={current.completed?'interactive-button interactive-button-secondary':'interactive-button interactive-button-primary'} disabled={saving||current.completed||locked||!manualCompletionAllowed} onClick={()=>void complete()}>{current.completed?<><Check className="size-4"/> Completed</>:saving?'Saving…':completionLabel}</button>{next&&!next.locked?<a className="interactive-learn-player-nav next" href={`/learn/${encodeURIComponent(courseSlug)}/${encodeURIComponent(next.slug)}`}><span><small>Next</small><strong>{next.title}</strong></span><ChevronRight className="size-4"/></a>:next?<span className="interactive-learn-player-nav next is-disabled" aria-disabled="true"><span><small>Next</small><strong>{next.title}</strong></span><LockKeyhole className="size-4"/></span>:<a className="interactive-learn-player-nav next" href={`/learn/${encodeURIComponent(courseSlug)}`}><span><small>Next</small><strong>Course overview</strong></span><ChevronRight className="size-4"/></a>}</footer></div>}
