const router = require('express').Router();
const { testsDb, messagesDb, uuidv4 } = require('../lib/db');
const { authMiddleware, adminOnly } = require('../lib/auth');

function nowTime() {
  return new Date().toLocaleTimeString('en-IN',{hour:'2-digit',minute:'2-digit',hour12:true});
}
function todayStr() { return new Date().toISOString().slice(0,10); }

// GET /api/tests
router.get('/', authMiddleware, (req, res) => {
  const all = testsDb.get('tests').value();
  if (req.user.role === 'admin') return res.json(all);
  // Employee sees only sent+assigned tests, without correct answers
  const mine = all.filter(t => t.sent && t.assignedTo && t.assignedTo.includes(req.user.empId));
  res.json(mine.map(t => ({
    ...t,
    questions: t.questions.map(q => ({ text: q.text, options: q.options, marks: q.marks }))
  })));
});

// GET /api/tests/results/all  (admin)
router.get('/results/all', authMiddleware, adminOnly, (req, res) => {
  res.json(testsDb.get('results').value());
});

// GET /api/tests/:id
router.get('/:id', authMiddleware, (req, res) => {
  const test = testsDb.get('tests').find({ id: req.params.id }).value();
  if (!test) return res.status(404).json({ error: 'Not found' });
  if (req.user.role !== 'admin') {
    if (!test.assignedTo.includes(req.user.empId))
      return res.status(403).json({ error: 'Not assigned to you' });
    return res.json({
      ...test,
      questions: test.questions.map(q => ({ text: q.text, options: q.options, marks: q.marks }))
    });
  }
  res.json(test);
});

// POST /api/tests  (admin creates)
router.post('/', authMiddleware, adminOnly, (req, res) => {
  const { title, category, duration, passPct, instructions, questions, assignedTo, accessCode, codeEnabled } = req.body;
  if (!title) return res.status(400).json({ error: 'title is required' });
  const test = {
    id: uuidv4(), title,
    category:     category     || '',
    duration:     parseInt(duration)  || 30,
    passPct:      parseInt(passPct)   || 60,
    instructions: instructions || '',
    questions:    Array.isArray(questions)   ? questions   : [],
    assignedTo:   Array.isArray(assignedTo)  ? assignedTo  : [],
    accessCode:   accessCode   || '',
    codeEnabled:  !!codeEnabled,
    sent:         false,
    createdAt:    todayStr()
  };
  testsDb.get('tests').push(test).write();
  res.status(201).json(test);
});

// PUT /api/tests/:id  (admin edits)
router.put('/:id', authMiddleware, adminOnly, (req, res) => {
  if (!testsDb.get('tests').find({ id: req.params.id }).value())
    return res.status(404).json({ error: 'Not found' });
  testsDb.get('tests').find({ id: req.params.id }).assign(req.body).write();
  res.json(testsDb.get('tests').find({ id: req.params.id }).value());
});

// POST /api/tests/:id/send  (admin sends test)
router.post('/:id/send', authMiddleware, adminOnly, (req, res) => {
  const test = testsDb.get('tests').find({ id: req.params.id }).value();
  if (!test) return res.status(404).json({ error: 'Not found' });

  testsDb.get('tests').find({ id: req.params.id }).assign({ sent: true }).write();

  (test.assignedTo || []).forEach(empId => {
    const codeMsg = test.codeEnabled && test.accessCode
      ? ` Access code: ${test.accessCode}` : '';
    const msg = {
      id: uuidv4(), from: 'ADMIN',
      text: `📝 New test assigned: "${test.title}". Duration: ${test.duration} min.${codeMsg} Please complete it at your earliest.`,
      time: nowTime(), date: todayStr(), createdAt: new Date().toISOString()
    };
    const thread = messagesDb.get('threads').find({ empId }).value();
    if (thread) {
      messagesDb.get('threads').find({ empId }).get('messages').push(msg).write();
    } else {
      messagesDb.get('threads').push({ empId, messages: [msg] }).write();
    }
  });
  res.json({ message: `Test sent to ${test.assignedTo.length} employee(s)` });
});

// POST /api/tests/:id/verify-code
router.post('/:id/verify-code', authMiddleware, (req, res) => {
  const test = testsDb.get('tests').find({ id: req.params.id }).value();
  if (!test) return res.status(404).json({ error: 'Not found' });
  if (!test.codeEnabled || !test.accessCode) return res.json({ valid: true });
  const { code } = req.body;
  res.json({ valid: (code || '').toUpperCase() === test.accessCode.toUpperCase() });
});

// GET /api/tests/:id/results  (admin)
router.get('/:id/results', authMiddleware, adminOnly, (req, res) => {
  res.json(testsDb.get('results').filter({ testId: req.params.id }).value());
});

// GET /api/tests/:id/my-result  (employee checks own result — for one-attempt enforcement)
router.get('/:id/my-result', authMiddleware, (req, res) => {
  const result = testsDb.get('results').find({ testId: req.params.id, empId: req.user.empId }).value();
  if (!result) return res.json({ attempted: false });
  res.json({ attempted: true, pct: result.pct, passed: result.passed, score: result.score, totalMarks: result.totalMarks });
});

// POST /api/tests/:id/submit  (employee submits answers — one attempt only)
router.post('/:id/submit', authMiddleware, (req, res) => {
  const test = testsDb.get('tests').find({ id: req.params.id }).value();
  if (!test) return res.status(404).json({ error: 'Not found' });

  // Enforce one attempt
  const existing = testsDb.get('results').find({ testId: test.id, empId: req.user.empId }).value();
  if (existing) {
    return res.status(403).json({ error: 'You have already attempted this test. Only one attempt is allowed.' });
  }

  const { answers } = req.body;
  let score = 0;
  const totalMarks = test.questions.reduce((s, q) => s + (q.marks || 1), 0);
  test.questions.forEach((q, i) => {
    if (answers && answers[i] !== undefined && answers[i] === q.correct) {
      score += (q.marks || 1);
    }
  });
  const pct    = totalMarks > 0 ? Math.round((score / totalMarks) * 100) : 0;
  const passed = pct >= test.passPct;

  const result = {
    id: uuidv4(), testId: test.id, testTitle: test.title,
    empId: req.user.empId, empName: req.user.name,
    score, totalMarks, pct, passed,
    submittedAt: new Date().toISOString()
  };
  testsDb.get('results').push(result).write();
  res.status(201).json(result);
});

// DELETE /api/tests/:id  (admin)
router.delete('/:id', authMiddleware, adminOnly, (req, res) => {
  testsDb.get('tests').remove({ id: req.params.id }).write();
  testsDb.get('results').remove({ testId: req.params.id }).write();
  res.json({ message: 'Deleted' });
});

module.exports = router;
