// routes/charger_sessions.js
const express = require('express');
const { param, query, body, validationResult } = require('express-validator');
const router = express.Router();
const verifyToken = require('../middleware/verifyToken');
const db = require('../db');

router.use(verifyToken);

function handleValidation(req, res, next) {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ success: false, errors: errors.array() });
  }
  next();
}

// GET /api/charger_sessions?chargerId=...
router.get(
  '/',
  [query('chargerId').isUUID().withMessage('chargerId deve ser UUID válido')],
  handleValidation,
  async (req, res) => {
    const { chargerId } = req.query;
    const userId = req.user.id;

    const charger = await db('chargers')
      .where({ id: chargerId, user_id: userId })
      .first();

    if (!charger) {
      return res
        .status(403)
        .json({ success: false, message: 'Acesso não autorizado' });
    }

    const sessions = await db('charger_sessions')
      .where({ charger_id: chargerId })
      .orderBy('started_at', 'desc');

    res.json({ success: true, data: sessions });
  }
);

// GET /api/charger_sessions/:id
router.get(
  '/:id',
  [param('id').isUUID().withMessage('ID de sessão inválido')],
  handleValidation,
  async (req, res) => {
    const { id } = req.params;
    const userId = req.user.id;

    const session = await db('charger_sessions')
      .join('chargers', 'charger_sessions.charger_id', 'chargers.id')
      .where({ 'charger_sessions.id': id, 'chargers.user_id': userId })
      .select('charger_sessions.*')
      .first();

    if (!session) {
      return res
        .status(404)
        .json({ success: false, message: 'Sessão não encontrada' });
    }

    res.json({ success: true, data: session });
  }
);

// POST /api/charger_sessions
router.post(
  '/',
  [body('charger_id').isUUID().withMessage('charger_id deve ser UUID válido')],
  handleValidation,
  async (req, res) => {
    const { charger_id } = req.body;
    const userId = req.user.id;

    const charger = await db('chargers')
      .where({ id: charger_id, user_id: userId })
      .first();

    if (!charger) {
      return res
        .status(403)
        .json({ success: false, message: 'Acesso não autorizado' });
    }

    const [inserted] = await db('charger_sessions')
      .insert({ charger_id, started_at: new Date() })
      .returning('*');

    res.status(201).json({ success: true, data: inserted });
  }
);

// PUT /api/charger_sessions/:id
router.put(
  '/:id',
  [
    param('id').isUUID().withMessage('ID de sessão inválido'),
    body('ended_at').optional().isISO8601().toDate(),
    body('kwh').optional().isFloat({ min: 0 }),
    body('cost').optional().isFloat({ min: 0 }),
  ],
  handleValidation,
  async (req, res) => {
    const { id } = req.params;
    const { ended_at, kwh, cost } = req.body;
    const userId = req.user.id;

    const session = await db('charger_sessions')
      .join('chargers', 'charger_sessions.charger_id', 'chargers.id')
      .where({ 'charger_sessions.id': id, 'chargers.user_id': userId })
      .first();

    if (!session) {
      return res
        .status(404)
        .json({ success: false, message: 'Sessão não encontrada' });
    }

    const [updated] = await db('charger_sessions')
      .where({ id })
      .update({ ended_at, kwh, cost })
      .returning('*');

    res.json({ success: true, data: updated });
  }
);

// DELETE /api/charger_sessions/:id
router.delete(
  '/:id',
  [param('id').isUUID().withMessage('ID de sessão inválido')],
  handleValidation,
  async (req, res) => {
    const { id } = req.params;
    const userId = req.user.id;

    const deleted = await db('charger_sessions')
      .join('chargers', 'charger_sessions.charger_id', 'chargers.id')
      .where({ 'charger_sessions.id': id, 'chargers.user_id': userId })
      .del();

    if (!deleted) {
      return res
        .status(404)
        .json({ success: false, message: 'Sessão não encontrada' });
    }

    res.json({ success: true, message: 'Sessão excluída com sucesso' });
  }
);

// GET /api/charger_sessions/history/:chargerId
router.get(
  '/history/:chargerId',
  [
    param('chargerId').isUUID().withMessage('chargerId deve ser UUID válido'),
    query('viewMode')
      .isIn(['Day', 'Week', 'Month'])
      .withMessage('viewMode inválido'),
  ],
  handleValidation,
  async (req, res) => {
    const { chargerId } = req.params;
    const { viewMode } = req.query;
    const userId = req.user.id;

    // ownership check
    const charger = await db('chargers')
      .where({ id: chargerId, user_id: userId })
      .first();

    if (!charger) {
      return res
        .status(403)
        .json({ success: false, message: 'Acesso não autorizado' });
    }

    let qb = db('charger_sessions')
      .where({ charger_id: chargerId })
      .sum('kwh as total_kwh');

    switch (viewMode) {
      case 'Day':
        qb = qb
          .select(db.raw('DATE(started_at) AS period'))
          .groupBy(db.raw('DATE(started_at)'))
          .orderBy('period', 'desc');
        break;

      case 'Week':
        qb = qb
          .select(
            db.raw('EXTRACT(ISOYEAR FROM started_at) AS y'),
            db.raw('EXTRACT(WEEK FROM started_at) AS w'),
            db.raw(
              "EXTRACT(ISOYEAR FROM started_at)||'-'||LPAD(EXTRACT(WEEK FROM started_at)::text,2,'0') AS period"
            )
          )
          .groupBy('y', 'w')
          .orderBy([{ column: 'y', order: 'desc' }, { column: 'w', order: 'desc' }]);
        break;

      case 'Month':
        qb = qb
          .select(
            db.raw('EXTRACT(YEAR FROM started_at) AS y'),
            db.raw('EXTRACT(MONTH FROM started_at) AS m'),
            db.raw(
              "EXTRACT(YEAR FROM started_at)||'-'||LPAD(EXTRACT(MONTH FROM started_at)::text,2,'0') AS period"
            )
          )
          .groupBy('y', 'm')
          .orderBy([{ column: 'y', order: 'desc' }, { column: 'm', order: 'desc' }]);
        break;
    }

    const rows = await qb;

    // ✅ devolve lista vazia em vez de 404
    if (!rows.length) {
      return res.json({ success: true, data: [] });
    }

    const data = rows.map((r) => ({
      started_at: r.period,
      kwh: parseFloat(r.total_kwh) || 0,
    }));

    res.json({ success: true, data });
  }
);

module.exports = router;
