import axios from "axios";
import moment from "moment";
import log from "../config/log";
import CONSTANTS from "../config/constants";
import clientConfigDB from "../models/clientConfig.model";
import { processors } from "xml2js";

const cashfreePayout: any = {};

cashfreePayout.addBeneficiary = async (C: string, CF: string, clientId: number, beneficiaryName: string, beneficiaryId: string, accountNumber: string, ifsc: string, upiId: string, type: number, mobile: string) => {

  const U = `cashfreePayout`;
  const F = `addBeneficiary`;
  let beneficiary_instrument_details: any;

  if (type === CONSTANTS.BANK_TYPES.UPI) {
    beneficiary_instrument_details = {
      "vpa": upiId,
    }
  } else {
    beneficiary_instrument_details = {
      "bank_account_number": accountNumber,
      "bank_ifsc": ifsc,
    }
  }
  let beneficiary_contact_details: any;
  if (mobile && mobile.trim() != "") {
    beneficiary_contact_details = {
      //"beneficiary_email": "sample@cashfree.com",
      "beneficiary_phone": mobile,
      "beneficiary_country_code": "+91",
      // "beneficiary_address": "177A Bleecker Street",
      // "beneficiary_city": "New York City",
      // "beneficiary_state": "New York",
      // "beneficiary_postal_code": "560011"
    }
  }
  const payload: any = {
    "beneficiary_id": beneficiaryId,
    "beneficiary_name": beneficiaryName,
    "beneficiary_instrument_details": beneficiary_instrument_details,
    // "beneficiary_contact_details": {
    //   //"beneficiary_email": "sample@cashfree.com",
    //   "beneficiary_phone": mobile,
    //   "beneficiary_country_code": "+91",
    //   // "beneficiary_address": "177A Bleecker Street",
    //   // "beneficiary_city": "New York City",
    //   // "beneficiary_state": "New York",
    //   // "beneficiary_postal_code": "560011"
    // }
  };

  if (mobile && mobile.trim() !== "") {
    payload.beneficiary_contact_details = beneficiary_contact_details;
  }

  let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
  let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

  const isXClientId = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
  });
  const isXClientSecretKey = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
  });

  if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
    xClientId = isXClientId.value;
    xSecretKey = isXClientSecretKey.value;
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
  } else {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
  }
  const options = {
    method: "POST",
    url: `${process.env.CASHFREE_PAYOUT_BASE_URL}/beneficiary`,
    headers: {
      "Content-Type": "application/json",
      "x-client-id": xClientId,
      "x-client-secret": xSecretKey,
      "x-api-version": "2024-01-01",
    },
    data: payload,
  };

  try {
    const response = await axios.request(options);

    return {
      isSuccess: true,
      data: response.data,
    };
  } catch (err: any) {
    log.info(`[${U}], [${F}], Error:`, err.response?.data || err.message);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.removeBeneficiary = async (C: string, CF: string, clientId: number, beneficiaryId: string) => {

  const U = `cashfreePayout`;
  const F = `removeBeneficiary`;

  
  let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
  let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

  const isXClientId = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
  });
  const isXClientSecretKey = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
  });

  if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
    xClientId = isXClientId.value;
    xSecretKey = isXClientSecretKey.value;
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
  } else {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
  }
  const options = {
    method: "DELETE",
    url: `${process.env.CASHFREE_PAYOUT_BASE_URL}/beneficiary?beneficiary_id=${beneficiaryId}`,
    headers: {
      "Content-Type": "application/json",
      "x-client-id": xClientId,
      "x-client-secret": xSecretKey,
      "x-api-version": "2024-01-01",
    },
  };

  try {
    const response = await axios.request(options);

    return {
      isSuccess: true,
      data: response.data,
    };
  } catch (err: any) {
    log.info(`[${U}], [${F}], Error:`, err.response?.data || err.message);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.fetchBeneficiary = async (C: string, CF: string, clientId: number, accountNumber: string, ifsc: string) => {

  const U = `cashfreePayout`;
  const F = `fetchBeneficiary`;

  
  let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
  let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

  const isXClientId = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
  });
  const isXClientSecretKey = await clientConfigDB.getClientConfig({
    clientId,
    provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
    type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
  });

  if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
    xClientId = isXClientId.value;
    xSecretKey = isXClientSecretKey.value;
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
  } else {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
  }
  const options = {
    method: "GET",
    url: `${process.env.CASHFREE_PAYOUT_BASE_URL}/beneficiary?bank_account_number=${accountNumber}&bank_ifsc=${ifsc}`,
    headers: {
      "Content-Type": "application/json",
      "x-client-id": xClientId,
      "x-client-secret": xSecretKey,
      "x-api-version": "2024-01-01",
    },
  };

  try {
    const response = await axios.request(options);

    return {
      isSuccess: true,
      data: response.data,
    };
  } catch (err: any) {
    log.info(`[${U}], [${F}], Error:`, err.response?.data || err.message);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.payoutToBeneficiary = async (C: string, CF: string, clientId: number, transferId: string, amount: number, beneficiaryId: string, transferMode: string, transferRemark: string) => {

  const U = `cashfreePayout`;
  const F = `payoutToBeneficiary`;
  try {
    const payload: any = {
      "transfer_id": transferId,
      "transfer_mode": transferMode,
      "transfer_amount": amount,
      "beneficiary_details": {
        "beneficiary_id": beneficiaryId
      },
      "transfer_remarks": transferRemark
    };
    //IT SHOULD BE PAYOUT CREDENTIALS
    let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
    let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

    const isXClientId = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
    });
    const isXClientSecretKey = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
    });

    if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
      xClientId = isXClientId.value;
      xSecretKey = isXClientSecretKey.value;
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
    } else {
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
    }
    const options = {
      method: "POST",
      url: `${process.env.CASHFREE_PAYOUT_BASE_URL}/transfers`,
      headers: {
        "Content-Type": "application/json",
        "x-client-id": xClientId,
        "x-client-secret": xSecretKey,
        "x-api-version": "2024-01-01",
      },
      data: payload,
    };

    try {
      const response = await axios.request(options);

      return {
        isSuccess: true,
        data: response.data,
      };
    } catch (err: any) {
      //log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${err.response?.data || err.message}]`);
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${JSON.stringify(err.response?.data)}]`);

      return {
        isSuccess: false,
        error: err.response?.data || err.message,
      };
    }
  } catch (err: any) {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Error Payout [${err.stack}]`);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.quickPayout = async (C: string, CF: string, clientId: number, transferId: string, amount: number, accountName: string, accountNumber: string, ifsc: string, transferMode: string, transferRemark: string) => {

  const U = `cashfreePayout`;
  const F = `quickPayout`;
  try {
    const payload: any = {
      "transfer_id": transferId,
      "transfer_mode": transferMode,
      "transfer_remarks": transferRemark,
      "transfer_amount": amount,
      "beneficiary_details": {
        "beneficiary_name": accountName,
        "beneficiary_instrument_details": {
          "bank_account_number": accountNumber,
          "bank_ifsc": ifsc
        }
      }
    };
    //IT SHOULD BE PAYOUT CREDENTIALS
    let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
    let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

    const isXClientId = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
    });
    const isXClientSecretKey = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
    });

    if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
      xClientId = isXClientId.value;
      xSecretKey = isXClientSecretKey.value;
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
    } else {
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
    }
    const options = {
      method: "POST",
      url: `${process.env.CASHFREE_PAYOUT_BASE_URL}/transfers`,
      headers: {
        "Content-Type": "application/json",
        "x-client-id": xClientId,
        "x-client-secret": xSecretKey,
        "x-api-version": "2024-01-01",
      },
      data: payload,
    };

    try {
      const response = await axios.request(options);

      return {
        isSuccess: true,
        data: response.data,
      };
    } catch (err: any) {
      //log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${err.response?.data || err.message}]`);
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${JSON.stringify(err.response?.data)}]`);

      return {
        isSuccess: false,
        error: err.response?.data || err.message,
      };
    }
  } catch (err: any) {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Error Payout [${err.stack}]`);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.getWalletBalance = async (C: string, CF: string, clientId: number) => {

  const U = `cashfreePayout`;
  const F = `getWalletBalance`;
  try {
    //IT SHOULD BE PAYOUT CREDENTIALS
    let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
    let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;

    const isXClientId = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
    });
    const isXClientSecretKey = await clientConfigDB.getClientConfig({
      clientId,
      provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
      type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
    });

    if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
      xClientId = isXClientId.value;
      xSecretKey = isXClientSecretKey.value;
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
    } else {
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
    }
    const options = {
      method: "POST",
      url: process.env.CASHFREE_PAYOUT_AUTH_URL,
      headers: {
        "Content-Type": "application/json",
        "x-client-id": xClientId,
        "x-client-secret": xSecretKey,
        "x-api-version": "2024-01-01",
      },
    };

    try {
      const response = await axios.request(options);
      //log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Auth Resp [${JSON.stringify(response)}]`);
      let token = response?.data?.data?.token;
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], CF Token [${token}]`);

      if (response?.data?.status !== "SUCCESS" || !token) {
        log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Auth Resp  [${response?.data}], Authentication failed`);
        return {
          isSuccess: false,
          error: response?.data?.message || "Authentication failed",
        };
      } else {
        const balOptions = {
          method: "GET",
          url: process.env.CASHFREE_PAYOUT_GET_BAL_URL,
          headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${token}`
          },
        };
        try {
          const balResponse = await axios.request(balOptions);
          if (balResponse.data.status === "SUCCESS") {
            const availableBalance = balResponse?.data?.data?.availableBalance;
            const balance = balResponse?.data?.data?.balance;
            log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Available Balance [${availableBalance}], Account Balance [${balance}], Balance fetched successfully`);
            return {
              isSuccess: true,
              balance,
              availableBalance,
            };
          } else {
            log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Resp [${balResponse?.data}], Failed to fetch balance`);
            return {
              isSuccess: false,
              error: balResponse?.data?.message || "Failed to fetch balance",
            };
          }
        } catch (err: any) {
          log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${err.response?.data || err.message}]`);

          return {
            isSuccess: false,
            error: err.response?.data || err.message,
          };
        }
      }
    } catch (err: any) {
      log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Cashfree Error [${err.response?.data || err.message}]`);

      return {
        isSuccess: false,
        error: err.response?.data || err.message,
      };
    }
  } catch (err: any) {
    log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], Error Payout [${err.stack}]`);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};

cashfreePayout.verifyAccount = async (C: string, CF: string, clientId: number, accountNumber: string, ifsc: string,  accountHolderName: any = null, phone: any = null) => {

  const U = `cashfreePayout`;
  const F = `verifyAccount`;
  
  // let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
  // let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;
  let xClientId = process.env.CASHFREE_PAYOUT_CLIENTID;
  let xSecretKey = process.env.CASHFREE_PAYOUT_SECRET;
  //OXO
  // xClientId = "CF1246673D86RB6EUPKTS73EG6HE0";
  // xSecretKey = "cfsk_ma_prod_490a3f3afaccadff7c6fb254484bb23d_1eec2462";

  // const isXClientId = await clientConfigDB.getClientConfig({
  //   clientId,
  //   provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
  //   type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_CLIENT_ID,
  // });
  // const isXClientSecretKey = await clientConfigDB.getClientConfig({
  //   clientId,
  //   provider: CONSTANTS.CLIENT_CONFIG_PROVIDER.CASHFREE,
  //   type: CONSTANTS.CLIENT_CONFIG_TYPE.CASHFREE.PAYOUT_X_SECRET_KEY,
  // });

  // if (isXClientId && isXClientId.value && isXClientSecretKey && isXClientSecretKey.value) {
  //   xClientId = isXClientId.value;
  //   xSecretKey = isXClientSecretKey.value;
  //   log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Client Gateway `);
  // } else {
  //   log.info(`[${C}], [${CF}], [${F}], Client Id [${clientId}], X Client Id [${xClientId}], Secret Key [${xSecretKey}], Kipinn Gateway `);
  // }

  let payload : any = {
    "bank_account": accountNumber,
    "ifsc": ifsc,
    ...(accountHolderName && { name: accountHolderName }),
    ...(phone && { phone: phone }),
  }

  const options = {
    method: "POST",
    url: `${process.env.CASHFREE_API_BASE_URL}/verification/bank-account/sync`,
    headers: {
      "Content-Type": "application/json",
      "x-client-id": xClientId,
      "x-client-secret": xSecretKey,
    },
    data: payload,
  };

  try {
    const response = await axios.request(options);

    return {
      isSuccess: true,
      data: response.data,
    };
  } catch (err: any) {
    log.info(`[${U}], [${F}], Error:`, err.response?.data || err.message);

    return {
      isSuccess: false,
      error: err.response?.data || err.message,
    };
  }

};



export default cashfreePayout;