import { useCallback, useEffect, useRef, useState } from 'react';
import { router } from '@inertiajs/react';
import { AppLayout } from '@/Components/Layout/AppLayout';

type Settings = {
  randomizeQuestions: boolean;
  shuffleOptions: boolean;
  timeMode: 'full' | 'per_question';
  timePerQuestionSeconds: number | null;
};

type Option = { id: number; body: string; imagePath: string | null };

type Question = {
  id: number;
  type: 'test' | 'descriptive' | 'file';
  body: string;
  score: number;
  imagePath: string | null;
  allowFileUpload: boolean;
  options: Option[];
  savedOptionId: number | null;
  savedText: string | null;
  savedFilePath: string | null;
};

type ExamMeta = {
  id: number;
  title: string;
  maxScore: number;
  durationMinutes: number | null;
  settings: Settings;
};

type Props = {
  exam: ExamMeta;
  sessionId: number;
  questions: Question[];
  remainingSeconds: number | null;
  studentName: string;
};

function formatTime(secs: number): string {
  const h = Math.floor(secs / 3600);
  const m = Math.floor((secs % 3600) / 60);
  const s = secs % 60;
  if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
  return `${m}:${String(s).padStart(2, '0')}`;
}

function csrfToken(): string {
  return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') ?? '';
}

export default function TakeExam({ exam, sessionId, questions, remainingSeconds, studentName }: Props) {
  const isPerQuestion = exam.settings.timeMode === 'per_question';
  const perQuestionSecs = exam.settings.timePerQuestionSeconds ?? 60;

  const [answers, setAnswers] = useState<Record<number, { optionId?: number; text?: string; fileName?: string }>>(() => {
    const init: Record<number, { optionId?: number; text?: string; fileName?: string }> = {};
    for (const q of questions) {
      init[q.id] = {
        optionId: q.savedOptionId ?? undefined,
        text: q.savedText ?? undefined,
        fileName: q.savedFilePath ? q.savedFilePath.split('/').pop() : undefined,
      };
    }
    return init;
  });

  const [currentIdx, setCurrentIdx] = useState(0);
  const [fullTimeLeft, setFullTimeLeft] = useState<number | null>(remainingSeconds);
  const [qTimeLeft, setQTimeLeft] = useState<number>(isPerQuestion ? perQuestionSecs : 0);
  const [submitting, setSubmitting] = useState(false);
  const [showLeaveWarning, setShowLeaveWarning] = useState(false);
  const [uploadingQid, setUploadingQid] = useState<number | null>(null);
  const saveQueueRef = useRef<Record<number, ReturnType<typeof setTimeout>>>({});
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const fileUploadQid = useRef<number | null>(null);

  // ── Anti-screenshot / anti-copy ──
  useEffect(() => {
    const blockContext = (e: Event) => e.preventDefault();
    const blockCopy = (e: ClipboardEvent) => e.preventDefault();
    const onVisibility = () => {
      if (document.hidden) setShowLeaveWarning(true);
    };
    const onBlur = () => setShowLeaveWarning(true);

    document.addEventListener('contextmenu', blockContext);
    document.addEventListener('copy', blockCopy);
    document.addEventListener('cut', blockCopy);
    document.addEventListener('visibilitychange', onVisibility);
    window.addEventListener('blur', onBlur);

    return () => {
      document.removeEventListener('contextmenu', blockContext);
      document.removeEventListener('copy', blockCopy);
      document.removeEventListener('cut', blockCopy);
      document.removeEventListener('visibilitychange', onVisibility);
      window.removeEventListener('blur', onBlur);
    };
  }, []);

  // ── Full-exam timer ──
  useEffect(() => {
    if (isPerQuestion || fullTimeLeft === null || fullTimeLeft <= 0) return;
    const timer = setInterval(() => {
      setFullTimeLeft((prev) => {
        if (prev === null || prev <= 1) {
          clearInterval(timer);
          handleSubmit();
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
    return () => clearInterval(timer);
  }, [isPerQuestion]);

  // ── Per-question timer ──
  useEffect(() => {
    if (!isPerQuestion) return;
    setQTimeLeft(perQuestionSecs);
    const timer = setInterval(() => {
      setQTimeLeft((prev) => {
        if (prev <= 1) {
          clearInterval(timer);
          if (currentIdx < questions.length - 1) {
            setCurrentIdx((i) => i + 1);
          } else {
            handleSubmit();
          }
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
    return () => clearInterval(timer);
  }, [currentIdx, isPerQuestion]);

  const autoSave = useCallback((questionId: number, payload: { optionId?: number; text?: string }) => {
    if (saveQueueRef.current[questionId]) clearTimeout(saveQueueRef.current[questionId]);
    saveQueueRef.current[questionId] = setTimeout(() => {
      fetch(`/student/exams/${exam.id}/answer`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
          'X-CSRF-TOKEN': csrfToken(),
        },
        body: JSON.stringify({
          session_id: sessionId,
          question_id: questionId,
          option_id: payload.optionId ?? null,
          answer_text: payload.text ?? null,
        }),
      }).catch(() => {});
    }, 600);
  }, [exam.id, sessionId]);

  function setOption(questionId: number, optionId: number) {
    setAnswers((prev) => {
      const next = { ...prev, [questionId]: { ...prev[questionId], optionId } };
      autoSave(questionId, { optionId });
      return next;
    });
  }

  function setText(questionId: number, text: string) {
    setAnswers((prev) => {
      const next = { ...prev, [questionId]: { ...prev[questionId], text } };
      autoSave(questionId, { text });
      return next;
    });
  }

  function handleFileUpload(questionId: number, file: File) {
    setUploadingQid(questionId);
    const formData = new FormData();
    formData.append('session_id', String(sessionId));
    formData.append('question_id', String(questionId));
    formData.append('file', file);

    fetch(`/student/exams/${exam.id}/upload`, {
      method: 'POST',
      headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': csrfToken() },
      body: formData,
    })
      .then((res) => res.json())
      .then((data) => {
        if (data.ok) {
          setAnswers((prev) => ({
            ...prev,
            [questionId]: { ...prev[questionId], fileName: data.fileName ?? file.name },
          }));
        }
      })
      .catch(() => {})
      .finally(() => setUploadingQid(null));
  }

  function triggerFileUpload(questionId: number) {
    fileUploadQid.current = questionId;
    fileInputRef.current?.click();
  }

  function onFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (file && fileUploadQid.current) {
      handleFileUpload(fileUploadQid.current, file);
    }
    if (fileInputRef.current) fileInputRef.current.value = '';
  }

  function handleSubmit() {
    if (submitting) return;
    setSubmitting(true);
    router.post(
      `/student/exams/${exam.id}/submit`,
      { session_id: sessionId },
      { onError: () => setSubmitting(false) }
    );
  }

  function goNext() {
    if (currentIdx < questions.length - 1) setCurrentIdx(currentIdx + 1);
  }

  function goPrev() {
    if (currentIdx > 0) setCurrentIdx(currentIdx - 1);
  }

  function isAnswered(q: Question): boolean {
    const a = answers[q.id];
    if (q.type === 'test') return !!a?.optionId;
    if (q.type === 'file' || q.allowFileUpload) return !!a?.fileName;
    return (a?.text?.trim() ?? '').length > 0;
  }

  const answeredCount = questions.filter(isAnswered).length;
  const currentQ = questions[currentIdx];
  const timeLeft = isPerQuestion ? qTimeLeft : fullTimeLeft;
  const urgent = timeLeft !== null && timeLeft < 60;
  const isLastQ = currentIdx === questions.length - 1;

  return (
    <>
      <input type="file" ref={fileInputRef} onChange={onFileChange} accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.txt,.zip" style={{ display: 'none' }} />

      <AppLayout title={`امتحان: ${exam.title}`}>
        <div className="page-stack exam-secure">
          <section className="section-header">
            <div>
              <h2><i className="bi bi-pencil-square" style={{ marginLeft: '0.5rem', color: 'var(--color-primary)' }} />{exam.title}</h2>
              <p>پاسخ‌ها به‌صورت خودکار ذخیره می‌شوند.</p>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: '0.25rem' }}>
              {timeLeft !== null && (
                <span className={`status-pill ${urgent ? 'warning' : 'success'}`} style={{ fontVariantNumeric: 'tabular-nums', direction: 'ltr' }}>
                  <i className="bi bi-stopwatch" /> {formatTime(timeLeft)}
                  {isPerQuestion && <span style={{ fontSize: '0.7rem', marginRight: '0.3rem' }}>(هر سوال)</span>}
                </span>
              )}
              <span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted)' }}>
                {answeredCount} از {questions.length} پاسخ داده شد
              </span>
            </div>
          </section>

          <div style={{ height: 6, background: 'var(--color-border)', borderRadius: 99, overflow: 'hidden', position: 'sticky', top: 64, zIndex: 10 }}>
            <div style={{ height: '100%', width: `${questions.length > 0 ? (answeredCount / questions.length) * 100 : 0}%`, background: 'var(--color-primary)', borderRadius: 99, transition: 'width 0.3s' }} />
          </div>

          {/* Question navigator */}
          <section className="panel-card exam-nav" style={{ padding: '0.6rem 0.8rem' }}>
            <div className="exam-nav-pills">
              {questions.map((q, idx) => (
                <button
                  key={q.id}
                  type="button"
                  className={`exam-nav-pill${idx === currentIdx ? ' active' : ''}${isAnswered(q) ? ' done' : ''}`}
                  onClick={() => setCurrentIdx(idx)}
                >
                  {idx + 1}
                </button>
              ))}
            </div>
          </section>

          {questions.length === 0 ? (
            <section className="panel-card"><p style={{ textAlign: 'center', color: 'var(--color-text-muted)' }}>این امتحان هنوز سوالی ندارد.</p></section>
          ) : (
            <section className="panel-card exam-question-card" key={currentQ.id}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '0.75rem' }}>
                <h3 style={{ margin: 0, fontSize: '1rem' }}>سوال {currentIdx + 1} از {questions.length}</h3>
                <span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted)', background: 'var(--color-surface-muted)', padding: '0.15rem 0.5rem', borderRadius: 'var(--radius-sm)' }}>
                  {currentQ.score} نمره
                </span>
              </div>

              <p className="exam-question-body" style={{ margin: '0 0 1rem', lineHeight: 1.7 }}>{currentQ.body}</p>

              {currentQ.imagePath && (
                <img src={`/storage/${currentQ.imagePath}`} alt="تصویر سوال" className="exam-question-image" style={{ maxWidth: '100%', borderRadius: 'var(--radius-sm)', marginBottom: '1rem' }} />
              )}

              {currentQ.type === 'test' && (
                <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
                  {currentQ.options.map((opt) => {
                    const selected = answers[currentQ.id]?.optionId === opt.id;
                    return (
                      <li key={opt.id}>
                        <label
                          className="exam-option-label"
                          style={{
                            display: 'flex', alignItems: 'flex-start', gap: '0.75rem', padding: '0.6rem 0.9rem', borderRadius: 'var(--radius-sm)',
                            border: `1px solid ${selected ? 'var(--color-primary)' : 'var(--color-border)'}`,
                            background: selected ? 'var(--color-primary-soft)' : 'var(--color-bg)', cursor: 'pointer', transition: 'all 0.15s',
                          }}
                        >
                          <input type="radio" name={`q-${currentQ.id}`} checked={selected} onChange={() => setOption(currentQ.id, opt.id)} style={{ accentColor: 'var(--color-primary)', flexShrink: 0, marginTop: '0.15rem' }} />
                          <span style={{ flex: 1 }}>
                            {opt.body}
                            {opt.imagePath && (
                              <img src={`/storage/${opt.imagePath}`} alt="گزینه" style={{ maxWidth: '100%', borderRadius: 'var(--radius-sm)', marginTop: '0.5rem', display: 'block' }} />
                            )}
                          </span>
                        </label>
                      </li>
                    );
                  })}
                </ul>
              )}

              {currentQ.type === 'descriptive' && (
                <textarea
                  className="form-control exam-answer-textarea"
                  rows={4}
                  placeholder="پاسخ خود را اینجا بنویسید..."
                  value={answers[currentQ.id]?.text ?? ''}
                  onChange={(e) => setText(currentQ.id, e.target.value)}
                  maxLength={5000}
                />
              )}

              {(currentQ.type === 'file' || currentQ.allowFileUpload) && (
                <div className="exam-file-upload">
                  {answers[currentQ.id]?.fileName ? (
                    <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', padding: '0.6rem 0.9rem', background: 'var(--color-primary-soft)', borderRadius: 'var(--radius-sm)', border: '1px solid var(--color-primary)' }}>
                      <i className="bi bi-file-earmark-check" style={{ color: 'var(--color-primary-active)', fontSize: '1.2rem' }} />
                      <span style={{ flex: 1, fontSize: '0.875rem', fontWeight: 600 }}>{answers[currentQ.id]?.fileName}</span>
                      <button type="button" className="btn btn-ghost btn-sm" onClick={() => triggerFileUpload(currentQ.id)}>
                        <i className="bi bi-arrow-repeat" /> تغییر
                      </button>
                    </div>
                  ) : (
                    <button type="button" className="btn btn-soft" onClick={() => triggerFileUpload(currentQ.id)} disabled={uploadingQid === currentQ.id}>
                      {uploadingQid === currentQ.id
                        ? <><i className="bi bi-hourglass-split" /> در حال آپلود...</>
                        : <><i className="bi bi-cloud-upload" /> آپلود فایل پاسخ (حداکثر ۵ مگابایت)</>
                      }
                    </button>
                  )}
                  <p style={{ fontSize: '0.78rem', color: 'var(--color-text-muted)', margin: '0.4rem 0 0' }}>
                    فرمت‌های مجاز: تصویر، PDF، Word، ZIP
                  </p>
                </div>
              )}

              {isAnswered(currentQ) && (
                <div style={{ marginTop: '0.5rem', fontSize: '0.78rem', color: 'var(--color-primary-active)', display: 'flex', alignItems: 'center', gap: '0.3rem' }}>
                  <i className="bi bi-cloud-check" /> ذخیره شد
                </div>
              )}
            </section>
          )}

          {/* Navigation buttons */}
          {questions.length > 0 && (
            <section className="panel-card" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: '0.75rem' }}>
              <button type="button" className="btn btn-ghost" onClick={goPrev} disabled={currentIdx === 0}>
                <i className="bi bi-arrow-right" /> سوال قبلی
              </button>

              <span style={{ fontSize: '0.85rem', color: 'var(--color-text-muted)' }}>
                {currentIdx + 1} / {questions.length}
              </span>

              {isLastQ ? (
                <button type="button" className="btn btn-primary" onClick={handleSubmit} disabled={submitting} style={{ minWidth: 140 }}>
                  {submitting
                    ? <><i className="bi bi-hourglass-split" /> در حال ارسال...</>
                    : <><i className="bi bi-send-check" /> ثبت نهایی</>
                  }
                </button>
              ) : (
                <button type="button" className="btn btn-primary" onClick={goNext}>
                  سوال بعدی <i className="bi bi-arrow-left" />
                </button>
              )}
            </section>
          )}

          <section className="panel-card" style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', fontSize: '0.8rem', color: 'var(--color-text-muted)' }}>
            <i className="bi bi-shield-lock" style={{ color: 'var(--color-danger)' }} />
            کپی، کلیک راست و خروج از صفحه غیرفعال است. در صورت تغییر تب، امتحان شما ثبت می‌شود.
          </section>
        </div>
      </AppLayout>

      {/* Anti-screenshot overlay */}
      {showLeaveWarning && (
        <div className="exam-leave-overlay">
          <div className="exam-leave-box">
            <i className="bi bi-exclamation-triangle-fill" style={{ fontSize: '3rem', color: 'var(--color-danger)' }} />
            <h2>هشدار امنیتی</h2>
            <p>شما از صفحه امتحان خارج شدید. خروج از تب یا پنجره در حین امتحان ممکن است موجب ثبت خودکار پاسخ‌ها شود.</p>
            <button className="btn btn-primary" onClick={() => { setShowLeaveWarning(false); }}>
              <i className="bi bi-arrow-return-left" /> بازگشت به امتحان
            </button>
          </div>
        </div>
      )}
    </>
  );
}
