/**
 * Social Controller
 * Handles student social documents
 *
 * Visibility: teachers + admin/principal/HR (school leadership).
 * Students and parents do NOT see this — it contains sensitive info
 * (medical notes, family situation, past behavior). The student themself
 * can review their own row only if the school explicitly enables that via
 * an admin role flag (not implemented yet).
 */

const express = require('express');
const router = express.Router();
const path = require('path');
const Database = require('better-sqlite3');
const { v4: uuidv4 } = require('uuid');

const dbPath = process.env.DB_PATH || path.join(__dirname, '../../data/school.db');
const db = new Database(dbPath);
db.pragma('foreign_keys = ON');

// Auth middleware
const auth = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'No token provided' });
  try {
    const jwt = require('jsonwebtoken');
    const { jwtSecret: JWT_SECRET } = require('../config');
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Roles allowed to view / edit student social documents.
// Teachers use these when they need to understand a student (especially
// across the year-boundary handover). Admins/principal/HR use them for
// pastoral oversight. Students/parents/librarian/etc. are explicitly excluded.
const SOCIAL_ACCESS_ROLES = [
  'teacher',
  'school_admin',
  'systems_admin',
  'principal',
  'hr',
];

const staffOnly = (req, res, next) => {
  if (!SOCIAL_ACCESS_ROLES.includes(req.user.role)) {
    return res.status(403).json({
      error: 'Staff access required. Student social documents contain confidential pastoral information.',
    });
  }
  next();
};

// ============ STUDENT SOCIAL DOCUMENTS ============

/**
 * @openapi
 * /api/social/student-docs:
 *   get:
 *     summary: List every student's social document
 *     description: |
 *       Oversight view of all student social documents (medical notes,
 *       family situation, past behaviour, etc.). Restricted to staff
 *       roles (`teacher`, `school_admin`, `systems_admin`, `principal`,
 *       `hr`).
 *     tags:
 *       - Social
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: class_id
 *         schema: { type: integer }
 *         description: Restrict to one class
 *       - in: query
 *         name: search
 *         schema: { type: string }
 *         description: Match against first/last name (LIKE %term%)
 *     responses:
 *       200:
 *         description: Array of student social documents with joined user info
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Staff access required }
 *       500: { description: Server error }
 *   post:
 *     summary: Create or update a student social document
 *     description: |
 *       Upserts the social document for a single student. Restricted to
 *       staff roles (`teacher`, `school_admin`, `systems_admin`,
 *       `principal`, `hr`).
 *     tags:
 *       - Social
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - student_id
 *             properties:
 *               student_id: { type: integer }
 *               learner_type: { type: string }
 *               past_behavior: { type: string }
 *               family_size:
 *                 type: integer
 *                 nullable: true
 *               parents_available: { type: string }
 *               home_environment: { type: string }
 *               medical_notes: { type: string }
 *               social_strengths: { type: string }
 *               social_challenges: { type: string }
 *               interests: { type: string }
 *               other_data: { type: string }
 *     responses:
 *       200:
 *         description: Document created or updated
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success: { type: boolean }
 *                 message: { type: string }
 *                 id: { type: integer }
 *                 uid:
 *                   type: string
 *                   description: Present only on create
 *       400: { description: student_id does not refer to a valid student }
 *       401: { description: Unauthorized }
 *       403: { description: Staff access required }
 *       500: { description: Server error }
 */
router.get('/student-docs', auth, staffOnly, (req, res) => {
  try {
    const { class_id, search } = req.query;
    let query = `
      SELECT sd.*, u.first_name, u.last_name, u.email, c.name AS class_name, c.section AS class_section
      FROM student_social_docs sd
      JOIN users u ON sd.student_id = u.id
      LEFT JOIN enrollments e ON e.student_id = u.id AND e.status = 'active' AND e.is_deleted = 0
      LEFT JOIN classes c ON e.class_id = c.id AND c.is_deleted = 0
      WHERE sd.is_deleted = 0 AND u.is_deleted = 0
    `;
    const params = [];
    if (class_id) { query += ' AND c.id = ?'; params.push(class_id); }
    if (search) {
      query += ' AND (u.first_name LIKE ? OR u.last_name LIKE ?)';
      const term = `%${search}%`;
      params.push(term, term);
    }
    query += ' GROUP BY sd.id ORDER BY u.last_name, u.first_name';
    res.json(db.prepare(query).all(...params));
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

/**
 * @openapi
 * /api/social/student-docs/{student_uid}:
 *   get:
 *     summary: Get a single student's social document
 *     description: |
 *       Fetches a student's social document by their user uid. If no
 *       document exists yet, returns an empty placeholder so the UI can
 *       render an "Edit Document" affordance instead of a 404. Restricted
 *       to staff roles (`teacher`, `school_admin`, `systems_admin`,
 *       `principal`, `hr`).
 *     tags:
 *       - Social
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: student_uid
 *         required: true
 *         schema: { type: string, format: uuid }
 *         description: User uid of the student
 *     responses:
 *       200:
 *         description: "Social document, or placeholder object flagged with _empty=true when no doc exists yet"
 *         content:
 *           application/json:
 *             schema: { type: object }
 *       401: { description: Unauthorized }
 *       403: { description: Staff access required }
 *       404: { description: Student not found }
 *       500: { description: Server error }
 */
router.get('/student-docs/:student_uid', auth, staffOnly, (req, res) => {
  try {
    const student = db.prepare(
      "SELECT id, first_name, last_name FROM users WHERE uid = ? AND is_deleted = 0 AND role = 'student'"
    ).get(req.params.student_uid);
    if (!student) return res.status(404).json({ error: 'Student not found' });

    const doc = db.prepare(`
      SELECT sd.*, u.first_name, u.last_name
      FROM student_social_docs sd
      JOIN users u ON sd.student_id = u.id
      WHERE u.uid = ? AND sd.is_deleted = 0
    `).get(req.params.student_uid);

    if (doc) return res.json(doc);

    // Return a placeholder so the UI knows the student exists but no doc yet.
    res.json({
      student_id: student.id,
      student_uid: req.params.student_uid,
      first_name: student.first_name,
      last_name: student.last_name,
      learner_type: null,
      past_behavior: null,
      family_size: null,
      parents_available: null,
      home_environment: null,
      medical_notes: null,
      social_strengths: null,
      social_challenges: null,
      interests: null,
      other_data: null,
      _empty: true,
    });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.post('/student-docs', auth, staffOnly, (req, res) => {
  const { student_id, learner_type, past_behavior, family_size, parents_available, home_environment, medical_notes, social_strengths, social_challenges, interests, other_data } = req.body;

  // Validate student_id actually points at a student
  const student = db.prepare("SELECT id FROM users WHERE id = ? AND role = 'student' AND is_deleted = 0").get(student_id);
  if (!student) return res.status(400).json({ error: 'student_id does not refer to a valid student' });

  // Coerce family_size to int (or null)
  const famSize = family_size === '' || family_size == null ? null : parseInt(family_size, 10);

  // Check if it already exists
  const existing = db.prepare('SELECT id FROM student_social_docs WHERE student_id = ? AND is_deleted = 0').get(student_id);

  if (existing) {
    db.prepare(`
      UPDATE student_social_docs
      SET learner_type = ?, past_behavior = ?, family_size = ?, parents_available = ?, home_environment = ?, medical_notes = ?, social_strengths = ?, social_challenges = ?, interests = ?, other_data = ?, updated_by = ?, updated_at = CURRENT_TIMESTAMP, sync_status = 'pending'
      WHERE id = ?
    `).run(learner_type, past_behavior, famSize, parents_available, home_environment, medical_notes, social_strengths, social_challenges, interests, other_data, req.user.id, existing.id);
    return res.json({ success: true, message: 'Document updated', id: existing.id });
  }

  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO student_social_docs (uid, student_id, learner_type, past_behavior, family_size, parents_available, home_environment, medical_notes, social_strengths, social_challenges, interests, other_data, updated_by, sync_status)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
  `).run(uid, student_id, learner_type, past_behavior, famSize, parents_available, home_environment, medical_notes, social_strengths, social_challenges, interests, other_data, req.user.id);
  res.json({ id: result.lastInsertRowid, uid, message: 'Document created' });
});

module.exports = router;
