import { useMemo, useRef, useState } from 'react';
import {
  answerKeyDoc,
  certificateDoc,
  getQuiz,
  handoutDoc,
  printableTestDoc,
  scoreQuiz,
  trainingLogDoc,
} from '../engine/quiz';
import type { QuizScore, TrainingRecord } from '../engine/quiz';
import { QUIZ_PASS_PCT, QUIZ_QUESTIONS } from '../engine/quizContent';
import type { CompanyProfile } from '../engine/types';
import { sha256HexBytes, withVerification } from '../engine/verify';
import { useI18n } from '../i18n/context';
import { fmt } from '../i18n/ui';
import { printDocument } from '../print/print';
import { todayISO, uiDate } from './common';

interface QuizViewProps {
  readonly profile: CompanyProfile;
  readonly records: readonly TrainingRecord[];
  readonly onRecord: (record: TrainingRecord) => void;
  readonly onUpdateRecord: (record: TrainingRecord) => void;
  readonly onDeleteRecord: (id: string) => void;
}

const MAX_SCAN_BYTES = 1_000_000;

/**
 * KI-Kompetenztest (Art. 4): Test mit Auswertung, druckbaren
 * Schulungsunterlagen, manueller Teilnehmer-Erfassung (Papier-Tests),
 * Scan-Belegen mit SHA-256-Prüfsumme und Schulungsregister.
 */
export function QuizView({
  profile,
  records,
  onRecord,
  onUpdateRecord,
  onDeleteRecord,
}: QuizViewProps): JSX.Element {
  const { t, locale, pack } = useI18n();
  const today = todayISO();
  const questions = useMemo(() => getQuiz(locale), [locale]);

  const [name, setName] = useState('');
  const [answers, setAnswers] = useState<readonly (number | null)[]>(() =>
    questions.map(() => null),
  );
  const [result, setResult] = useState<QuizScore | null>(null);
  const [lastRecordId, setLastRecordId] = useState<string | null>(null);

  const [manualName, setManualName] = useState('');
  const [manualCorrect, setManualCorrect] = useState('');
  const [attachTarget, setAttachTarget] = useState<string | null>(null);
  const [attachMessage, setAttachMessage] = useState('');
  const scanInput = useRef<HTMLInputElement>(null);

  const complete = name.trim() !== '' && answers.every((a) => a !== null);

  const printVerified = (file: string, markdown: string): void => {
    void withVerification(markdown, locale).then((verified) =>
      printDocument(file, verified, profile),
    );
  };

  const submit = (): void => {
    const score = scoreQuiz(answers);
    const id = crypto.randomUUID();
    setResult(score);
    setLastRecordId(id);
    onRecord({
      id,
      name: name.trim(),
      date: today,
      scorePct: score.pct,
      passed: score.passed,
      source: 'app',
    });
  };

  const addManual = (): void => {
    const correct = Number(manualCorrect);
    if (manualName.trim() === '' || !Number.isInteger(correct) || correct < 0 || correct > QUIZ_QUESTIONS.length) {
      return;
    }
    const pct = Math.round((correct / QUIZ_QUESTIONS.length) * 100);
    onRecord({
      id: crypto.randomUUID(),
      name: manualName.trim(),
      date: today,
      scorePct: pct,
      passed: pct >= QUIZ_PASS_PCT,
      source: 'paper',
    });
    setManualName('');
    setManualCorrect('');
  };

  const attachScan = async (file: File): Promise<void> => {
    const record = records.find((r) => r.id === attachTarget);
    if (!record) return;
    if (file.size > MAX_SCAN_BYTES) {
      setAttachMessage(t.quizAttachTooBig);
      return;
    }
    const buffer = await file.arrayBuffer();
    const sha256 = await sha256HexBytes(buffer);
    const dataUrl = await new Promise<string>((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(typeof reader.result === 'string' ? reader.result : '');
      reader.onerror = () => reject(new Error('read failed'));
      reader.readAsDataURL(file);
    });
    onUpdateRecord({ ...record, attachment: { fileName: file.name, sha256, dataUrl } });
    setAttachMessage(t.quizAttachDone);
  };

  const openScan = (record: TrainingRecord): void => {
    if (!record.attachment) return;
    const win = window.open('', '_blank');
    if (!win) return;
    if (record.attachment.dataUrl.startsWith('data:application/pdf')) {
      win.document.write(
        `<iframe src="${record.attachment.dataUrl}" style="border:0;width:100vw;height:100vh"></iframe>`,
      );
    } else {
      win.document.write(`<img src="${record.attachment.dataUrl}" style="max-width:100%">`);
    }
    win.document.close();
  };

  return (
    <div>
      <h1>{t.navQuiz}</h1>
      <p className="sub">{t.quizSub}</p>

      {result === null ? (
        <>
          <div className="panel">
            <label className="field">
              <span>{t.quizName}</span>
              <input
                type="text"
                value={name}
                placeholder={t.quizNamePh}
                onChange={(e) => setName(e.target.value)}
              />
            </label>
          </div>

          {questions.map((q, qi) => (
            <div key={q.id} className="panel">
              <h2 style={{ marginTop: 0 }}>
                {qi + 1}. {q.question}
              </h2>
              {q.options.map((option, oi) => (
                <label key={oi} className="check">
                  <input
                    type="radio"
                    name={q.id}
                    checked={answers[qi] === oi}
                    onChange={() => setAnswers(answers.map((a, i) => (i === qi ? oi : a)))}
                  />
                  <span>{option}</span>
                </label>
              ))}
            </div>
          ))}

          <div className="wizard-nav">
            <span className="hint">{!complete ? t.quizAnswerAll : ''}</span>
            <button className="primary" disabled={!complete} onClick={submit}>
              {t.quizSubmit}
            </button>
          </div>
        </>
      ) : (
        <div className="panel">
          <h2 style={{ marginTop: 0 }}>
            <span className={`badge ${result.passed ? 'minimal' : 'high'}`}>
              {result.passed ? t.quizPassed : t.quizFailed}
            </span>
          </h2>
          <p>
            {fmt(t.quizScoreLine, {
              correct: result.correct,
              total: result.total,
              pct: result.pct,
              pass: QUIZ_PASS_PCT,
            })}
          </p>
          <div className="toolbar">
            <button
              className="primary"
              onClick={() =>
                printVerified(
                  `ki-kompetenz-${name.trim()}-${today}`,
                  certificateDoc(name.trim(), result, pack, today, profile, locale, lastRecordId ?? undefined),
                )
              }
            >
              {t.quizCert}
            </button>
            <button
              className="ghost"
              onClick={() => {
                setAnswers(questions.map(() => null));
                setResult(null);
                setLastRecordId(null);
              }}
            >
              {t.quizRetry}
            </button>
          </div>

          <h2>{t.quizWhy}</h2>
          <ul className="reasons">
            {questions.map((q, qi) => (
              <li key={q.id}>
                <strong>
                  {answers[qi] === q.correctIndex ? '✓' : '✗'} {qi + 1}.
                </strong>{' '}
                {q.explanation}
              </li>
            ))}
          </ul>
        </div>
      )}

      <div className="panel">
        <h2 style={{ marginTop: 0 }}>{t.quizDocsTitle}</h2>
        <div className="toolbar" style={{ marginBottom: 0 }}>
          <button
            className="ghost"
            onClick={() =>
              printDocument(`ki-test-papier-${today}`, printableTestDoc(pack, today, profile, locale), profile)
            }
          >
            {t.quizPrintTest}
          </button>
          <button
            className="ghost"
            onClick={() =>
              printDocument(`ki-test-loesungen-${today}`, answerKeyDoc(pack, today, profile, locale), profile)
            }
          >
            {t.quizPrintKey}
          </button>
          <button
            className="ghost"
            onClick={() =>
              printDocument(`ki-schulungshandout-${today}`, handoutDoc(pack, today, profile, locale), profile)
            }
          >
            {t.quizPrintHandout}
          </button>
        </div>
      </div>

      <div className="panel">
        <h2 style={{ marginTop: 0 }}>{t.quizManualTitle}</h2>
        <p className="hint">{t.quizManualHint}</p>
        <div className="profile-grid">
          <label className="field">
            <span>{t.quizName}</span>
            <input
              type="text"
              value={manualName}
              placeholder={t.quizNamePh}
              onChange={(e) => setManualName(e.target.value)}
            />
          </label>
          <label className="field">
            <span>{t.quizManualScore}</span>
            <input
              type="text"
              inputMode="numeric"
              value={manualCorrect}
              placeholder={`0–${QUIZ_QUESTIONS.length}`}
              onChange={(e) => setManualCorrect(e.target.value)}
            />
          </label>
        </div>
        <button className="primary" onClick={addManual}>
          {t.quizManualAdd}
        </button>
      </div>

      <div className="panel">
        <div className="panel-head">
          <h2 style={{ margin: 0 }}>{t.quizLogTitle}</h2>
          {records.length > 0 && (
            <button
              className="ghost"
              onClick={() =>
                printVerified(
                  `schulungsregister-${today}`,
                  trainingLogDoc(records, pack, today, profile, locale),
                )
              }
            >
              {t.quizLogPrint}
            </button>
          )}
        </div>
        <p className="hint">{t.quizLogHint}</p>
        {attachMessage && <p className="hint">{attachMessage}</p>}
        <input
          ref={scanInput}
          type="file"
          accept="image/*,application/pdf"
          style={{ display: 'none' }}
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) void attachScan(file);
            e.target.value = '';
          }}
        />
        {records.length === 0 ? (
          <p className="hint">{t.quizLogEmpty}</p>
        ) : (
          <div className="table-scroll">
            <table>
              <thead>
                <tr>
                  <th>{t.colUpdated}</th>
                  <th>{t.colOwner}</th>
                  <th>{t.quizColSource}</th>
                  <th>{t.quizColScore}</th>
                  <th>{t.quizColStatus}</th>
                  <th>{t.quizColEvidence}</th>
                </tr>
              </thead>
              <tbody>
                {records.map((r) => (
                  <tr key={r.id}>
                    <td>{uiDate(r.date, locale)}</td>
                    <td>{r.name}</td>
                    <td>{(r.source ?? 'app') === 'paper' ? t.quizSourcePaper : t.quizSourceApp}</td>
                    <td>{r.scorePct} %</td>
                    <td>
                      <span className={`badge ${r.passed ? 'minimal' : 'high'}`}>
                        {r.passed ? t.quizPassed : t.quizFailed}
                      </span>
                    </td>
                    <td>
                      <div className="toolbar" style={{ margin: 0 }}>
                        {r.attachment ? (
                          <button
                            className="ghost"
                            title={`SHA-256: ${r.attachment.sha256}`}
                            onClick={() => openScan(r)}
                          >
                            ✓ {t.quizAttachView}
                          </button>
                        ) : (
                          <button
                            className="ghost"
                            onClick={() => {
                              setAttachTarget(r.id);
                              scanInput.current?.click();
                            }}
                          >
                            {t.quizAttach}
                          </button>
                        )}
                        <button
                          className="danger"
                          onClick={() => {
                            if (window.confirm(fmt(t.quizDeleteRecord, { name: r.name }))) {
                              onDeleteRecord(r.id);
                            }
                          }}
                        >
                          ✕
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}
