'use strict';
const db = require('../../db/db');
const { emitToSession, hasAccess, canDraw } = require('./_shared');

function postStrokes(req, res) {
  const sessionId = Number(req.params.id);
  const { strokes, page_num = 1 } = req.body;
  if (!Array.isArray(strokes) || !strokes.length || strokes.length > 500)
    return res.status(400).json({ error: 'strokes array required (max 500)' });

  const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (!canDraw(sessionId, req.user.id, session) && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  const insert    = db.prepare('INSERT INTO classroom_strokes (session_id, page_num, user_id, tool, data, seq) VALUES (?,?,?,?,?,?)');
  const getMaxSeq = db.prepare('SELECT COALESCE(MAX(seq), 0) AS m FROM classroom_strokes WHERE session_id=? AND page_num=?');

  const saved = [];
  db.transaction(() => {
    let seq = getMaxSeq.get(sessionId, page_num).m;
    for (const s of strokes) {
      seq++;
      const { lastInsertRowid } = insert.run(sessionId, page_num, req.user.id, s.tool || 'pencil', JSON.stringify(s.data), seq);
      saved.push({ id: Number(lastInsertRowid), tool: s.tool || 'pencil', data: s.data, seq });
    }
  })();

  emitToSession(sessionId, { type: 'classroom_strokes', sessionId, pageNum: page_num, strokes: saved, userId: req.user.id });
  res.json({ strokes: saved });
}

function getStrokes(req, res) {
  const sessionId = Number(req.params.id);
  const pageNum   = Number(req.query.page_num) || 1;
  const sinceSeq  = req.query.since_seq !== undefined ? Number(req.query.since_seq) : -1;
  const session   = db.prepare('SELECT * FROM classroom_sessions WHERE id=?').get(sessionId);
  if (!session) return res.status(404).json({ error: 'Не найдено' });
  if (!hasAccess(session, req.user.id, req.user.role)) return res.status(403).json({ error: 'Нет доступа' });

  const STROKES_PAGE_LIMIT = 5000;
  const rows = sinceSeq >= 0
    ? db.prepare('SELECT id, tool, data, seq FROM classroom_strokes WHERE session_id=? AND page_num=? AND seq > ? ORDER BY seq LIMIT ?').all(sessionId, pageNum, sinceSeq, STROKES_PAGE_LIMIT)
    : db.prepare('SELECT id, tool, data, seq FROM classroom_strokes WHERE session_id=? AND page_num=? ORDER BY seq LIMIT ?').all(sessionId, pageNum, STROKES_PAGE_LIMIT);

  const strokes = rows.map(r => ({ ...r, data: JSON.parse(r.data) }));
  const hasMore = rows.length === STROKES_PAGE_LIMIT;
  const pageRow = db.prepare('SELECT template, name FROM classroom_pages WHERE session_id=? AND page_num=?').get(sessionId, pageNum);
  res.json({ strokes, template: pageRow?.template || 'blank', name: pageRow?.name || null, hasMore });
}

function updateStroke(req, res) {
  const sessionId = Number(req.params.id);
  const strokeId  = Number(req.params.strokeId);
  const { data }  = req.body;
  if (!data) return res.status(400).json({ error: 'data required' });

  const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (!canDraw(sessionId, req.user.id, session) && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  const existing = db.prepare('SELECT id, page_num, user_id FROM classroom_strokes WHERE id=? AND session_id=?').get(strokeId, sessionId);
  if (!existing) return res.status(404).json({ error: 'Штрих не найден' });
  if (existing.user_id !== req.user.id && session.teacher_id !== req.user.id && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  db.prepare('UPDATE classroom_strokes SET data=? WHERE id=?').run(JSON.stringify(data), strokeId);
  emitToSession(sessionId, { type: 'classroom_stroke_updated', sessionId, strokeId, pageNum: existing.page_num, data });
  res.json({ ok: true });
}

function deleteStroke(req, res) {
  const sessionId = Number(req.params.id);
  const strokeId  = Number(req.params.strokeId);
  const session   = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (session.teacher_id !== req.user.id && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  const stroke = db.prepare('SELECT page_num FROM classroom_strokes WHERE id=? AND session_id=?').get(strokeId, sessionId);
  if (!stroke) return res.status(404).json({ error: 'Штрих не найден' });

  db.prepare('DELETE FROM classroom_strokes WHERE id=?').run(strokeId);
  emitToSession(sessionId, { type: 'classroom_stroke_deleted', sessionId, strokeId, pageNum: stroke.page_num });
  res.json({ ok: true });
}

function clearPage(req, res) {
  const sessionId  = Number(req.params.id);
  const { page_num = 1 } = req.body;
  const pageNumInt = Number(page_num);
  if (!Number.isInteger(pageNumInt) || pageNumInt < 1)
    return res.status(400).json({ error: 'Некорректный номер страницы' });
  const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (session.teacher_id !== req.user.id && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  db.prepare('DELETE FROM classroom_strokes WHERE session_id=? AND page_num=?').run(sessionId, pageNumInt);
  emitToSession(sessionId, { type: 'classroom_page_cleared', sessionId, pageNum: pageNumInt });
  res.json({ ok: true });
}

function previewStroke(req, res) {
  const sessionId = Number(req.params.id);
  const { live_id, tool, data, page_num = 1, cancel } = req.body;
  if (!live_id) return res.status(400).json({ error: 'live_id required' });

  const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (!canDraw(sessionId, req.user.id, session) && req.user.role !== 'admin')
    return res.status(403).json({ error: 'Нет доступа' });

  emitToSession(sessionId, {
    type: 'classroom_stroke_preview', sessionId, pageNum: Number(page_num),
    liveId: live_id, tool, data, cancel: cancel || false,
    userId: req.user.id, userName: req.user.name || req.user.email,
  });
  res.json({ ok: true });
}

function broadcastCursor(req, res) {
  const sessionId = Number(req.params.id);
  const { x, y, page_num = 1 } = req.body;
  const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId);
  if (!session) return res.status(404).json({ error: 'Сессия не активна' });
  if (!hasAccess(session, req.user.id, req.user.role)) return res.status(403).json({ error: 'Нет доступа' });

  emitToSession(sessionId, {
    type: 'classroom_cursor', sessionId, x, y, pageNum: Number(page_num),
    userId: req.user.id, userName: req.user.name || req.user.email,
  });
  res.json({ ok: true });
}

module.exports = { postStrokes, getStrokes, updateStroke, deleteStroke, clearPage, previewStroke, broadcastCursor };
