import test from 'node:test';
import assert from 'node:assert/strict';
import { randomUUID } from 'node:crypto';

process.env.NODE_ENV = 'test';
process.env.DB_PATH = ':memory:';

const jsonFetch = async (
  baseUrl: string,
  path: string,
  options?: { method?: string; body?: unknown },
) => {
  const res = await fetch(`${baseUrl}${path}`, {
    method: options?.method ?? 'GET',
    headers: options?.body ? { 'Content-Type': 'application/json' } : undefined,
    body: options?.body ? JSON.stringify(options.body) : undefined,
  });

  const text = await res.text();
  let json: any = null;
  try {
    json = text ? JSON.parse(text) : null;
  } catch {
    json = null;
  }
  return { status: res.status, json, text };
};

test('得分占比=总得分/试卷总分；40%应判定为不及格', async () => {
  const { initDatabase, run, get } = await import('../api/database');
  await initDatabase();

  const { app } = await import('../api/server');
  const server = app.listen(0);

  try {
    const addr = server.address();
    assert.ok(addr && typeof addr === 'object');
    const baseUrl = `http://127.0.0.1:${addr.port}`;

    const userId = randomUUID();

    await run(`INSERT INTO users (id, name, phone, password) VALUES (?, ?, ?, ?)`, [
      userId,
      '测试用户',
      '13900139001',
      '',
    ]);

    // 5道单选题，每题5分，总分25；答对2题得10分，得分占比=40%
    const questionIds: string[] = [];
    for (let i = 0; i < 5; i++) {
      const qid = randomUUID();
      questionIds.push(qid);
      await run(
        `INSERT INTO questions (id, content, type, options, answer, analysis, score, category)
         VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
        [
          qid,
          `题目${i + 1}`,
          'single',
          JSON.stringify(['A', 'B', 'C', 'D']),
          'A',
          '',
          5,
          '通用',
        ],
      );
    }

    const answers = questionIds.map((questionId, idx) => ({
      questionId,
      userAnswer: idx < 2 ? 'A' : 'B',
      score: 0,
      isCorrect: false,
    }));

    const submitRes = await jsonFetch(baseUrl, '/api/quiz/submit', {
      method: 'POST',
      body: { userId, answers },
    });

    assert.equal(submitRes.status, 200, submitRes.text);
    assert.equal(submitRes.json?.success, true);
    const recordId = submitRes.json?.data?.recordId;
    assert.ok(recordId);

    const detailRes = await jsonFetch(baseUrl, `/api/quiz/records/detail/${recordId}`);
    assert.equal(detailRes.status, 200, detailRes.text);
    assert.equal(detailRes.json?.success, true);

    const record = detailRes.json?.data?.record;
    assert.ok(record);
    assert.equal(record.totalScore, 10);
    assert.equal(record.correctCount, 2);
    assert.equal(record.totalCount, 5);

    assert.ok(typeof record.scorePercentage === 'number');
    assert.ok(Math.abs(record.scorePercentage - 40) < 0.0001);
    assert.equal(record.status, '不及格');

    // 数据库里也应写入合理的score_percentage（避免旧逻辑200%）
    const dbRow = await get(`SELECT score_percentage as scorePercentage, status FROM quiz_records WHERE id = ?`, [recordId]);
    assert.ok(dbRow);
    assert.ok(typeof dbRow.scorePercentage === 'number');
    assert.ok(Math.abs(dbRow.scorePercentage - 40) < 0.0001);
    assert.equal(dbRow.status, '不及格');
  } finally {
    server.close();
  }
});

test('0分题目提交时默认判定正确且不要求作答', async () => {
  const { initDatabase, run, get } = await import('../api/database');
  await initDatabase();

  const { app } = await import('../api/server');
  const server = app.listen(0);

  const jsonFetch = async (baseUrl: string, path: string, options?: { method?: string; body?: unknown }) => {
    const res = await fetch(`${baseUrl}${path}`, {
      method: options?.method ?? 'GET',
      headers: options?.body ? { 'Content-Type': 'application/json' } : undefined,
      body: options?.body ? JSON.stringify(options.body) : undefined,
    });
    const text = await res.text();
    let json: any = null;
    try {
      json = text ? JSON.parse(text) : null;
    } catch {
      json = null;
    }
    return { status: res.status, json, text };
  };

  try {
    const addr = server.address();
    assert.ok(addr && typeof addr === 'object');
    const baseUrl = `http://127.0.0.1:${addr.port}`;

    const userId = randomUUID();
    await run(`INSERT INTO users (id, name, phone, password) VALUES (?, ?, ?, ?)`, [
      userId,
      '测试用户',
      `138${Math.floor(Math.random() * 1e8).toString().padStart(8, '0')}`,
      '',
    ]);

    const q0 = randomUUID();
    await run(
      `INSERT INTO questions (id, content, type, options, answer, analysis, score, category)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
      [q0, '0分题', 'single', JSON.stringify(['A', 'B']), '', '用于验证0分默认正确', 0, '通用'],
    );

    const res = await jsonFetch(baseUrl, '/api/quiz/submit', {
      method: 'POST',
      body: {
        userId,
        answers: [
          {
            questionId: q0,
            // 不传 userAnswer
            score: 0,
            isCorrect: false,
          },
        ],
      },
    });

    assert.equal(res.status, 200);
    assert.equal(res.json?.success, true);
    assert.equal(res.json?.data?.totalScore, 0);
    assert.equal(res.json?.data?.correctCount, 1);
    assert.equal(res.json?.data?.totalCount, 1);

    const recordId = res.json?.data?.recordId;
    assert.ok(recordId);

    const row = await get(`SELECT * FROM quiz_answers WHERE record_id = ?`, [recordId]);
    assert.ok(row);
    assert.equal(row.is_correct, 1);
    assert.equal(row.score, 0);
    assert.equal(row.user_answer, '');
  } finally {
    await new Promise<void>((resolve) => server.close(() => resolve()));
  }
});
