const { query, getClient } = require('../config/db');

// ─────────────────────────────────────────────────────────────────
// GET /api/leave/balances
// Returns current user's leave balances for the current year.
// Used by Step 1 balance cards.
// Query: ?year=2026  (optional, defaults to current year)
// ─────────────────────────────────────────────────────────────────
async function getMyBalances(req, res) {
  const { id: user_id, org_id } = req.user;
  const year = parseInt(req.query.year) || new Date().getFullYear();

  try {
    const { rows } = await query(
      `SELECT
         lb.id,
         lt.name        AS type,
         lt.color,
         lt.is_paid,
         lb.total_days  AS total,
         lb.used_days   AS used,
         (lb.total_days - lb.used_days) AS remaining
       FROM leave_balances lb
       JOIN leave_types lt ON lt.id = lb.leave_type_id
       WHERE lb.user_id = $1
         AND lb.year    = $2
         AND lb.org_id  = $3
         AND lb.is_deleted = false
         AND lt.is_deleted = false
       ORDER BY lt.name`,
      [user_id, year, org_id]
    );
    res.json({ success: true, data: rows });
  } catch (err) {
    console.error('getMyBalances:', err);
    res.status(500).json({ success: false, message: 'Internal server error' });
  }
}

// ─────────────────────────────────────────────────────────────────
// GET /api/leave/balances/user/:userId
// HR/manager view — balances for any employee
// ─────────────────────────────────────────────────────────────────
async function getUserBalances(req, res) {
  const { org_id } = req.user;
  const { userId } = req.params;
  const year = parseInt(req.query.year) || new Date().getFullYear();

  try {
    const { rows } = await query(
      `SELECT
         lb.id,
         lt.name        AS type,
         lt.color,
         lt.is_paid,
         lb.total_days  AS total,
         lb.used_days   AS used,
         (lb.total_days - lb.used_days) AS remaining
       FROM leave_balances lb
       JOIN leave_types lt ON lt.id = lb.leave_type_id
       WHERE lb.user_id = $1
         AND lb.year    = $2
         AND lb.org_id  = $3
         AND lb.is_deleted = false
         AND lt.is_deleted = false
       ORDER BY lt.name`,
      [userId, year, org_id]
    );
    res.json({ success: true, data: rows });
  } catch (err) {
    console.error('getUserBalances:', err);
    res.status(500).json({ success: false, message: 'Internal server error' });
  }
}

// ─────────────────────────────────────────────────────────────────
// POST /api/leave/balances/init/:userId
// HR only — initialise balances for a user for a given year.
// Creates one row per active leave_type for the org.
// Body: { year? }  defaults to current year
// ─────────────────────────────────────────────────────────────────
async function initUserBalances(req, res) {
  const { org_id, id: created_by } = req.user;
  const { userId } = req.params;
  const year = parseInt(req.body.year) || new Date().getFullYear();

  const client = await getClient();
  try {
    await client.query('BEGIN');

    const types = await client.query(
      `SELECT id, default_days_per_year FROM leave_types
       WHERE org_id = $1 AND is_deleted = false`,
      [org_id]
    );

    const inserted = [];
    for (const lt of types.rows) {
      const { rows } = await client.query(
        `INSERT INTO leave_balances
           (user_id, leave_type_id, year, total_days, org_id, created_by)
         VALUES ($1, $2, $3, $4, $5, $6)
         ON CONFLICT (user_id, leave_type_id, year) DO NOTHING
         RETURNING id`,
        [userId, lt.id, year, lt.default_days_per_year, org_id, created_by]
      );
      if (rows.length) inserted.push(rows[0].id);
    }

    await client.query('COMMIT');
    res.status(201).json({
      success: true,
      message: `${inserted.length} balance(s) initialised for year ${year}`,
    });
  } catch (err) {
    await client.query('ROLLBACK');
    console.error('initUserBalances:', err);
    res.status(500).json({ success: false, message: 'Internal server error' });
  } finally {
    client.release();
  }
}

// ─────────────────────────────────────────────────────────────────
// PATCH /api/leave/balances/:id
// HR only — manually adjust total_days for a balance row
// Body: { total_days }
// ─────────────────────────────────────────────────────────────────
async function updateBalance(req, res) {
  const { id } = req.params;
  const { total_days } = req.body;
  const { org_id, id: updated_by } = req.user;

  if (total_days === undefined) {
    return res.status(422).json({ success: false, message: 'total_days is required' });
  }

  try {
    const { rows } = await query(
      `UPDATE leave_balances
       SET total_days = $1, updated_by = $2, updated_at = NOW()
       WHERE id = $3 AND org_id = $4 AND is_deleted = false
       RETURNING id, total_days, used_days`,
      [total_days, updated_by, id, org_id]
    );
    if (!rows.length) return res.status(404).json({ success: false, message: 'Balance record not found' });
    res.json({ success: true, data: rows[0] });
  } catch (err) {
    console.error('updateBalance:', err);
    res.status(500).json({ success: false, message: 'Internal server error' });
  }
}

module.exports = { getMyBalances, getUserBalances, initUserBalances, updateBalance };