import {
  companyDiscountsSelectors,
  companyInformationSelectors,
  companyPolicySelectors,
  loyaltyProgramsSelectors,
  paymentMethodsSelectors,
  travelCreditsSelectors,
  travelPreferencesSelectors,
  userDetailsPageSelectors,
  userInformationSelectors,
  userRewardsSelectors
} from '@travelxen-lib/selectors/user';
import { commonPageSelectors } from '@travelxen-lib/selectors/common';

export class TravelXenAccountPage {
  static navigateBackToOverview() {
    cy.allure().logStep('navigate back to overview');
    cy.get(userDetailsPageSelectors.overviewNavBtn).click();
  }

  static verifyUserInformationViewRenders() {
    cy.allure().logStep('navigate to user information view');
    cy.get(userInformationSelectors.userInformationNavBtn).click();
    userInformationSelectors.children.forEach(({ name, selector }) => {
      cy.allure().logStep(`user information sub view called ${name} renders`);
      cy.get(selector).should('exist');
    });
    this.navigateBackToOverview();
  }

  static verifyTravelCreditViewRenders() {
    cy.allure().logStep('navigate to travel credits view');
    cy.get(travelCreditsSelectors.travelCreditsNavBtn).click();
    cy.get(travelCreditsSelectors.travelCreditsView).should('exist');
    this.navigateBackToOverview();
  }

  static verifyPaymentMethodsViewRenders() {
    cy.allure().logStep('navigate to payment methods view');
    cy.get(paymentMethodsSelectors.paymentMethodsNavBtn).click();
    cy.get(paymentMethodsSelectors.paymentMethodsView).should('exist');
    this.navigateBackToOverview();
  }

  static verifyOtpFlow() {
    cy.allure().logStep('navigate to payment methods view');
    cy.get(paymentMethodsSelectors.paymentMethodsNavBtn).click();
    cy.get(paymentMethodsSelectors.paymentMethodsView).should('exist');

    cy.allure().logStep('open payment details access request modal');
    cy.get(paymentMethodsSelectors.paymentMethodsViewBtn).click();
    cy.get(paymentMethodsSelectors.accessRequestModal.container).should('exist');

    cy.get(paymentMethodsSelectors.accessRequestModal.container).within(() => {
      cy.get(paymentMethodsSelectors.accessRequestModal.permissionCheckbox)
        .next()
        .click();
      cy.get(paymentMethodsSelectors.accessRequestModal.submitButton).click();
      cy.wait('@sendRequest')
        .its('response')
        .should((response) => {
          expect(response?.statusCode).to.eq(201);
        });

      // TODO: Use real response when code would be accessible somehow  // ****
      cy.get(paymentMethodsSelectors.accessRequestModal.codeInput).type('1234');
      cy.wait('@getPaymentDetails')
        .its('response')
        .should((response) => {
          expect(response?.statusCode).to.eq(200);
        });
      cy.get(paymentMethodsSelectors.accessRequestModal.submitButton).click();
    });

    cy.allure().logStep('close modal');
    cy.get(paymentMethodsSelectors.detailsModal.container).within(() => {
      cy.get(paymentMethodsSelectors.detailsModal.closeButton).click();
    });

    this.navigateBackToOverview();
  }

  static verifyOtpFallbackFlow() {
    cy.allure().logStep('navigate to payment methods view');
    cy.get(paymentMethodsSelectors.paymentMethodsNavBtn).click();
    cy.get(paymentMethodsSelectors.paymentMethodsView).should('exist');

    cy.allure().logStep('open payment details access request modal');
    cy.get(paymentMethodsSelectors.paymentMethodsViewBtn).click();
    cy.get(paymentMethodsSelectors.accessRequestModal.container).should('exist');
    cy.allure().logStep('go to access without authentication');
    cy.get(paymentMethodsSelectors.accessRequestModal.noAuthButton).click();
    cy.get(paymentMethodsSelectors.fallbackModal.container).should('exist');

    cy.allure().logStep('choose the reason and go to details modal');
    cy.get(paymentMethodsSelectors.fallbackModal.container).within(() => {
      cy.get(paymentMethodsSelectors.fallbackModal.justificationSelect).click();
      cy.get(paymentMethodsSelectors.fallbackModal.justificationSelect).type('O');
      cy.get(commonPageSelectors.menuList).children().eq(1).click();
      cy.get(paymentMethodsSelectors.fallbackModal.justificationDetails).type(
        'With great power comes great responsibility'
      );
      cy.get(paymentMethodsSelectors.fallbackModal.submitButton).click();
    });

    cy.wait('@getPaymentDetails')
      .its('response.statusCode')
      .should('be.oneOf', [200, 304]);

    cy.allure().logStep('close modal');
    cy.get(paymentMethodsSelectors.detailsModal.container).within(() => {
      cy.get(paymentMethodsSelectors.detailsModal.closeButton).click();
    });

    this.navigateBackToOverview();
  }

  static verifyCompanyInformationViewRenders() {
    cy.allure().logStep('navigate to company information view');
    cy.get(companyInformationSelectors.companyInformationNavBtn).click();
    companyInformationSelectors.children.forEach(({ name, selector }) => {
      cy.allure().logStep(`company information sub view called ${name} renders`);
      cy.get(selector).should('exist');
    });
    this.navigateBackToOverview();
  }

  static verifyCompanyDiscountsViewRenders() {
    cy.allure().logStep('navigate to company discounts view');
    cy.get(companyDiscountsSelectors.companyDiscountsNavBtn).click();
    cy.get(companyDiscountsSelectors.companyDiscountTabs).should('be.visible');
    cy.get(companyDiscountsSelectors.companyDiscountTabs).each(($tab) => {
      cy.wrap($tab).click();
      cy.wrap($tab).then(() => {
        cy.get(companyDiscountsSelectors.companyDiscountsTable)
          .should('be.visible')
          .then(() => {
            cy.allure().logStep('Company Discounts table is visible');
          });
      });
    });
    this.navigateBackToOverview();
  }

  static verifyCompanyPolicyViewRenders() {
    cy.allure().logStep('navigate to company policy view');
    cy.get(companyPolicySelectors.companyPolicyNavBtn).click();
    companyPolicySelectors.children.forEach((ddItem, index) => {
      cy.get(companyPolicySelectors.policyDropdownSelector).click();
      cy.get(ddItem.selector).eq(index).click();
      cy.allure().logStep(`selected dropdown option ${ddItem.name}`);
      cy.get(companyPolicySelectors.subviewTriggerSelector).each(($subviewBtn, index) => {
        cy.wrap($subviewBtn).click();
        cy.wrap($subviewBtn).then(() => {
          const subview = ddItem.children[index];
          cy.allure().logStep(`navigated to ${subview.name}`);
          cy.get(subview.selector).should('exist');
        });
      });
    });
    this.navigateBackToOverview();
  }

  static verifyLoyaltyProgramsViewRenders() {
    cy.allure().logStep('navigate to loyalty programs view');
    cy.get(loyaltyProgramsSelectors.loyaltyProgramsNavBtn).click();
    cy.get(loyaltyProgramsSelectors.loyaltyProgramsView).should('have.length', 4);
  }

  static verifyVipPreferencesViewRenders() {
    cy.allure().logStep('navigate to travel preferences view');
    cy.get(travelPreferencesSelectors.travelPreferencesNavBtn).click();
    cy.get(travelPreferencesSelectors.travelPreferencesView).should('exist');
    cy.get(travelPreferencesSelectors.travelPreferencesTabs.selector).should(
      'have.length',
      4
    );
    cy.get(travelPreferencesSelectors.travelPreferencesTabs.selector).each(
      ($tab, index) => {
        cy.wrap($tab).click();
        cy.wrap($tab).then(() => {
          const view = travelPreferencesSelectors.travelPreferencesTabs.children[index];
          cy.allure().logStep(`navigate to ${view.name}`);
          cy.get(view.selector).should('exist');
        });
      }
    );

    this.navigateBackToOverview();
  }

  static verifyUserRewardsViewRenders() {
    cy.allure().logStep('navigate to user rewards view');
    cy.get(userRewardsSelectors.userRewardsNavBtn).click();
    cy.get(userRewardsSelectors.userRewardsView).should('exist');

    this.navigateBackToOverview();
  }
}
