import {
  AmexTransactionInput,
  CalTransactionInput,
  CurrencyRateInput,
  DiscountTransactionInput,
  IsracardTransactionInput,
  MaxTransactionInput,
  PoalimForeignTransactionInput,
  PoalimIlsTransactionInput,
  PoalimSwiftTransactionInput,
} from '../../../__generated__/types.js';
import {
  IUploadAmexTransactionsParams,
  IUploadCalTransactionsParams,
  IUploadCurrencyRatesParams,
  IUploadDiscountTransactionsParams,
  IUploadIsracardTransactionsParams,
  IUploadMaxTransactionsParams,
  IUploadPoalimForeignTransactionsParams,
  IUploadPoalimIlsTransactionsParams,
  IUploadPoalimSwiftTransactionsParams,
} from '../types.js';

export function validatePoalimIlsTransactions(
  transactions: readonly PoalimIlsTransactionInput[],
): IUploadPoalimIlsTransactionsParams['transactions'] {
  return transactions.map(t => ({
    eventDate: t.eventDate,
    formattedEventDate: t.formattedEventDate,
    serialNumber: t.serialNumber,
    activityTypeCode: t.activityTypeCode,
    activityDescription: t.activityDescription,
    textCode: t.textCode,
    referenceNumber: t.referenceNumber,
    referenceCatenatedNumber: t.referenceCatenatedNumber,
    valueDate: t.valueDate,
    formattedValueDate: t.formattedValueDate,
    eventAmount: t.eventAmount,
    eventActivityTypeCode: t.eventActivityTypeCode,
    currentBalance: t.currentBalance,
    internalLinkCode: t.internalLinkCode,
    originalEventCreateDate: t.originalEventCreateDate,
    formattedOriginalEventCreateDate: t.formattedOriginalEventCreateDate,
    transactionType: t.transactionType,
    dataGroupCode: t.dataGroupCode,
    beneficiaryDetailsData: t.beneficiaryDetailsData,
    expandedEventDate: t.expandedEventDate,
    executingBranchNumber: t.executingBranchNumber,
    eventId: t.eventId,
    details: t.details,
    pfmDetails: t.pfmDetails,
    differentDateIndication: t.differentDateIndication,
    rejectedDataEventPertainingIndication: t.rejectedDataEventPertainingIndication,
    tableNumber: t.tableNumber,
    recordNumber: t.recordNumber,
    contraBankNumber: t.contraBankNumber,
    contraBranchNumber: t.contraBranchNumber,
    contraAccountNumber: t.contraAccountNumber,
    contraAccountTypeCode: t.contraAccountTypeCode,
    marketingOfferContext: (t.marketingOfferContext ? '1' : '0') as unknown as boolean,
    commentExistenceSwitch: (t.commentExistenceSwitch ? '1' : '0') as unknown as boolean,
    englishActionDesc: t.englishActionDesc,
    fieldDescDisplaySwitch: (t.fieldDescDisplaySwitch ? '1' : '0') as unknown as boolean,
    urlAddressNiar: t.urlAddressNiar,
    offerActivityContext: t.offerActivityContext,
    comment: t.comment,
    beneficiaryDetailsDataPartyName: t.beneficiaryDetailsDataPartyName,
    beneficiaryDetailsDataMessageHeadline: t.beneficiaryDetailsDataMessageHeadline,
    beneficiaryDetailsDataPartyHeadline: t.beneficiaryDetailsDataPartyHeadline,
    beneficiaryDetailsDataMessageDetail: t.beneficiaryDetailsDataMessageDetail,
    beneficiaryDetailsDataTableNumber: t.beneficiaryDetailsDataTableNumber,
    beneficiaryDetailsDataRecordNumber: t.beneficiaryDetailsDataRecordNumber,
    activityDescriptionIncludeValueDate: t.activityDescriptionIncludeValueDate,
    bankNumber: t.bankNumber,
    branchNumber: t.branchNumber,
    accountNumber: t.accountNumber,
  }));
}

export function validatePoalimForeignTransactions(
  transactions: readonly PoalimForeignTransactionInput[],
): IUploadPoalimForeignTransactionsParams['transactions'] {
  return transactions.map(t => ({
    metadataAttributesOriginalEventKey: t.metadataAttributesOriginalEventKey,
    metadataAttributesContraBranchNumber: t.metadataAttributesContraBranchNumber,
    metadataAttributesContraAccountNumber: t.metadataAttributesContraAccountNumber,
    metadataAttributesContraBankNumber: t.metadataAttributesContraBankNumber,
    metadataAttributesContraAccountFieldNameLable: t.metadataAttributesContraAccountFieldNameLable,
    metadataAttributesDataGroupCode: t.metadataAttributesDataGroupCode,
    metadataAttributesCurrencyRate: t.metadataAttributesCurrencyRate,
    metadataAttributesContraCurrencyCode: t.metadataAttributesContraCurrencyCode,
    metadataAttributesRateFixingCode: t.metadataAttributesRateFixingCode,
    executingDate: t.executingDate,
    formattedExecutingDate: t.formattedExecutingDate,
    valueDate: t.valueDate,
    formattedValueDate: t.formattedValueDate,
    originalSystemId: t.originalSystemId,
    activityDescription: t.activityDescription,
    eventAmount: t.eventAmount,
    currency: t.currency,
    currentBalance: t.currentBalance,
    referenceCatenatedNumber: t.referenceCatenatedNumber,
    referenceNumber: Number(t.referenceNumber),
    currencyRate: t.currencyRate,
    eventDetails: t.eventDetails,
    rateFixingCode: t.rateFixingCode,
    contraCurrencyCode: t.contraCurrencyCode,
    eventActivityTypeCode: t.eventActivityTypeCode,
    transactionType: t.transactionType,
    rateFixingShortDescription: t.rateFixingShortDescription,
    currencyLongDescription: t.currencyLongDescription,
    activityTypeCode: t.activityTypeCode,
    eventNumber: t.eventNumber,
    validityDate: t.validityDate,
    comments: t.comments,
    commentExistenceSwitch: (t.commentExistenceSwitch ? '1' : '0') as unknown as boolean,
    accountName: t.accountName,
    contraBankNumber: t.contraBankNumber,
    contraBranchNumber: t.contraBranchNumber,
    contraAccountNumber: t.contraAccountNumber,
    originalEventKey: (t.originalEventKey ? '1' : '0') as unknown as boolean,
    contraAccountFieldNameLable: t.contraAccountFieldNameLable,
    dataGroupCode: (t.dataGroupCode ? '1' : '0') as unknown as boolean,
    rateFixingDescription: t.rateFixingDescription,
    urlAddressNiar: t.urlAddressNiar,
    currencySwiftCode: t.currencySwiftCode,
    urlAddress: t.urlAddress,
    bankNumber: t.bankNumber,
    branchNumber: t.branchNumber,
    accountNumber: t.accountNumber,
  }));
}

export function validatePoalimSwiftTransactions(
  transactions: readonly PoalimSwiftTransactionInput[],
): IUploadPoalimSwiftTransactionsParams['transactions'] {
  return transactions.map(t => ({
    accountNumber: t.accountNumber,
    branchNumber: t.branchNumber,
    bankNumber: t.bankNumber,
    startDate: t.startDate,
    formattedStartDate: t.formattedStartDate,
    swiftStatusCode: t.swiftStatusCode,
    swiftStatusDesc: t.swiftStatusDesc,
    amount: t.amount?.toString(),
    currencyCodeCatenatedKey: t.currencyCodeCatenatedKey,
    currencyLongDescription: t.currencyLongDescription,
    chargePartyName: t.chargePartyName,
    referenceNumber: t.referenceNumber,
    transferCatenatedId: t.transferCatenatedId,
    dataOriginCode: t.dataOriginCode,
    swiftIsnSerialNumber: t.swiftIsnSerialNumber,
    swiftBankCode: t.swiftBankCode,
    orderCustomerName: t.orderCustomerName,
    beneficiaryEnglishStreetName: t.beneficiaryEnglishStreetName,
    beneficiaryEnglishCityName: t.beneficiaryEnglishCityName,
    beneficiaryEnglishCountryName: t.beneficiaryEnglishCountryName,
    swiftSendersReference20: t.swiftSendersReference20,
    swiftBankOperationCode23B: t.swiftBankOperationCode23B,
    swiftInstructionCode23E: t.swiftInstructionCode23E,
    swiftValueDateCurrencyAmount32A: t.swiftValueDateCurrencyAmount32A,
    swiftCurrencyInstructedAmount33B: t.swiftCurrencyInstructedAmount33B,
    swiftExchangeRate36: t.swiftExchangeRate36,
    swiftOrderingCustomer50K: t.swiftOrderingCustomer50K,
    swiftOrderingInstitution52A: t.swiftOrderingInstitution52A,
    swiftOrderingInstitution52D: t.swiftOrderingInstitution52D,
    swiftSendersCorrespondent53A: t.swiftSendersCorrespondent53A,
    swiftReceiversCorrespondent54A: t.swiftReceiversCorrespondent54A,
    swiftAccountWithInstitution57: t.swiftAccountWithInstitution57,
    swiftBeneficiaryCustomer59: t.swiftBeneficiaryCustomer59,
    swiftRemittanceInformation70: t.swiftRemittanceInformation70,
    swiftDetailsOfCharges71A: t.swiftDetailsOfCharges71A,
    swiftSendersCharges71F: t.swiftSendersCharges71F,
    swiftSendersToReceiverInformation72: t.swiftSendersToReceiverInformation72,
    swiftRegulatoryReporting77B: t.swiftRegulatoryReporting77B,
  }));
}

export function validateCalTransactions(
  transactions: readonly CalTransactionInput[],
): IUploadCalTransactionsParams['transactions'] {
  return transactions.map(t => ({
    card: t.card,
    trnIntId: t.trnIntId,
    trnNumaretor: t.trnNumaretor,
    merchantName: t.merchantName,
    trnPurchaseDate: t.trnPurchaseDate,
    trnAmt: t.trnAmt,
    trnCurrencySymbol: t.trnCurrencySymbol,
    trnType: t.trnType,
    trnTypeCode: t.trnTypeCode,
    debCrdDate: t.debCrdDate,
    amtBeforeConvAndIndex: t.amtBeforeConvAndIndex,
    debCrdCurrencySymbol: t.debCrdCurrencySymbol,
    merchantAddress: t.merchantAddress,
    merchantPhoneNo: t.merchantPhoneNo,
    branchCodeDesc: t.branchCodeDesc,
    transCardPresentInd: t.transCardPresentInd,
    curPaymentNum: t.curPaymentNum,
    numOfPayments: t.numOfPayments,
    tokenInd: t.tokenInd,
    walletProviderCode: t.walletProviderCode,
    walletProviderDesc: t.walletProviderDesc,
    tokenNumberPart4: t.tokenNumberPart4,
    cashAccountTrnAmt: t.cashAccountTrnAmt,
    chargeExternalToCardComment: t.chargeExternalToCardComment,
    refundInd: t.refundInd,
    isImmediateCommentInd: t.isImmediateCommentInd,
    isImmediateHhkInd: t.isImmediateHhkInd,
    isMargarita: t.isMargarita,
    isSpreadPaymenstAbroad: t.isSpreadPaymenstAbroad,
    trnExacWay: t.trnExacWay,
    debitSpreadInd: t.debitSpreadInd,
    onGoingTransactionsComment: t.onGoingTransactionsComment,
    earlyPaymentInd: t.earlyPaymentInd,
    merchantId: t.merchantId,
    crdExtIdNumTypeCode: t.crdExtIdNumTypeCode,
    transSource: t.transSource,
    isAbroadTransaction: t.isAbroadTransaction,
  }));
}

export function validateDiscountTransactions(
  transactions: readonly DiscountTransactionInput[],
): IUploadDiscountTransactionsParams['transactions'] {
  return transactions.map(t => ({
    operationDate: t.operationDate,
    valueDate: t.valueDate,
    operationCode: t.operationCode,
    operationDescription: t.operationDescription,
    operationDescription2: t.operationDescription2,
    operationDescription3: t.operationDescription3,
    operationBranch: t.operationBranch,
    operationBank: t.operationBank,
    accountNumber: t.accountNumber,
    channel: t.channel,
    channelName: t.channelName,
    checkNumber: t.checkNumber,
    instituteCode: t.instituteCode,
    operationAmount: t.operationAmount,
    balanceAfterOperation: t.balanceAfterOperation,
    operationNumber: t.operationNumber,
    branchTreasuryNumber: t.branchTreasuryNumber,
    urn: t.urn,
    operationDetailsServiceName: t.operationDetailsServiceName,
    commissionChannelCode: t.commissionChannelCode,
    commissionChannelName: t.commissionChannelName,
    commissionTypeName: t.commissionTypeName,
    businessDayDate: t.businessDayDate,
    eventName: t.eventName,
    categoryCode: t.categoryCode,
    categoryDescCode: t.categoryDescCode,
    categoryDescription: t.categoryDescription,
    operationDescriptionToDisplay: t.operationDescriptionToDisplay,
    operationOrder: t.operationOrder,
    isLastSeen: t.isLastSeen,
  }));
}

export function validateMaxTransactions(
  transactions: readonly MaxTransactionInput[],
): IUploadMaxTransactionsParams['transactions'] {
  return transactions.map(t => ({
    actualPaymentAmount: t.actualPaymentAmount,
    arn: t.arn,
    cardIndex: t.cardIndex,
    categoryId: t.categoryId,
    comments: t.comments,
    dealDataAcq: t.dealDataAcq,
    dealDataAdjustmentAmount: t.dealDataAdjustmentAmount,
    dealDataAdjustmentType: t.dealDataAdjustmentType,
    dealDataAmount: t.dealDataAmount,
    dealDataAmountIls: t.dealDataAmountIls,
    dealDataAmountLeft: t.dealDataAmountLeft,
    dealDataArn: t.dealDataArn,
    dealDataAuthorizationNumber: t.dealDataAuthorizationNumber,
    dealDataCardName: t.dealDataCardName,
    dealDataCardToken: t.dealDataCardToken,
    dealDataCommissionVat: t.dealDataCommissionVat,
    dealDataDirectExchange: t.dealDataDirectExchange,
    dealDataExchangeCommissionAmount: t.dealDataExchangeCommissionAmount,
    dealDataExchangeCommissionMaam: t.dealDataExchangeCommissionMaam,
    dealDataExchangeCommissionType: t.dealDataExchangeCommissionType,
    dealDataExchangeDirect: t.dealDataExchangeDirect,
    dealDataExchangeRate: t.dealDataExchangeRate,
    dealDataIndexRateBase: t.dealDataIndexRateBase,
    dealDataIndexRatePmt: t.dealDataIndexRatePmt,
    dealDataInterestAmount: t.dealDataInterestAmount,
    dealDataIsAllowedSpreadWithBenefit: t.dealDataIsAllowedSpreadWithBenefit,
    dealDataIssuerCurrency: t.dealDataIssuerCurrency,
    dealDataIssuerExchangeRate: t.dealDataIssuerExchangeRate,
    dealDataOriginalTerm: t.dealDataOriginalTerm,
    dealDataPercentMaam: t.dealDataPercentMaam,
    dealDataPlan: t.dealDataPlan,
    dealDataPosEntryEmv: t.dealDataPosEntryEmv,
    dealDataProcessingDate: t.dealDataProcessingDate,
    dealDataPurchaseAmount: t.dealDataPurchaseAmount,
    dealDataPurchaseTime: t.dealDataPurchaseTime,
    dealDataRefNbr: t.dealDataRefNbr,
    dealDataShowCancelDebit: t.dealDataShowCancelDebit,
    dealDataShowSpread: t.dealDataShowSpread,
    dealDataShowSpreadBenefitButton: t.dealDataShowSpreadBenefitButton,
    dealDataShowSpreadButton: t.dealDataShowSpreadButton,
    dealDataShowSpreadForLeumi: t.dealDataShowSpreadForLeumi,
    dealDataTdmCardToken: t.dealDataTdmCardToken,
    dealDataTdmTransactionType: t.dealDataTdmTransactionType,
    dealDataTransactionType: t.dealDataTransactionType,
    dealDataTxnCode: t.dealDataTxnCode,
    dealDataUserName: t.dealDataUserName,
    dealDataWithdrawalCommissionAmount: t.dealDataWithdrawalCommissionAmount,
    discountKeyAmount: t.discountKeyAmount,
    discountKeyRecType: t.discountKeyRecType,
    ethocaInd: t.ethocaInd,
    fundsTransferComment: t.fundsTransferComment,
    fundsTransferReceiverOrTransfer: t.fundsTransferReceiverOrTransfer,
    isRegisterCh: t.isRegisterCh,
    isSpreadingAutorizationAllowed: t.isSpreadingAutorizationAllowed,
    issuerId: t.issuerId,
    merchantAddress: t.merchantAddress,
    merchantCoordinates: t.merchantCoordinates,
    merchantMaxPhone: t.merchantMaxPhone,
    merchant: t.merchant,
    merchantCommercialName: t.merchantCommercialName,
    merchantNumber: t.merchantNumber,
    merchantPhone: t.merchantPhone,
    merchantTaxId: t.merchantTaxId,
    merchantName: t.merchantName,
    originalAmount: t.originalAmount,
    originalCurrency: t.originalCurrency,
    paymentCurrency: t.paymentCurrency,
    paymentDate: t.paymentDate,
    planName: t.planName,
    planTypeId: t.planTypeId,
    promotionAmount: t.promotionAmount,
    promotionClub: t.promotionClub,
    promotionType: t.promotionType,
    purchaseDate: t.purchaseDate,
    receiptPDF: t.receiptPDF,
    refIndex: t.refIndex,
    runtimeReferenceInternalId: t.runtimeReferenceInternalId,
    runtimeReferenceType: t.runtimeReferenceType,
    runtimeReferenceId: t.runtimeReferenceId,
    shortCardNumber: t.shortCardNumber,
    spreadTransactionByCampainInd: t.spreadTransactionByCampainInd,
    spreadTransactionByCampainNumber: t.spreadTransactionByCampainNumber,
    tableType: t.tableType,
    tag: t.tag,
    uid: t.uid,
    upSaleForTransactionResult: t.upSaleForTransactionResult,
    userIndex: t.userIndex,
  }));
}

export function validateIsracardAmexTransactions<
  T extends IsracardTransactionInput | AmexTransactionInput,
>(
  transactions: readonly T[],
): (T extends IsracardTransactionInput
  ? IUploadIsracardTransactionsParams
  : IUploadAmexTransactionsParams)['transactions'] {
  return transactions.map(t => {
    const validatedCard = Number.parseInt(t.card, 10);
    if (Number.isNaN(validatedCard)) {
      throw new Error(`Invalid card number: ${t.card}`);
    }
    return {
      specificDate: t.specificDate,
      cardIndex: t.cardIndex,
      dealsInbound: t.dealsInbound,
      supplierId: t.supplierId,
      supplierName: t.supplierName,
      dealSumType: t.dealSumType,
      paymentSumSign: t.paymentSumSign,
      purchaseDate: t.purchaseDate,
      fullPurchaseDate: t.fullPurchaseDate,
      moreInfo: t.moreInfo,
      horaatKeva: t.horaatKeva,
      voucherNumber: t.voucherNumber,
      voucherNumberRatz: t.voucherNumberRatz,
      solek: t.solek,
      purchaseDateOutbound: t.purchaseDateOutbound,
      fullPurchaseDateOutbound: t.fullPurchaseDateOutbound,
      currencyId: t.currencyId,
      currentPaymentCurrency: t.currentPaymentCurrency,
      city: t.city,
      supplierNameOutbound: t.supplierNameOutbound,
      fullSupplierNameOutbound: t.fullSupplierNameOutbound,
      paymentDate: t.paymentDate,
      fullPaymentDate: t.fullPaymentDate,
      isShowDealsOutbound: t.isShowDealsOutbound,
      adendum: t.adendum,
      voucherNumberRatzOutbound: t.voucherNumberRatzOutbound,
      isShowLinkForSupplierDetails: t.isShowLinkForSupplierDetails,
      dealSum: t.dealSum,
      paymentSum: t.paymentSum,
      fullSupplierNameHeb: t.fullSupplierNameHeb,
      dealSumOutbound: t.dealSumOutbound,
      paymentSumOutbound: t.paymentSumOutbound,
      isHoraatKeva: t.isHoraatKeva,
      stage: t.stage,
      returnCode: t.returnCode,
      message: t.message,
      returnMessage: t.returnMessage,
      displayProperties: t.displayProperties,
      tablePageNum: (t.tablePageNum ? '1' : '0') as unknown as boolean,
      isError: t.isError,
      isCaptcha: t.isCaptcha,
      isButton: t.isButton,
      siteName: t.siteName,
      clientIpAddress: t.clientIpAddress,
      card: validatedCard,
      chargingDate: t.chargingDate,
      kodMatbeaMekori: t.kodMatbeaMekori,
      esbServicesCall: t.esbServicesCall,
    };
  });
}

export function validateRates(
  rates: readonly CurrencyRateInput[],
): IUploadCurrencyRatesParams['rates'] {
  return rates.map(r => ({
    exchangeDate: r.exchangeDate,
    usd: r.usd,
    eur: r.eur,
    gbp: r.gbp,
    cad: r.cad,
    jpy: r.jpy,
    aud: r.aud,
    sek: r.sek,
  }));
}
