const pool = require('../db/connection');
const path = require('path');
const fs = require('fs');
const XLSX = require('xlsx');
const csv = require('csv-parser');
const getincomes = async (req, res) => 
{   
    try{
    const {checkin_initial,checkin_final} = req.body;
    const result = await pool.query('SELECT * FROM getincomesv2($1,$2)',[checkin_initial,checkin_final]);
    const incomereport = result.rows.map(re => ({
      room: re.room,
      occupation: re.occupation,
      income_per_night: re.income_per_night,
      total_income: re.total_income
    }));

    
    res.json({
        message: "Se obtuvieron los ingresos",
        data:incomereport
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos.' });   
    }
};

const getSoftRestaurant = async (req, res) => 
{   
    try{
    //const {checkin_initial,checkin_final} = req.body;
    const result = await pool.query('SELECT * FROM getdataproductsolds()',);
    const incomereport = result.rows.map(re => ({
      id_soldpro: re.id_soldpro,
      clave: re.clave,
      description: re.description,
      group_sp: re.group_sp,
      price: re.price,
      quantity: re.quantity,
      totalsale: re.totalsale,
      cost_sp: re.cost_sp,
      totalcost: re.totalcost,
      salecost: re.salecost,
      catalogprice: re.catalogprice,
      totalsalecatalogprice: re.totalsalecatalogprice,
      vat_rate: re.vat_rate
    }));

    
    res.json({
        message: "Se obtuvieron los ingresos",
        data:incomereport
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos.' });   
    }
};

const getdetallecheques = async (req, res) => 
{   
    try{
    //const {checkin_initial,checkin_final} = req.body;
    const result = await pool.query('SELECT * FROM getchequesdetalles()',);
    const incomereport = result.rows.map(re => ({
      id_cheque: re.id_cheque,
      folio: re.folio,
      fecha: re.fecha,
      descuento: re.descuento,
      importe: re.importe,
      cargo: re.cargo,
      efectivo: re.efectivo,
      tarjeta: re.tarjeta,
      vales: re.vales,
      propina: re.propina,
      OTROS: re.OTROS,
    }));

    
    res.json({
        message: "Se obtuvieron los ingresos",
        data:incomereport
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos.' });   
    }
};

const totalincomes = async (req, res) => 
{   
    try{
    const {checkin_initial,checkin_final} = req.body;
    const result = await pool.query('SELECT totalincomesv2($1,$2) as total',[checkin_initial,checkin_final]);
    const totalincomes = result.rows[0].total;

    res.json({
        message: "Se obtuvieron los ingresos de las fechas seleccionadas",
        data:totalincomes
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos totales.' });   
    }
};

const channelscards = async (req, res) => 
{   
    try{
    const {checkin_initial,checkin_final} = req.body;
    const result = await pool.query('SELECT * from channelscardsv2($1,$2)',[checkin_initial,checkin_final]);
    const incomef = result.rows.map(re => ({
      channel: re.channel,
      total_channel: re.total_channel,
      percentage: re.percentage,
    }));

    res.json({
        message: "Canal donde se obtuvieron más ingresos",
        data:incomef
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el dato' });   
    }
};

const loadincomes = (req, res) => {
  const {nombrearchivo} = req.body;
  const CSV_PATH = `/home/Hotel/backend/hotel_hacienda/src/resources/littleHotelier/${nombrearchivo}`;
  //const CSV_PATH = `C:/Users/otamegane/Desktop/Trabajo_free_lancer/reservations/${nombrearchivo}`;
  const results = [];

  if (!fs.existsSync(CSV_PATH)) {
    return res.status(404).json({
      message: 'El archivo CSV no existe'
    });
  }

  fs.createReadStream(CSV_PATH)
    .pipe(csv())
    .on('data', (row) => {
      results.push(row);
    })
    .on('end', async () => {
      try {
        const result = await pool.query(
          'SELECT insertincomesandtempV2($1::jsonb) AS inserted',
          [JSON.stringify(results)]
        );

        res.json({
          message: 'CSV procesado e insertado en base de datos',
          rows_read: results.length,
          rows_inserted: result.rows[0].inserted
        });

      } catch (error) {
        console.error('Error insertando en BD:', error);
        res.status(500).json({ message: 'Error al insertar datos en BD' });
      }
    })
    .on('error', (err) => {
      console.error('Error leyendo el CSV:', err);
      res.status(500).json({ error: 'No se pudo leer el CSV' });
    });
};

/*const loadsoftrestaurant = (req, res) => {
  const {nombrearchivo} = req.body;
  //const CSV_PATH = `/home/Hotel/backend/hotel_hacienda/src/resources/littleHotelier/${nombrearchivo}`;
  const CSV_PATH = `C:/Users/otamegane/Desktop/Trabajo_free_lancer/reservations/${nombrearchivo}`;
  const results = [];

  if (!fs.existsSync(CSV_PATH)) {
    return res.status(404).json({
      message: 'El archivo CSV no existe'
    });
  }

  fs.createReadStream(CSV_PATH)
    .pipe(csv())
    .on('data', (row) => {
      results.push(row);
    })
    .on('end', async () => {
      try {
        const result = await pool.query(
          'SELECT insertproductsale($1::jsonb) AS inserted',
          [JSON.stringify(results)]
        );

        res.json({
          message: 'CSV procesado e insertado en base de datos',
          rows_read: results.length,
          rows_inserted: result.rows[0].inserted
        });

      } catch (error) {
        console.error('Error insertando en BD:', error);
        res.status(500).json({ message: 'Error al insertar datos en BD' });
      }
    })
    .on('error', (err) => {
      console.error('Error leyendo el CSV:', err);
      res.status(500).json({ error: 'No se pudo leer el CSV' });
    });
};*/

const loadsoftrestaurant = async (req, res) => {
  try {
    const { nombrearchivo } = req.body;
    //const FILE_PATH = `C:/Users/otamegane/Desktop/Trabajo_free_lancer/reservations/${nombrearchivo}`;
    const FILE_PATH = `/home/Hotel/backend/hotel_hacienda/src/resources/littleHotelier/${nombrearchivo}`;
    if (!fs.existsSync(FILE_PATH)) {
      return res.status(404).json({
        message: 'El archivo Excel no existe'
      });
    }

    //Se lee el archivo
    const workbook = XLSX.readFile(FILE_PATH);

    //Toma la primera hoja primera hoja
    const sheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[sheetName];

    //Se convierte a json
    const results = XLSX.utils.sheet_to_json(worksheet, {
      defval: null, 
      range: 4
    });

    //console.log(results[0]);

    if (results.length === 0) {
      return res.status(400).json({
        message: 'El archivo no contiene datos'
      });
    }

    // Insertar en PostgreSQL
    const result = await pool.query(
      'SELECT insertproductsale($1::jsonb) AS inserted',
      [JSON.stringify(results)]
    );

    res.json({
      message: 'Excel procesado e insertado en base de datos',
      rows_read: results.length,
      rows_inserted: result.rows[0].inserted
    });

  } catch (error) {
    console.error('Error procesando Excel:', error);
    res.status(500).json({
      message: 'Error al procesar el archivo Excel'
    });
  }
};

const loadChequesDetalle = async (req, res) => {
  try {
    const { nombrearchivo } = req.body;
    const FILE_PATH = `/home/Hotel/backend/hotel_hacienda/src/resources/littleHotelier/${nombrearchivo}`;
    //const FILE_PATH = `C:/Users/otamegane/Desktop/Trabajo_free_lancer/reservations/${nombrearchivo}`;

    if (!fs.existsSync(FILE_PATH)) {
      return res.status(404).json({
        message: 'El archivo Excel no existe'
      });
    }

    //Se lee el archivo
    const workbook = XLSX.readFile(FILE_PATH);

    //Toma la primera hoja primera hoja
    const sheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[sheetName];

    //Se convierte a json
    const results = XLSX.utils.sheet_to_json(worksheet, {
      defval: null, 
      range: 5
    });

    //console.log(results[0]);

    if (results.length === 0) {
      return res.status(400).json({
        message: 'El archivo no contiene datos'
      });
    }

    // Insertar en PostgreSQL
    const result = await pool.query(
      'SELECT insertchequesdetalles($1::jsonb) AS inserted',
      [JSON.stringify(results)]
    );

    res.json({
      message: 'Excel procesado e insertado en base de datos',
      rows_read: results.length,
      rows_inserted: result.rows[0].inserted
    });

  } catch (error) {
    console.error('Error procesando Excel:', error);
    res.status(500).json({
      message: 'Error al procesar el archivo Excel'
    });
  }
};


const reportIncomes = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT * from stadisticsrooms($1,$2)',[initial_date,final_date]);
    const reportincome = result.rows.map(re => ({
      room_type: re.room_type,
      total_uses: re.total_uses,
      total_income: re.total_income,
      occupation_percentage: re.occupation_percentage,
      income_percentage: re.income_percentage,
      ADR: re.adr,
      CPOR: re.cpor,
      CPAR: re.cpar,
      PPOR: re.ppor,
      fixed_cost: re.fixed_cost,
      break_event_point: re.break_event_point,
      gift_room: re.gift_room
    }));

    res.json({
        message: "Reporte del income",
        data:reportincome
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el dato',
                           error});   
    }
};

const countFolios = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT countFolios($1,$2) as total',[initial_date,final_date]);
    const count = result.rows[0].total;

    res.json({
        message: "Se obtuvo el conteo de los tickets",
        data:count
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos totales.' });   
    }
};

const sumasTotales = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumasTotales($1,$2) as total',[initial_date,final_date]);
    const sumatotal = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total",
        data:sumatotal
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos totales.' });   
    }
};

const sumaEfectivo = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumaEfectivo($1,$2) as total',[initial_date,final_date]);
    const efectivo = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total de efectivo",
        data:efectivo
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos efectivo.' });   
    }
};

const sumaTarjeta = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumaTarjeta($1,$2) as total',[initial_date,final_date]);
    const tarjeta = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total de tarjeta",
        data:tarjeta
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos tarjeta.' });   
    }
};

const sumaVales = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumaVales($1,$2) as total',[initial_date,final_date]);
    const vales = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total de vales",
        data:vales
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos vales.' });   
    }
};

const sumaOtros = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumaOtros($1,$2) as total',[initial_date,final_date]);
    const otros = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total de otros",
        data:otros
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos otros.' });   
    }
};

const sumaPropinas = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT sumaPropinas($1,$2) as total',[initial_date,final_date]);
    const propinas = result.rows[0].total;

    res.json({
        message: "Se obtuvo el total de propinas",
        data:propinas
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener los ingresos propinas.' });   
    }
};

const ticketPromedio = async (req, res) => 
{   
    try{
    const {initial_date,final_date} = req.body;
    const result = await pool.query('SELECT ticketPromedio($1,$2) as total',[initial_date,final_date]);
    const promedio = result.rows[0].total;

    res.json({
        message: "Se obtuvo el promedio de ticket",
        data:promedio
    });

    }catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el promedio.' });   
    }
};

module.exports = {getincomes,totalincomes,loadChequesDetalle,getdetallecheques,
  channelscards,loadincomes,reportIncomes,loadsoftrestaurant,getSoftRestaurant,
  ticketPromedio,sumaEfectivo,sumaOtros,sumaPropinas,sumaTarjeta,sumaVales,sumasTotales,countFolios};