import DB from "../config/database/db";
import { ResultSetHeader, RowDataPacket } from "mysql2";
import requestTypes from "../schemas/request.schema";
import bankTypes from "../schemas/bankAccount.schema";
import log from "../config/log";

const bankDB: any = {};

bankDB.getById = async ({ id }: bankTypes) => {
  const query = "Select * from BankAccounts where id = ?";
  const data = [id];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows[0];
  else return false;
};

bankDB.getByClientId = async ({ clientId }: bankTypes) => {
  const query =
    "Select * from BankAccounts where clientId = ? order by id desc";
  const data = [clientId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows;
  else return false;
};

bankDB.getByClientIdByOnlineSettlement = async ({ clientId, isOnlineSettlement }: bankTypes) => {
  const query =
    "Select * from BankAccounts where clientId = ? and isOnlineSettlement=? order by id desc";
  const data = [clientId, isOnlineSettlement];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows;
  else return false;
};


bankDB.getByAccNum = async ({ accountNum, clientId }: bankTypes) => {
  const query = "Select * from BankAccounts where accountNum = ? and clientId = ?";
  const data = [accountNum, clientId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows[0];
  else return false;
};

bankDB.getByUPI = async ({ upiId }: bankTypes) => {
  const query = "Select * from BankAccounts where upiId = ?";
  const data = [upiId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows[0];
  else return false;
};

bankDB.addBank = async ({
  clientId,
  holderName,
  accountNum,
  ifsc,
  bankAddress,
  type,
  bankName,
}: bankTypes) => {
  const query =
    "Insert into BankAccounts (clientId, holderName, accountNum, ifsc, bankAddress, type, bankName) values (?,?,?,?,?,?,?)";
  const data = [
    clientId,
    holderName,
    accountNum,
    ifsc,
    bankAddress,
    type,
    bankName,
  ];
  const [rows] = await DB.query<ResultSetHeader>(query, data);
  return rows.insertId;
};

bankDB.addBankOnline = async ({
  clientId,
  holderName,
  accountNum,
  ifsc,
  bankAddress,
  type,
  bankName,
  isOnlineSettlement,
}: bankTypes) => {
  const query =
    "Insert into BankAccounts (clientId, holderName, accountNum, ifsc, bankAddress, type, bankName, isOnlineSettlement) values (?,?,?,?,?,?,?,?)";
  const data = [
    clientId,
    holderName,
    accountNum,
    ifsc,
    bankAddress,
    type,
    bankName,
    isOnlineSettlement,
  ];
  const [rows] = await DB.query<ResultSetHeader>(query, data);
  return rows.insertId;
};

bankDB.addUPI = async ({ clientId, type, upiId }: bankTypes) => {
  const query =
    "Insert into BankAccounts (clientId, type, upiId) values (?,?,?)";
  const data = [clientId, type, upiId];
  const [rows] = await DB.query<ResultSetHeader>(query, data);
  return rows.insertId;
};

bankDB.removeBank = async ({ id }: bankTypes) => {
  const query = "Delete from BankAccounts where id = ?";
  const data = [id];
  const [rows] = await DB.query<ResultSetHeader>(query, data);
  return true;
};

bankDB.getByClientIdLimitedFields = async ({ clientId }: bankTypes) => {
  const query =
    "Select id, accountNum, holderName from BankAccounts where clientId = ? and accountNum is not null order by id desc";
  const data = [clientId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows;
  else return false;
};

bankDB.getBankAccountByPayuCreds = async ({ clientId, payuKey, payuMid }: bankTypes) => {
  try {
    const query =
      "Select * from BankAccounts where clientId = ? and payuKey = ? and payuMid = ?";
    const data = [clientId, payuKey, payuMid];
    const [rows] = await DB.execute<RowDataPacket[]>(query, data);
    if (rows?.length > 0) return rows[0];
    else return false;
  } catch (error: any) {
    log.info(`[Bank Model], [getBankAccountByPayuCreds], Error: ${error?.message || error}, Client Id [${clientId}], Payu Key [${payuKey}], Payu Mid [${payuMid}]`)
    return false;
  }
};

bankDB.getBankAccountByEazebuzzCreds = async ({ clientId, easebuzzSubMerchantId }: bankTypes) => {
  try {
    const query =
      "Select * from BankAccounts where clientId = ? and easebuzzSubMerchantId = ?";
    const data = [clientId, easebuzzSubMerchantId];
    const [rows] = await DB.execute<RowDataPacket[]>(query, data);
    if (rows?.length > 0) return rows[0];
    else return false;
  } catch (error: any) {
    log.info(`[Bank Model], [getBankAccountByEazebuzzCreds], Error: ${error?.message || error}, Client Id [${clientId}], Easebuzz Sub Merchant Id [${easebuzzSubMerchantId}]`)
    return false;
  }
};

bankDB.getActivePaymentAccountsByClientId = async ({
  clientId,
}: bankTypes) => {
  // const query = `
  //   SELECT id, bankName, accountNum, ifsc, holderName
  //   FROM BankAccounts
  //   WHERE clientId = ?
  //     AND (
  //       (payuMid IS NOT NULL AND payuMid != '' 
  //        AND payuKey IS NOT NULL AND payuKey != '')
  //       OR
  //       (easebuzzSubMerchantId IS NOT NULL AND easebuzzSubMerchantId != '')
  //     )
  // `;

  const query = `
    SELECT id, bankName, accountNum, ifsc, holderName
    FROM BankAccounts
    WHERE clientId = ? and type=1
  `;

  const [rows] = await DB.execute<RowDataPacket[]>(query, [clientId]);

  return rows || [];
};

bankDB.getBankAccountByCashfreeVendorId = async ({ clientId, cashfreeVendorId }: bankTypes) => {
  const query =
    "Select * from BankAccounts where clientId = ? and cashfreeVendorId = ?";
  const data = [clientId, cashfreeVendorId];
  const [rows] = await DB.execute<RowDataPacket[]>(query, data);
  if (rows?.length > 0) return rows[0];
  else return false;
};

export default bankDB;
