/**
 * HR Controller
 * Handles staff roles, salary grades, records, leave, and attendance
 */

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 JWT_SECRET = process.env.JWT_SECRET || 'africa-alert-secret-key-2024';
    req.user = jwt.verify(token, JWT_SECRET);
    next();
  } catch (err) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

const hrAccess = (req, res, next) => {
  const allowedRoles = ['admin', 'principal', 'hr'];
  if (!allowedRoles.includes(req.user.role)) {
    return res.status(403).json({ error: 'HR, Principal or Admin access required' });
  }
  next();
};

const adminOnly = (req, res, next) => {
  if (req.user.role !== 'admin' && req.user.role !== 'principal') {
    return res.status(403).json({ error: 'Admin or Principal access required' });
  }
  next();
};

// ============ STAFF ROLES ============

router.get('/roles', auth, hrAccess, (req, res) => {
  const roles = db.prepare('SELECT * FROM staff_roles WHERE is_deleted = 0').all();
  res.json(roles);
});

router.post('/roles', auth, adminOnly, (req, res) => {
  const { name, description, is_teaching_role, permissions } = req.body;
  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO staff_roles (uid, name, description, is_teaching_role, permissions, sync_status)
    VALUES (?, ?, ?, ?, ?, 'pending')
  `).run(uid, name, description, is_teaching_role ? 1 : 0, permissions);
  res.json({ id: result.lastInsertRowid, uid });
});

// ============ SALARY GRADES ============

router.get('/salary-grades', auth, hrAccess, (req, res) => {
  const grades = db.prepare('SELECT * FROM salary_grades WHERE is_deleted = 0').all();
  res.json(grades);
});

router.post('/salary-grades', auth, adminOnly, (req, res) => {
  const { name, grade_level, basic_salary, housing_allowance, transport_allowance, medical_allowance, other_allowances, description, effective_date } = req.body;
  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO salary_grades (uid, name, grade_level, basic_salary, housing_allowance, transport_allowance, medical_allowance, other_allowances, description, effective_date, sync_status)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
  `).run(uid, name, grade_level, basic_salary, housing_allowance, transport_allowance, medical_allowance, other_allowances, description, effective_date);
  res.json({ id: result.lastInsertRowid, uid });
});

// ============ STAFF RECORDS ============

router.get('/records', auth, hrAccess, (req, res) => {
  const records = db.prepare(`
    SELECT sr.*, u.first_name, u.last_name, u.email, r.name as role_name, sg.name as grade_name
    FROM staff_records sr
    JOIN users u ON sr.user_id = u.id
    LEFT JOIN staff_roles r ON sr.role_id = r.id
    LEFT JOIN salary_grades sg ON sr.salary_grade_id = sg.id
    WHERE sr.is_deleted = 0
  `).all();
  res.json(records);
});

router.post('/records', auth, hrAccess, (req, res) => {
  const { user_id, staff_number, role_id, salary_grade_id, employment_type, appointment_date, bank_name, account_number, department, designation } = req.body;
  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO staff_records (uid, user_id, staff_number, role_id, salary_grade_id, employment_type, appointment_date, bank_name, account_number, department, designation, sync_status)
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
  `).run(uid, user_id, staff_number, role_id, salary_grade_id, employment_type, appointment_date, bank_name, account_number, department, designation);
  res.json({ id: result.lastInsertRowid, uid });
});

// ============ LEAVE ============

router.get('/leave-types', auth, hrAccess, (req, res) => {
  const types = db.prepare('SELECT * FROM leave_types WHERE is_deleted = 0').all();
  res.json(types);
});

router.get('/leave-requests', auth, (req, res) => {
  const isPrivileged = ['admin', 'principal', 'hr'].includes(req.user.role);
  
  const query = isPrivileged 
    ? 'SELECT lr.*, u.first_name, u.last_name, lt.name as leave_type FROM leave_requests lr JOIN users u ON lr.staff_id = u.id JOIN leave_types lt ON lr.leave_type_id = lt.id WHERE lr.is_deleted = 0'
    : 'SELECT lr.*, lt.name as leave_type FROM leave_requests lr JOIN leave_types lt ON lr.leave_type_id = lt.id WHERE lr.staff_id = ? AND lr.is_deleted = 0';
  
  const params = isPrivileged ? [] : [req.user.id];
  const requests = db.prepare(query).all(...params);
  res.json(requests);
});

router.post('/leave-requests', auth, (req, res) => {
  const { leave_type_id, start_date, end_date, days_count, reason } = req.body;
  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO leave_requests (uid, staff_id, leave_type_id, start_date, end_date, days_count, reason, sync_status)
    VALUES (?, ?, ?, ?, ?, ?, ?, 'pending')
  `).run(uid, req.user.id, leave_type_id, start_date, end_date, days_count, reason);
  res.json({ id: result.lastInsertRowid, uid });
});

router.put('/leave-requests/:uid/status', auth, hrAccess, (req, res) => {
  const { status, rejection_reason } = req.body;
  db.prepare(`
    UPDATE leave_requests 
    SET status = ?, rejection_reason = ?, approved_by = ?, approved_at = CURRENT_TIMESTAMP, sync_status = 'pending'
    WHERE uid = ?
  `).run(status, rejection_reason, req.user.id, req.params.uid);
  res.json({ success: true });
});

// ============ ATTENDANCE ============

router.get('/attendance', auth, hrAccess, (req, res) => {
  const { date } = req.query;
  const records = db.prepare(`
    SELECT sa.*, u.first_name, u.last_name
    FROM staff_attendance sa
    JOIN users u ON sa.staff_id = u.id
    WHERE sa.date = ? AND sa.is_deleted = 0
  `).all(date || new Date().toISOString().split('T')[0]);
  res.json(records);
});

router.post('/attendance', auth, hrAccess, (req, res) => {
  const { staff_id, date, status, remarks } = req.body;
  const uid = uuidv4();
  const result = db.prepare(`
    INSERT INTO staff_attendance (uid, staff_id, date, status, remarks, marked_by, sync_status)
    VALUES (?, ?, ?, ?, ?, ?, 'pending')
  `).run(uid, staff_id, date, status, remarks, req.user.id);
  res.json({ id: result.lastInsertRowid, uid });
});

module.exports = router;
