import { paymentMethodData } from '@fixtures/payment-method/payment-method-data';
import { utilitySelector, Timeouts } from '@utility-lib/index';

const paymentSelectors = {
  formNumber: '[formcontrolname="number"]',
  formCvc: '[formcontrolname="cvc"]',
  formNickname: '[formcontrolname="nickname"]',
  formFullName: '[formcontrolname="_fullName"]',
  formMonth: '[formcontrolname="expirationMonth"]',
  formYear: '[formcontrolname="expirationYear"]',
  formAddressLine1: '[formcontrolname="addressLine1"]',
  formCity: '[formcontrolname="city"]',
  formPostalCode: '[formcontrolname="postalCode"]',
  menuOption: '.mat-option-text',
  cvcErrorMessage: 'mat-error',
  filterCardsByTypeOrName: '[qaid="filterCardsByTypeOrName"]',
  helpPopup: '[class="contextual-help__content animate-help-panel"] span',
  otherPaymentDropdown: '[formcontrolname="backupPaymentMethodUuid"]',
  otherPaymentOption: 'mat-option',
  backUpAddCard: 'mat-option[value="addCard"]',
  useThisCard:
    '[class^="mat-focus-indicator mat-flat-button mat-button-base mat-primary ta-button"]',
  helpButton: '[class="icon-cross-filled button-icon close-help"]',
  modalContainer: 'modal-container',
  cardType: (cardType: string) => `[data-qa-id="${cardType}"]`,
  cardTable: 'app-ta-mat-table',
  issuerName: '[for="issuerName"]',
  deleteCardConfirmation: '[data-testid="delete-card-confirmation"]'
};

export class AdminPayment {
  static visitPage(): void {
    cy.visit('app/admin2/settings/payments');
  }

  static clickAddCard(cardType: string): void {
    cy.get(paymentSelectors.cardType(cardType)).click();
  }

  static closeHelpPopup() {
    cy.wait(Timeouts.SHORT_TIMEOUT_3_SEC.timeout);
    cy.get(utilitySelector.bodySelector).then((newTask) => {
      if (newTask.find(paymentSelectors.helpPopup).length > 0) {
        cy.allure().logStep('accept new task');
        cy.get(paymentSelectors.helpPopup).eq(0).click();
      }
    });
  }

  static enterNickname(cardNickname: string): void {
    cy.clearInputAndType(paymentSelectors.formNickname, cardNickname);
  }

  static enterCardNumber(cardNumber: string): void {
    cy.clearInputAndType(paymentSelectors.formNumber, cardNumber);
  }

  static enterCardCVC(cvc: string): void {
    cy.clearInputAndType(paymentSelectors.formCvc, cvc);
  }

  static enterCardInfo(): void {
    cy.get(paymentSelectors.formFullName).type(paymentMethodData.creditCard._fullName);
    cy.get(paymentSelectors.formMonth).click();
    cy.get(paymentSelectors.menuOption)
      .contains(
        `${paymentMethodData.creditCard.expirationMonthNumber} - ${paymentMethodData.creditCard.expirationMonthName}`
      )
      .click();
    cy.get(paymentSelectors.formYear).then((ele) => {
      cy.wrap(ele).click();
    });

    cy.get(paymentSelectors.menuOption)
      .contains(paymentMethodData.creditCard.expirationYear)
      .click();
  }

  static enterBillingAddressInfo(): void {
    cy.get(paymentSelectors.formAddressLine1).type(
      paymentMethodData.billingAddress.addressLine1
    );
    cy.get(paymentSelectors.formCity).type(paymentMethodData.billingAddress.city);
    cy.get(paymentSelectors.formPostalCode).type(
      paymentMethodData.billingAddress.postalCode
    );
  }

  static cvcErrorShould(state: string, cvcCheck: number): void {
    if (cvcCheck === 3) {
      cy.get(paymentSelectors.cvcErrorMessage)
        .contains('CVC must be 3 characters long')
        .should(state);
    } else if (cvcCheck === 4) {
      cy.get(paymentSelectors.cvcErrorMessage)
        .contains('CVC must be 4 characters long for AMEX')
        .should(state);
    }
  }

  static bottomButtonShould(text: string, state: string): void {
    cy.get(paymentSelectors.modalContainer).as('modalContainer');
    cy.get('@modalContainer').scrollTo('bottom');
    cy.get('@modalContainer')
      .find(utilitySelector.spanSelector)
      .contains(text)
      .parent(utilitySelector.buttonSelector)
      .should(state);
  }

  static clickBottomButton(text: string): void {
    cy.get(paymentSelectors.modalContainer).as('modalContainer');
    cy.get('@modalContainer').scrollTo('bottom');
    cy.get('@modalContainer')
      .find(utilitySelector.spanSelector)
      .contains(text)
      .parent(utilitySelector.buttonSelector)
      .click();
  }

  static clickEditButton(cardNickname: string): void {
    this.filterForCard(cardNickname);
    cy.get(paymentSelectors.cardTable)
      .eq(0)
      .find(utilitySelector.buttonSelector)
      .contains('Edit')
      .click();
  }

  static checkNewCardName(cardNickname: string): void {
    this.filterForCard(cardNickname);
    cy.get(paymentSelectors.cardTable)
      .eq(0)
      .find(utilitySelector.listItemSelector)
      .contains(cardNickname)
      .should('be.visible');
  }

  static filterForCard(cardNickname: string): void {
    cy.clearInputAndType(paymentSelectors.filterCardsByTypeOrName, cardNickname);
  }

  static editCard(): void {
    this.clickEditButton(paymentMethodData.nickname);
    this.enterNickname(paymentMethodData.creditCard._fullName);
    this.clickBottomButton('Save');
    this.checkNewCardName(paymentMethodData.creditCard._fullName);
  }

  static deleteCard(name: string): void {
    cy.get(paymentSelectors.cardTable)
      .contains(utilitySelector.listItemSelector, name)
      .parentsUntil(utilitySelector.tableRowSelector)
      .parent()
      .find(utilitySelector.buttonSelector)
      .contains('Delete')
      .click();
    cy.get(paymentSelectors.deleteCardConfirmation).click();
  }

  static checkIssuerSupplierName(issuerName: string): void {
    cy.get(paymentSelectors.issuerName)
      .siblings()
      .contains(issuerName)
      .should('be.visible');
  }

  static selectOtherPayment(): void {
    cy.get(paymentSelectors.otherPaymentDropdown).click();
    cy.get(paymentSelectors.otherPaymentOption).eq(1).click();
  }

  static clickDesignateCard(): void {
    cy.get(paymentSelectors.modalContainer)
      .find(utilitySelector.spanSelector)
      .contains('Designate a card')
      .parent(utilitySelector.buttonSelector)
      .click();
  }
  static selectOtherPaymentAsAddCard(): void {
    cy.allure().logStep('Click the Add card link from backup drop down');
    cy.get(paymentSelectors.otherPaymentDropdown).click();
    cy.get(paymentSelectors.backUpAddCard).click();
  }
  static selectUseThisCard(): void {
    cy.get(paymentSelectors.useThisCard).click();
  }
  static errorMessage(message: string): void {
    cy.contains(message);
  }
  static clickHelpButton(): void {
    cy.get(paymentSelectors.helpButton).click();
  }
}
