const pool = require('../db/connection');
const transporter = require('../services/mailService');

const getPendingAppExpenses = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM getpendingappexpenses()');

    const status_approval = result.rows.map(pxp => ({
      id_expense: pxp.id_expense,
      expense_description: pxp.description,
      request_date: pxp.request_date,
      requested_by: pxp.name_user,
      area: pxp.name_area,
      amount: pxp.total,
      status_appr: pxp.status_approval
    }));



    res.json({
        data:status_approval
    });

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

};

const getApprovedAppExpenses = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM getapprovedappexpenses()');

    const status_approval = result.rows.map(pxp => ({
      id_expense: pxp.id_expense,
      expense_description: pxp.description,
      request_date: pxp.request_date,
      approval_date: pxp.approval_date,
      requested_by: pxp.name_user,
      area: pxp.name_area,
      amount: pxp.total,
      status_appr: pxp.status_approval
    }));



    res.json({
        data:status_approval
    });

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

};
const getRejectedappExpenses = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM getrejectedappexpenses()');

    const status_approval = result.rows.map(pxp => ({
      id_expense: pxp.id_expense,
      expense_description: pxp.description,
      request_date: pxp.request_date,
      reject_date: pxp.reject_date,
      requested_by: pxp.name_user,
      area: pxp.name_area,
      amount: pxp.total,
      status_appr: pxp.status_approval
    }));



    res.json({
        data:status_approval
    });

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

};

const getTotalApproved = async (req, res) => {
    try{
      const {option} = req.body;
      if(option ==1 )
      {
    const result = await pool.query('SELECT totalApproved() as total');
    const total = result.rows[0].total;
    res.json({
        message: "Total aprobado",
        data:total
    });
      }
      else if (option ==2){
            const result = await pool.query('SELECT totalrejected() as total');
            const total = result.rows[0].total;
            res.json({
            message: "Total rechazado",
            data:total });
        }else {
      return res.status(400).json({
        message: "El parámetro 'option' solo puede ser 1 (aprobado) o 2 (rechazado).",
        data: 0
      });
    }

    }
    catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el total de aprobados.' });
    }
};
const mainSupplier = async (req, res) => {
    try{

    const result = await pool.query('SELECT * from mainsupplier()');
    const mainSupp = result.rows.map(ms => ({
      supplier: ms.name_suppliers,
      percentage: ms.percentage,
    }));
    res.json({
        message: "Proveedor Principal",
        data:mainSupp
    });
    }
    catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el total de aprobados.' });
    }
};

const getReportExpenses = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM report_expenses()');

    const reportExpenses = result.rows.map(re => ({
      id_expense: re.id_expense,
      expense_description: re.description,
      name_suppliers: re.name_suppliers,
      rfc_suppliers: re.rfc_suppliers,
      request_date: re.request_date,
      approval_date: re.approval_date,
      payment_date: re.payment_date,
      requested_by: re.requested_by,
      totalpesos: re.totalpesos,
      totaldolares: re.totaldolares,
      category: re.category,
      area: re.area,
      status_approval: re.approval_status,
      status_payment: re.payment_status,
      is_monthly : re.is_monthly
    }));



    res.json({
        data:reportExpenses
    });

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

};

const getReportPayments = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM paymentsreport()');

    const reportPayment = result.rows.map(rp => ({
      id_expense: rp.id_expense,
      expense_description: rp.description,
      approval_date: rp.approval_date,
      area: rp.area,
      supplier: rp.supplier,
      totalpesos: rp.totalpesos,
      totaldolares: rp.totaldolares,
      status_approval: rp.approval_status,
      status_payment: rp.payment_status
    }));



    res.json({
        data:reportPayment
    });

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

};

const countpending = async (req, res) => {
    try{
    const {option} = req.body;
      if(option ==1 )  //OBtienes cuantas aprobaciones tienes pendientes
      {
        const result = await pool.query('SELECT countpendingapprove() as countpen');
        const total = result.rows[0].countpen;
        res.json({
        message: "Pagos pendientes de aprobación",
        data:total
    });
    }else if(option ==2) //Obtienes los pagos pendientes de los gastos mensuales
    {
        const result = await pool.query('SELECT countpendingmonthly() as monthpen');
        const total = result.rows[0].monthpen;
        res.json({
        message: "Pagos mensuales pendientes",
        data:total
    });
    }
}
    catch(error)
    {
    console.error(error);
    res.status(500).json({ message: 'Error al obtener el conteo de pendientes.' });
    }

};

const getmonthlypayments = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM getmonthlypayments()');

    const monthlypayment = result.rows.map(mp => ({
      id_expense: mp.id_expense,
      expense_description: mp.description,
      recurrence_name: mp.recurrence_name,
      payment_type: mp.payment_type,
      payment_deadline: mp.payment_deadline,
      area: mp.name_area,
      supplier: mp.name_suppliers,
      status: mp.status,
      total: mp.total,
      status_payment: mp.name_pay_status
    }));



    res.json({
        data:monthlypayment
    });

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

};
const getExpense = async(req,res) =>
{
  const { id } = req.params;
  try{
    const result = await pool.query('SELECT * FROM getexpense($1)',[parseInt(id)]);

    const expense = result.rows.map(exp => ({
      id_exp: exp.id_exp,
      description_exp: exp.description_exp,
      suppliers_id: exp.suppliers_id,
      request_date: exp.request_date,
      payment_deadline: exp.payment_deadline,
      request_by: exp.request_by,
      approval_by: exp.approval_by,
      id_area: exp.id_area,
      category_exp: exp.category_exp,
      currency: exp.currency,
      subtotal: exp.subtotal,
      iva: exp.iva,
      ieps: exp.ieps,
      total: exp.total,
      needtoapprove: exp.needtoapprove,
      products: exp.products,
    }));
    res.json({
        data:expense
    });

  }catch(error){
    console.error(error);
    res.status(500).json(error);
  }

};

const getInfoExpense = async(req,res) =>
{
  try{
    const infoSuppliers = await pool.query('SELECT * FROM getsuppliers()');
    const infoCategories = await pool.query('SELECT * FROM getcategoryexpense()');
    const infoAreas = await pool.query('SELECT * FROM getareas()');
    const infoUsers = await pool.query('SELECT * FROM getapproveby()');
    const infoCurrencies = await pool.query('SELECT * FROM getcurrency()');
    const infoUniforms = await pool.query('SELECT * FROM getuniforms()');
    const taxes = await pool.query('SELECT * FROM gettaxes()');

    const suppliers = infoSuppliers.rows.map(supp => ({
      id: supp.id_supplier,
      rfc: supp.rfc_suppliers,
      name: supp.name_suppliers
    }));
    const categories = infoCategories.rows.map(cat => ({
      id: cat.id_category,
      name: cat.name_category,
      spanish_name: cat.spanish_name
    }));
    const areas = infoAreas.rows.map(area => ({
      id: area.id_area,
      name: area.name_area,
    }));
    const users = infoUsers.rows.map(user => ({
      id: user.id_user,
      name: user.user_name,
    }));
    const currencies = infoCurrencies.rows.map(cur => ({
      id: cur.id_currency,
      name: cur.name_currency,
    }));
    const uniforms = infoUniforms.rows.map(uni => ({
      id: uni.id_uniform,
      name: uni.name_uniform
    }));
    const tax = taxes.rows.map(uni => ({
      id: uni.id_tax,
      name: uni.name_tax,
      number: uni.number
    }));

    res.json({
        suppliers,
        categories,
        areas,
        users,
        currencies,
        uniforms,
        tax
    });

  }catch(error){
    console.error(error);
    res.status(500).json({ message: 'Error al obtener la información especifica.' });
  }
};

const newExpense =  async (req, res) => {
  try{
  const {new_description,
        suppliers_id,
        new_request_date,
        new_payment_deadline,
        request_by,
        area,
        expense_cat,
        currency_id,
        products,
        new_iva,
        new_ieps,
        new_subtotal,
        new_total,
        needtoapprove
  }= req.body;

    const product  = Array.isArray(products) && products.length > 0 ? JSON.stringify(products) : null;
   const result = await pool.query('SELECT newexpensev2($1,$2,$3,$4,$5,$6,$7,$8,$9,$10::jsonb,$11,$12,$13,$14) AS STATUS',[
    new_description,suppliers_id,new_request_date,new_payment_deadline,request_by,
    area,expense_cat,currency_id,needtoapprove,product,new_subtotal,new_iva,new_ieps,new_total]);
    const userEmail = await pool.query('SELECT * FROM getusersmailowner()');

   const newExpense = result.rows[0].status;
   const user = userEmail.rows;
  /*let fechaFormateada = 'No definida';
  if (new_payment_deadline) {
    try {
      const fecha = new Date(new_payment_deadline);
      fechaFormateada = isNaN(fecha)
        ? (() => {
            const [dia, mes, anio] = new_payment_deadline.split('/');
            return new Date(`${anio}-${mes}-${dia}`).toLocaleDateString('en-US');
          })()
        : fecha.toLocaleDateString('en-US');
    } catch {
      fechaFormateada = 'Fecha inválida';
    }
  }*/
  const productosHTML = Array.isArray(products)
      ? products.map(p => `<li>${p.id_product || 'N/A'} - QUANTITY: ${p.quantity || 1}</li>`).join('')
      : 'without products associate';
  const recipients = user.map(u => u.email);
    const mailOptions = {
      from: 'soporte@horuxfin.com',
      to: recipients,
      subject: `Approval of the new expense ${newExpense}`,
      html: `<div style="max-width:600px;margin:0 auto;font-family:Arial,Helvetica,sans-serif;
            background-color:#ffffff;border:1px solid #e5e5e5;border-radius:8px;
            overflow:hidden;">
  <!-- Header -->
  <div style="background-color:#7a0c1e;padding:18px 22px;">
    <h2 style="margin:0;color:#ffffff;font-size:20px;font-weight:600;">
      Expenditure approval required
    </h2>
    <p style="margin:6px 0 0 0;color:#f3dcdc;font-size:13px;">
      Action pending on your part
    </p>
  </div>

  <!-- Body -->
  <div style="padding:22px;color:#333333;font-size:14px;line-height:1.6;">
    <p style="margin-top:0;">
      An expense has been recorded that requires your approval.
    </p>

    <div style="background-color:#faf5f6;border-left:4px solid #7a0c1e;
                padding:12px 14px;margin:16px 0;">
      <strong style="color:#7a0c1e;">ID EXPENSE:</strong>
      <span style="font-size:15px;">${newExpense}</span>
    </div>

    <table width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
      <tr>
        <td style="padding:6px 0;"><strong>Description:</strong></td>
        <td style="padding:6px 0;">${new_description}</td>
      </tr>
      <tr>
        <td style="padding:6px 0;"><strong>Deadline:</strong></td>
        <td style="padding:6px 0;">${new_payment_deadline}</td>
      </tr>
      <tr>
        <td style="padding:6px 0;"><strong>Total:</strong></td>
        <td style="padding:6px 0;font-weight:bold;color:#7a0c1e;">
          ${new_total || 'N/A'}
        </td>
      </tr>
    </table>

    <div style="margin-top:18px;">
      <p style="margin-bottom:6px;"><strong>Products included:</strong></p>
      <ul style="padding-left:18px;margin:0;">
        ${productosHTML}
      </ul>
    </div>

    <!-- CTA -->
    <div style="text-align:center;margin-top:32px;">
      <a href="https://hacienda.consultoria-as.com/"
         style="background-color:#7a0c1e;color:#ffffff;
                text-decoration:none;font-weight:bold;
                padding:14px 28px;border-radius:6px;
                display:inline-block;">
        Review and approve spending
      </a>
    </div>

    <p style="margin-top:16px;font-size:12px;color:#777777;text-align:center;">
      We recommend reviewing this application before the deadline.
    </p>
  </div>

  <!-- Footer -->
  <div style="background-color:#f6f6f6;padding:12px 20px;
              font-size:12px;color:#888888;text-align:center;">
    Financial management system · Consultoría AS
  </div>

</div>`,
    };
  if(needtoapprove== true){
  await transporter.sendMail(mailOptions);
  };
  res.json({
              message: "Gasto agregado correctamente.",
              new_expense: newExpense
            });
          }catch(error)
    {
    console.error(error);
    res.status(500).json(error);
    }

};

const updateExpense =  async (req, res) => {
  try{

  let message = '';
  const { id } = req.params;
  const {up_description,
        suppliers_id,
        up_req_date,
        up_deadline,
        up_currency,
        up_request_by,
        up_area,
        up_category,
        needtoapprove,
        up_subtotal,
        up_iva,
        up_ieps,
        up_total,
        products
  }= req.body;

    const product  = Array.isArray(products) && products.length > 0 ? JSON.stringify(products) : null;

  const result = await pool.query('SELECT updateexpensev4($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15::jsonb) AS status',
    [parseInt(id),up_description,suppliers_id,up_req_date,up_deadline,up_currency,
        up_request_by,up_area,up_category,needtoapprove,up_subtotal,up_iva,up_ieps,up_total,product]);
  const userEmail = await pool.query('SELECT * FROM getusersmailowner()');

  const user = userEmail.rows;
  const upExpense = result.rows[0].status;
    switch (upExpense) {
      case 0:
        message = 'El gasto ya fue pagado, no se puede actualizar';
        break;
      case 1:
        message = 'El gasto se actualizo correctamente';
        break;
      default:
        message = 'Error desconocido en la validación';
    };
    
/*let fechaFormateada = 'No definida';
if (up_deadline) {
  try {
    // Manejo de formato "DD-MM-YYYY"
    if (typeof up_deadline === 'string' && up_deadline.includes('-')) {
      const [dia, mes, anio] = up_deadline.split('-');
      const fecha = new Date(`${anio}-${mes}-${dia}`);
      fechaFormateada = !isNaN(fecha)
        ? fecha.toLocaleDateString('es-MX', { timeZone: 'UTC' })
        : 'Fecha inválida';
    } else {
      const fecha = new Date(up_deadline);
      fechaFormateada = !isNaN(fecha)
        ? fecha.toLocaleDateString('es-MX', { timeZone: 'UTC' })
        : 'Fecha inválida';
    }
  } catch (err) {
    console.error('Error al formatear fecha:', err);
    fechaFormateada = 'Fecha inválida';
  }
};*/
  const productosHTML = Array.isArray(products)
      ? products.map(p => `<li>${p.id_product || 'N/A'} - Quantity: ${p.quantity || 1}</li>`).join('')
      : 'Without products associate';
  const recipients = user.map(u => u.email);
    const mailOptions = {
      from: 'soporte@horuxfin.com',
      to: recipients,
      subject: `An updated ID expense approval is required: ${id}`,
      html: `<div style="max-width:600px;margin:0 auto;font-family:Arial,Helvetica,sans-serif;
            background-color:#ffffff;border:1px solid #e5e5e5;border-radius:8px;
            overflow:hidden;">
  <!-- Header -->
  <div style="background-color:#7a0c1e;padding:18px 22px;">
    <h2 style="margin:0;color:#ffffff;font-size:20px;font-weight:600;">
      Expenditure approval required
    </h2>
    <p style="margin:6px 0 0 0;color:#f3dcdc;font-size:13px;">
      Action pending on your part
    </p>
  </div>

  <!-- Body -->
  <div style="padding:22px;color:#333333;font-size:14px;line-height:1.6;">
    <p style="margin-top:0;">
      An expense has been updated that requires your approval.
    </p>

    <div style="background-color:#faf5f6;border-left:4px solid #7a0c1e;
                padding:12px 14px;margin:16px 0;">
      <strong style="color:#7a0c1e;">ID EXPENSE:</strong>
      <span style="font-size:15px;">${id}</span>
    </div>

    <table width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
      <tr>
        <td style="padding:6px 0;"><strong>Description:</strong></td>
        <td style="padding:6px 0;">${up_description}</td>
      </tr>
      <tr>
        <td style="padding:6px 0;"><strong>Deadline:</strong></td>
        <td style="padding:6px 0;">${up_deadline}</td>
      </tr>
      <tr>
        <td style="padding:6px 0;"><strong>Total:</strong></td>
        <td style="padding:6px 0;font-weight:bold;color:#7a0c1e;">
          ${up_total || 'N/A'}
        </td>
      </tr>
    </table>

    <div style="margin-top:18px;">
      <p style="margin-bottom:6px;"><strong>Products included:</strong></p>
      <ul style="padding-left:18px;margin:0;">
        ${productosHTML}
      </ul>
    </div>

    <!-- CTA -->
    <div style="text-align:center;margin-top:32px;">
      <a href="https://hacienda.consultoria-as.com/"
         style="background-color:#7a0c1e;color:#ffffff;
                text-decoration:none;font-weight:bold;
                padding:14px 28px;border-radius:6px;
                display:inline-block;">
        Review and approve spending
      </a>
    </div>

    <p style="margin-top:16px;font-size:12px;color:#777777;text-align:center;">
      We recommend reviewing this application before the deadline.
    </p>
  </div>

  <!-- Footer -->
  <div style="background-color:#f6f6f6;padding:12px 20px;
              font-size:12px;color:#888888;text-align:center;">
    Financial management system · Consultoría AS
  </div>

</div>`,
    };
  if(needtoapprove== true){
  await transporter.sendMail(mailOptions);
  };

    res.json({
      message,
      upExpense: upExpense
    });
          }catch(error)
    {
    console.error(error);
    res.status(500).json(error);
    }

};

const getTaxes = async (req, res) => {
    try{
         const result = await pool.query('SELECT * FROM gettaxes()');

    const taxes  = result.rows.map(tx => ({
      id_tax: tx.id_tax,
      name_tax: tx.name_tax,
    }));



    res.json({
        data:taxes
    });

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

};

const formatDateDMY = (value) => {
  if (!value) return '';
  const date = value instanceof Date ? value : new Date(value);
  if (isNaN(date.getTime())) return '';
  return date.toLocaleDateString('es-MX', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric'
  });
};

module.exports = { getPendingAppExpenses,getApprovedAppExpenses,countpending,
                   getTotalApproved,mainSupplier,getReportExpenses,newExpense,
                   getReportPayments,getmonthlypayments,getRejectedappExpenses,
                   updateExpense,getExpense,getInfoExpense, getTaxes };
