// controllers/paymentsController.js
//const dbConnect = require('../../busapi/configs/dbConnection');
const { getBBPSConfig } = require("../utils/config");
const { callBBPS } = require("../utils/bbpsClient");
const paymentService = require('../services/paymentService');
const { buildValidateBody } = require("../services/buildValidateBody");
const { buildMakePaymentBody } = require("../services/buildMakePaymentBody");


exports.retrieveBillerId = async (req, res) => {
  try {
    //console.log("===== BBPS Retrieve Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/billers/retrieve",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    console.error("ERROR in retrieveBiller:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.retrieveOperator = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/operatorseries/list",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    console.error("ERROR in retrieveOperator:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.retrieveBillerAlert = async (req, res) => {
  try {
    const config = getBBPSConfig();

    // Call BBPS API
    const response = await callBBPS({
      path: "billpay/billeralerts/list",
      payload: "{}",
      config,
      lineEndings: "crlf",
    });

    console.log("BBPS Response:", response);

    if (!Array.isArray(response) || response.length === 0) {
      return res.status(200).json({ message: "No alerts to process" });
    }

    const query = `
      INSERT INTO biller_alerts 
      (billerid, biller_state, start_time, update_time, end_time, ext_end_time, billeralertid) 
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `;
    
    const parseDate = (str) => {
      if (!str) return null;
      const match = str.match(/(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2})/);
      if (!match) return null;
      const [, day, month, year, hour, min, sec] = match;
      return `${year}-${month}-${day} ${hour}:${min}:${sec}`;
    };
     let insertedCount = 0;

    for (const alert of response) {
      const data = {
        billerid: alert.billerid ?? null,           // Required
        biller_state: alert.biller_state ?? null,
        start_time: parseDate(alert.start_time),
        update_time: parseDate(alert.update_time),
        end_time: parseDate(alert.end_time),
        ext_end_time: parseDate(alert.ext_end_time),
        billeralertid: alert.billeralertid ?? null,
      };

      // Skip if required field is missing
      if (!data.billerid) {
        console.error("Skipping alert: missing billerid", alert);
        continue;
      }

      const values = Object.values(data);
      console.log("Inserting values:", values);

      await dbConnect.execute(query, values);
    }

    res.json(response);
  } catch (err) {
    console.error("ERROR in retrieveBillerAlert:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.retrieveRechargePlans = async (req, res) => {
  try {
    //console.log("===== BBPS Retrieve Recharge Plans START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    } else {
      rawBody = JSON.stringify(req.body); // fallback
    }

    // Call BBPS API
    const response = await callBBPS({
      path: "billpay/plans/retrieve",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Retrieve Recharge Plans response processed successfully");
    res.json(response);
  } catch (err) {
    console.error("ERROR in retrieveRechargePlans:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.generateBillerFile = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/billers/file/generate",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    console.error("ERROR in getBillerFile:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.getBillerFile = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/billers/file",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    console.error("ERROR in getBillerFile:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

// exports.validatePayment = async (req, res) => {
//   try {
//     //console.log("===== BBPS Operator Biller START =====");

//     const config = getBBPSConfig();

//     // Normalize body (ensure CRLF line endings)
//     let rawBody = req.rawBody;
//     if (typeof rawBody === "string") {
//       rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
//       rawBody = rawBody.replace(/\n/g, "\r\n");
//     }

//     // Make BBPS call
//     const response = await callBBPS({
//       path: "billpay/validate",
//       payload: rawBody,
//       config,
//       lineEndings: "crlf",
//     });

//     //console.log("Response processed successfully");
//     res.json(response);

//   } catch (err) {
//     console.error("ERROR in validatePayment:", err.message);
//     const status = err.status || 500;
//     res.status(status).json(err.response || { error: err.message });
//   }
// };

exports.validatePayment = async (req, res) => {
  try {
    const result = await buildValidateBody(req.body);

    console.log("🔍 buildValidateBody result:", JSON.stringify(result, null, 2));

    if (!result) {
      throw new Error("buildValidateBody() returned undefined");
    }

    if (result.flow === "error") {
      return res.status(400).json({
        success: false,
        flow: "error",
        error: result.error || { message: "Validation service returned an error" },
      });
    }

    if (result.flow === "adhoc") {
      return res.status(200).json({
        success: true,
        flow: "adhoc",
        message: "Online validation not required",
        meta: result,
      });
    }

    if (!result.body || !result.body.billerid) {
      throw new Error("Invalid response from buildValidateBody() — missing body or billerid");
    }

    console.log("➡️ Sending BBPS validation request for:", result.body.billerid);
    console.log("Payload:", JSON.stringify(result.body, null, 2));

    const config = getBBPSConfig();
    const response = await callBBPS({
      path: "billpay/validate",
      payload: result.body,
      config,
    });

    res.status(200).json({
      success: true,
      flow: "validate",
      data: response,
    });
  } catch (err) {
    console.error("❌ BBPS Error:", err.response || err);

  if (err.response) {
    // Send decrypted BBPS error to frontend
    return res.status(err.response.status || 500).json(err.response);
  }

  // Fallback for unexpected internal errors
  return res.status(500).json({
    success: false,
    message: err.message || "Internal server error"
  });
  }
};

exports.retrieveComplaintById = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/complaints/retrieve",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    console.error("ERROR in retrieveComplaint:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.operatorSeriesList = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/operatorseries/list",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    //console.error("ERROR in operator series:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

// exports.makePayment = async (req, res) => {
//   try {
//     //console.log("===== BBPS Operator Biller START =====");

//     const config = getBBPSConfig();

//     // Normalize body (ensure CRLF line endings)
//     let rawBody = req.rawBody;
//     if (typeof rawBody === "string") {
//       rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
//       rawBody = rawBody.replace(/\n/g, "\r\n");
//     }

//     // Make BBPS call
//     const response = await callBBPS({
//       path: "billpay/payments/initiate",
//       payload: rawBody,
//       config,
//       lineEndings: "crlf",
//     });

//     //console.log("Response processed successfully");
//     res.json(response);

//   } catch (err) {
//     //console.error("ERROR in operator series:", err.message);
//     const status = err.status || 500;
//     res.status(status).json(err.response || { error: err.message });
//   }
// };

exports.makePayment = async (req, res) => {
    try {
    const result = await buildMakePaymentBody(req.body);

    console.log("🔍 buildMakePaymentBody result:", JSON.stringify(result, null, 2));

    if (!result) {
      throw new Error("buildMakePaymentBody() returned undefined");
    }

    if (result.flow === "error") {
      return res.status(400).json({
        success: false,
        flow: "error",
        error: result.error || { message: "Make Payment service returned an error" },
      });
    }

    // if (result.flow === "adhoc") {
    //   return res.status(200).json({
    //     success: true,
    //     flow: "adhoc",
    //     message: "Online validation not required",
    //     meta: result,
    //   });
    // }

    if (!result.body || !result.body.billerid) {
      throw new Error("Invalid response from buildMakePaymentBody() — missing body or billerid");
    }

    console.log("➡️ Sending BBPS make payment request for:", result.body.billerid);
    console.log("Payload:", JSON.stringify(result.body, null, 2));

    const config = getBBPSConfig();
    const response = await callBBPS({
      path: "billpay/payments/initiate",
      payload: result.body,
      config,
    });

    res.status(200).json({
      success: true,
      flow: "validate",
      data: response,
    });
  } catch (err) {
    console.error("❌ BBPS Error:", err.response || err);

  if (err.response) {
    // Send decrypted BBPS error to frontend
    return res.status(err.response.status || 500).json(err.response);
  }

  // Fallback for unexpected internal errors
  return res.status(500).json({
    success: false,
    message: err.message || "Internal server error"
  });
  }
};

exports.operatorSeriesId = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/operatorseries/retrieve",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    //console.error("ERROR in operator series:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.listPayments = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/payments/list",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    //console.error("ERROR in operator series:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};

exports.retrievePayments = async (req, res) => {
  try {
    //console.log("===== BBPS Operator Biller START =====");

    const config = getBBPSConfig();

    // Normalize body (ensure CRLF line endings)
    let rawBody = req.rawBody;
    if (typeof rawBody === "string") {
      rawBody = rawBody.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
      rawBody = rawBody.replace(/\n/g, "\r\n");
    }

    // Make BBPS call
    const response = await callBBPS({
      path: "billpay/payments/retrieve",
      payload: rawBody,
      config,
      lineEndings: "crlf",
    });

    //console.log("Response processed successfully");
    res.json(response);

  } catch (err) {
    //console.error("ERROR in operator series:", err.message);
    const status = err.status || 500;
    res.status(status).json(err.response || { error: err.message });
  }
};








