'use strict';
const db   = require('../../db/db');
const path = require('path');
const fs   = require('fs');
const { emitToUser } = require('../../ws-server');
const { emitToSession, hasAccess } = require('./_shared');

const CHAT_UPLOADS_DIR = path.join(__dirname, '../../../uploads/chat');
if (!fs.existsSync(CHAT_UPLOADS_DIR)) fs.mkdirSync(CHAT_UPLOADS_DIR, { recursive: true });

const ALLOWED_REACTIONS = ['like', 'heart', 'question', 'idea', 'wow'];

function sendChat(req, res) {
  const sessionId = Number(req.params.id);
  const { message = '', attachment_url, attachment_type } = req.body;
  const text    = message.trim().slice(0, 2000);
  const safeUrl = attachment_url && typeof attachment_url === 'string' && attachment_url.startsWith('/uploads/')
    ? attachment_url : null;
  if (!text && !safeUrl) 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 (!hasAccess(session, req.user.id, req.user.role)) return res.status(403).json({ error: 'Нет доступа' });

  const { lastInsertRowid } = db.prepare(
    'INSERT INTO classroom_chat (session_id, user_id, message, attachment_url, attachment_type) VALUES (?,?,?,?,?)'
  ).run(sessionId, req.user.id, text, safeUrl, safeUrl ? (attachment_type || null) : null);

  const row = db.prepare('SELECT * FROM classroom_chat WHERE id=?').get(lastInsertRowid);
  emitToSession(sessionId, {
    type: 'classroom_chat', sessionId,
    id: row.id, userId: req.user.id, userName: req.user.name, message: text,
    createdAt: row.created_at, attachmentUrl: row.attachment_url || null, attachmentType: row.attachment_type || null,
  });
  res.json(row);
}

function getChat(req, res) {
  const sessionId = Number(req.params.id);
  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 sinceId  = Number(req.query.since_id) || 0;
  const messages = sinceId
    ? db.prepare(`SELECT c.*, u.name AS user_name FROM classroom_chat c
        JOIN users u ON u.id = c.user_id
        WHERE c.session_id=? AND c.id > ? ORDER BY c.id ASC LIMIT 100`).all(sessionId, sinceId)
    : db.prepare(`SELECT c.*, u.name AS user_name FROM classroom_chat c
        JOIN users u ON u.id = c.user_id
        WHERE c.session_id=? ORDER BY c.id DESC LIMIT 200`).all(sessionId).reverse();

  if (messages.length > 0) {
    const ids      = messages.map(m => m.id);
    const reactions = db.prepare(
      `SELECT chat_id, reaction, COUNT(*) AS cnt, GROUP_CONCAT(user_id) AS uids
       FROM classroom_chat_reactions
       WHERE chat_id IN (${ids.map(() => '?').join(',')})
       GROUP BY chat_id, reaction`
    ).all(...ids);
    const rmap = {};
    reactions.forEach(r => {
      if (!rmap[r.chat_id]) rmap[r.chat_id] = {};
      rmap[r.chat_id][r.reaction] = { count: r.cnt, mine: (r.uids || '').split(',').includes(String(req.user.id)) };
    });
    messages.forEach(m => { m.reactions = rmap[m.id] || {}; });
  }
  res.json({ messages });
}

function pinMessage(req, res) {
  const sessionId = Number(req.params.id);
  const msgId     = Number(req.params.msgId);
  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 msg = db.prepare('SELECT * FROM classroom_chat WHERE id=? AND session_id=?').get(msgId, sessionId);
  if (!msg) return res.status(404).json({ error: 'Сообщение не найдено' });

  const newPinned = msg.pinned ? 0 : 1;
  db.prepare('UPDATE classroom_chat SET pinned=? WHERE id=?').run(newPinned, msgId);
  emitToSession(sessionId, { type: 'classroom_message_pinned', sessionId, msgId, pinned: !!newPinned, message: msg.message });
  res.json({ ok: true, pinned: !!newPinned });
}

function reactToMessage(req, res) {
  const chatId    = Number(req.params.msgId);
  const { reaction } = req.body;
  if (!ALLOWED_REACTIONS.includes(reaction)) return res.status(400).json({ error: 'Неизвестная реакция' });

  const msg = db.prepare('SELECT * FROM classroom_chat WHERE id=?').get(chatId);
  if (!msg) return res.status(404).json({ error: 'Сообщение не найдено' });

  const session = db.prepare('SELECT * FROM classroom_sessions WHERE id=?').get(msg.session_id);
  if (!session || !hasAccess(session, req.user.id, req.user.role))
    return res.status(403).json({ error: 'Нет доступа' });

  const existing = db.prepare('SELECT id FROM classroom_chat_reactions WHERE chat_id=? AND user_id=? AND reaction=?').get(chatId, req.user.id, reaction);
  let added;
  if (existing) {
    db.prepare('DELETE FROM classroom_chat_reactions WHERE id=?').run(existing.id);
    added = false;
  } else {
    db.prepare('INSERT INTO classroom_chat_reactions (chat_id, user_id, reaction) VALUES (?,?,?)').run(chatId, req.user.id, reaction);
    added = true;
  }

  const counts = db.prepare(`SELECT reaction, COUNT(*) AS cnt, GROUP_CONCAT(user_id) AS uids
    FROM classroom_chat_reactions WHERE chat_id=? GROUP BY reaction`).all(chatId);
  const reactionsMap = {};
  counts.forEach(r => { reactionsMap[r.reaction] = { count: r.cnt, uids: r.uids }; });

  emitToSession(msg.session_id, { type: 'classroom_reaction', sessionId: msg.session_id, chatId, reaction, userId: req.user.id, added, reactions: reactionsMap });
  res.json({ ok: true, added, reactions: reactionsMap });
}

function uploadChatAttachment(req, res) {
  if (!req.file) return res.status(400).json({ error: 'Файл не получен' });
  const url  = `/uploads/chat/${req.file.filename}`;
  const type = req.file.mimetype.startsWith('image/') ? 'image' : 'file';
  res.json({ url, type, name: req.file.originalname });
}

function exportChat(req, res) {
  const sessionId = Number(req.params.id);
  const session   = db.prepare('SELECT * FROM classroom_sessions WHERE id=?').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 messages = db.prepare(`
    SELECT c.created_at, u.name AS user_name, c.message, c.attachment_url
    FROM classroom_chat c JOIN users u ON u.id = c.user_id
    WHERE c.session_id=? ORDER BY c.id ASC
  `).all(sessionId);

  const title = session.title || `Урок #${sessionId}`;
  const date  = session.created_at ? new Date(session.created_at).toLocaleDateString('ru-RU') : '';
  let text    = `Чат урока: ${title}\nДата: ${date}\n${'─'.repeat(50)}\n\n`;
  messages.forEach(m => {
    const ts = m.created_at ? new Date(m.created_at).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' }) : '';
    const safeUser = (m.user_name || '').replace(/[\r\n]/g, ' ');
    const safeMsg  = (m.message  || '').replace(/[\r\n]/g, ' ');
    text += `[${ts}] ${safeUser}: ${safeMsg}`;
    if (m.attachment_url) text += ` [вложение]`;
    text += '\n';
  });

  const filename = `chat_${sessionId}_${date.replace(/\./g, '-')}.txt`;
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
  res.send(text);
}

module.exports = {
  CHAT_UPLOADS_DIR, ALLOWED_REACTIONS,
  sendChat, getChat, pinMessage, reactToMessage, uploadChatAttachment, exportChat,
};
