'use strict';
const { db } = require('../utils/dbName');

const express  = require('express');
const router   = express.Router();
const { getPool, sql } = require('../db');
const { sanitizeDate } = require('../utils/validate');
const { localDateStr } = require('../utils/localDate');

const NOMBRES = ['1er Turno', '2do Turno', '3er Turno', '4to Turno', '5to Turno'];

function ventasUnionSql(alias = 'tr') {
  return `(
    SELECT folio, fecha, idturno, cancelado, pagado, total
    FROM ${db()}cheques
    WHERE cancelado = 0 AND pagado = 1 AND total > 0
    UNION ALL
    SELECT folio, fecha, idturno, cancelado, pagado, total
    FROM ${db()}tempcheques ${alias}tc
    WHERE ISNULL(${alias}tc.cancelado, 0) = 0
      AND ISNULL(${alias}tc.pagado, 0) = 1
      AND ISNULL(${alias}tc.total, 0) > 0
      AND NOT EXISTS (
        SELECT 1 FROM ${db()}cheques ${alias}ch
        WHERE ${alias}ch.folio = ${alias}tc.folio
          AND CAST(${alias}ch.fecha AS DATE) = CAST(${alias}tc.fecha AS DATE)
          AND ${alias}ch.cancelado = 0
          AND ${alias}ch.pagado = 1
      )
  )`;
}

// ─── Query base reutilizable ────────────────────────────────────────────────
async function queryTurnos(whereClause, request) {
  const result = await request.query(`
    SELECT
      t.idturno,
      t.apertura                           AS apertura,
      CASE WHEN t.cierre IS NULL THEN NULL
           ELSE t.cierre END               AS cierre,
      t.cajero,
      t.idestacion,
      CAST(t.apertura AS DATE)             AS fecha_turno,
      ISNULL(COUNT(c.folio), 0)                 AS tickets,
      ROUND(ISNULL(SUM(c.total), 0), 2)         AS venta_total,
      ROUND(
        ISNULL(SUM(c.total), 0) /
        NULLIF(COUNT(DISTINCT c.folio), 0)
      , 2)                                      AS ticket_promedio
    FROM ${db()}turnos t
    LEFT JOIN ${ventasUnionSql('turn_')} c
        ON t.idturno   = c.idturno
       AND c.cancelado = 0
       AND c.pagado    = 1
       AND c.total     > 0
    WHERE ${whereClause}
    GROUP BY t.idturno, t.apertura, t.cierre, t.cajero, t.idestacion
    ORDER BY t.apertura
  `);
  return result.recordset;
}

// ─── Turnos de hoy ──────────────────────────────────────────────────────────
router.get('/hoy', async (req, res, next) => {
  try {
    const pool    = await getPool();
    const request = pool.request().input('rt_hoy', sql.VarChar(10), localDateStr());
    // Fechas en hora local SQL/SoftRestaurant; no aplicar offset manual.
    const rows    = await queryTurnos(`CAST(t.apertura AS DATE) = CONVERT(date, @rt_hoy, 23)`, request);

    const data = rows.map((t, i) => ({
      ...t,
      nombre_turno: NOMBRES[i] || `Turno ${i + 1}`,
    }));

    res.json({ ok: true, data });
  } catch (err) {
    next(err);
  }
});


// ─── Turnos por fecha específica (para selector en productos-cancelados) ──────
router.get('/por-fecha', async (req, res, next) => {
  try {
    const pool   = await getPool();
    const fecha  = sanitizeDate(req.query.fecha) || localDateStr();
    const request = pool.request().input('pf_fecha', sql.VarChar(10), fecha);
    const rows   = await queryTurnos(
      `CAST(t.apertura AS DATE) = CONVERT(date, @pf_fecha, 23)`, request
    );
    const data = rows.map((t, i) => ({
      ...t,
      nombre_turno: NOMBRES[i] || `Turno ${i + 1}`,
    }));
    res.json({ ok: true, data });
  } catch (err) { next(err); }
});

// ─── Histórico de turnos por rango de fechas ─────────────────────────────────
router.get('/historial', async (req, res, next) => {
  try {
    const pool  = await getPool();
    const desde = sanitizeDate(req.query.fechaDesde || req.query.desde);
    const hasta = sanitizeDate(req.query.fechaHasta || req.query.hasta);
    const fecha = sanitizeDate(req.query.fecha);

    const request = pool.request();
    let where;

    if (desde && hasta) {
      request.input('rh_desde', sql.VarChar(10), desde);
      request.input('rh_hasta', sql.VarChar(10), hasta);
      // Fechas en hora local SQL/SoftRestaurant
      where = `CAST(t.apertura AS DATE) BETWEEN CONVERT(date, @rh_desde, 23) AND CONVERT(date, @rh_hasta, 23)`;
    } else if (fecha) {
      request.input('rh_fecha', sql.VarChar(10), fecha);
      where = `CAST(t.apertura AS DATE) = CONVERT(date, @rh_fecha, 23)`;
    } else {
      request.input('rh_hoy', sql.VarChar(10), localDateStr());
      where = `CAST(t.apertura AS DATE) = CONVERT(date, @rh_hoy, 23)`;
    }

    const rows = await queryTurnos(where, request);

    // Agrupar por fecha y asignar nombre_turno dentro de cada día
    const porFecha = {};
    rows.forEach(t => {
      const f = t.fecha_turno instanceof Date
        ? localDateStr(t.fecha_turno)
        : String(t.fecha_turno).split('T')[0];
      if (!porFecha[f]) porFecha[f] = [];
      porFecha[f].push(t);
    });

    const data = [];
    Object.keys(porFecha).sort().forEach(f => {
      porFecha[f].forEach((t, i) => {
        data.push({ ...t, nombre_turno: NOMBRES[i] || `Turno ${i + 1}` });
      });
    });

    res.json({ ok: true, data });
  } catch (err) {
    next(err);
  }
});

module.exports = router;
