import { Timeouts, guidRegex } from '@utility-lib/index';

const approvalBookingsSelectors = {
  approvalsBreadcrumb: '[qaid="approvalsPageTitle"]',
  approvalBookingsTitle: '[qaid="pageTitle"]',
  approvalStatusSelect: '[qaid="approvalsStatusSelect"]',
  approvalStatusPending: '[qaid="approvalsStatusPending"]',
  approvalStatusApproved: '[qaid="approvalsStatusApproved"]',
  approvalStatusDeclined: '[qaid="approvalsStatusDeclined"]',
  bookingListingsToggle: '[qaid="bookingListingsToggle-0"]',
  bookingListingsExpanded: '[aria-expanded="true"]',
  bookingListingsBtn: '[qaid="bookingListingsDetailsBtn-0"]',
  backToApprovalsListings: '.approvals-header__link',
  approvalsMenuButton: '[data-qaid="APPROVALS"]',
  tripProposalMenuItem: '[data-qaid="APPROVALS_PROPOSALS"]',
  delegateApprovalWindow: '.delegation-window',
  emptyBookingListing: '[qaid="emptyBookingListing"]',
  emptyListingTitle: '[qaid="emptyBookingListingTitle"]',
  tripProposalRejectBtn: '[qaid="tripProposalRejectAction"]',
  tripProposalApproveBtn: '[qaid="tripProposalApproveAction"]',
  tripProposalActionModal: '.cdk-overlay-pane',
  tripProposalActionModalTitle: '[qaid="proposalModalTitle"]',
  tripProposalModalCancelBtn: '[qaid="cancelProposalModalBtn"]',
  tripProposalApproveButton: '[qaid="approvedProposalModalBtn"]'
};

export class ApprovalBookingsPage {
  static visitBookingsPage() {
    cy.allure().logStep('Visit approvals > bookings page');
    cy.intercept('GET', /api\/admin\/bookingApprovals/).as('waitForPendingApprovals');
    cy.visit('app/admin2/approvals/manageAllApprovals');
    cy.url().should('include', '/manageAllApprovals');
    cy.wait('@waitForPendingApprovals');
  }

  static verifyApprovalBookingsPage() {
    cy.allure().logStep('Verify approvals bookings page');
    cy.get(approvalBookingsSelectors.approvalsBreadcrumb).should('be.visible');
    cy.get(approvalBookingsSelectors.approvalBookingsTitle).contains(
      'Approvals > Bookings'
    );
  }

  static verifyBookingListings() {
    cy.allure().logStep('Verify booking listings');
    ApprovalBookingsPage.verifyBookingListingsToggletIsVisible();
    cy.get(approvalBookingsSelectors.bookingListingsToggle).click();
    cy.get(approvalBookingsSelectors.bookingListingsExpanded).should('exist');
    cy.get(approvalBookingsSelectors.bookingListingsToggle).click();
  }

  static gotoSelectedListingPage() {
    cy.allure().logStep('Go to selected booking details page');
    cy.intercept('GET', new RegExp(`/api/admin/bookingApprovals/${guidRegex}`)).as(
      'waitForApprovalDetails'
    );
    cy.get(approvalBookingsSelectors.bookingListingsBtn).click();
    cy.url().should('match', new RegExp(guidRegex));
    cy.wait('@waitForApprovalDetails');
  }

  static goBackToListings() {
    cy.allure().logStep('Go back to listings page');
    cy.intercept('GET', /api\/admin\/bookingApprovals/).as('waitForPendingApprovals');
    cy.get(approvalBookingsSelectors.backToApprovalsListings).click();
    cy.wait('@waitForPendingApprovals');
  }

  static selectBookingDeclinedStatus() {
    cy.allure().logStep('Select declined booking status');
    ApprovalBookingsPage.verifyStatusSelectIsVisible();
    cy.get(approvalBookingsSelectors.approvalStatusSelect).click();
    cy.get(approvalBookingsSelectors.approvalStatusDeclined).click();
  }

  static selectBookingApprovedStatus() {
    cy.allure().logStep('Select approved booking status');
    ApprovalBookingsPage.verifyStatusSelectIsVisible();
    cy.get(approvalBookingsSelectors.approvalStatusSelect).click();
    cy.get(approvalBookingsSelectors.approvalStatusApproved).click();
  }

  static selectBookingPendingStatus() {
    cy.allure().logStep('Select pending booking status');
    ApprovalBookingsPage.verifyStatusSelectIsVisible();
    cy.get(approvalBookingsSelectors.approvalStatusSelect).click();
    cy.get(approvalBookingsSelectors.approvalStatusPending).click();
  }

  static verifyEmptyPageListings() {
    cy.allure().logStep('Verify empty listing');
    cy.get(approvalBookingsSelectors.emptyBookingListing).should('be.visible');
    cy.get(approvalBookingsSelectors.emptyBookingListing)
      .find(approvalBookingsSelectors.emptyListingTitle)
      .contains('There are no requests for approval.');
  }

  static goToTripProposalsPage(index = 0) {
    cy.allure().logStep('Go to trip proposal page');
    cy.intercept('GET', /api\/admin\/tripProposals\?tripProposalApprovalStatus/).as(
      'waitForTripProposals'
    );
    cy.get(approvalBookingsSelectors.approvalsMenuButton).eq(index).click();
    cy.get(approvalBookingsSelectors.tripProposalMenuItem).click();
    cy.url().should('include', '/trip-proposals-all');
    cy.wait('@waitForTripProposals');
  }

  static verifyApprovalModal(index = 0) {
    cy.allure().logStep('Verify trip proposal approval modal');
    cy.get(approvalBookingsSelectors.tripProposalApproveBtn).eq(index).click();
    cy.get(approvalBookingsSelectors.tripProposalActionModal)
      .find(approvalBookingsSelectors.tripProposalActionModalTitle)
      .contains('Approve trip proposal');
    cy.get(approvalBookingsSelectors.tripProposalModalCancelBtn).click();
  }

  static verifyRejectionModal(index = 0) {
    cy.allure().logStep('Verify trip proposal rejection modal');
    cy.get(approvalBookingsSelectors.tripProposalRejectBtn).eq(index).click();
    cy.get(approvalBookingsSelectors.tripProposalActionModal)
      .find(approvalBookingsSelectors.tripProposalActionModalTitle)
      .contains('Decline trip proposal');
  }

  static approveTripProposal(index = 0) {
    cy.allure().logStep('Approving trip proposal');
    cy.get(approvalBookingsSelectors.tripProposalApproveBtn).eq(index).click();
    cy.get(approvalBookingsSelectors.tripProposalActionModal)
      .find(approvalBookingsSelectors.tripProposalActionModalTitle)
      .contains('Approve trip proposal');
    cy.intercept(
      'GET',
      new RegExp(`api/admin/tripProposals/${guidRegex}/status/approved`)
    ).as('waitForTripApproval');
    cy.get(approvalBookingsSelectors.tripProposalApproveButton).click();
    cy.url().should('match', new RegExp(guidRegex));
    cy.wait('@waitForTripApproval');
  }

  static clearCacheAndLoginAs(email: string, password: string, isSA: boolean) {
    cy.clearLocalStorage();
    cy.clearCookies();
    cy.clearLocalStorage();
    cy.loginWithAuthToken({ email, password, isSA });
  }

  static verifyStatusSelectIsVisible() {
    cy.get(
      approvalBookingsSelectors.approvalStatusSelect,
      Timeouts.MAX_TIMEOUT_120_SEC // TODO: decrease timeout once /api/admin/bookingApprovals is more stable
    ).should('be.visible');
  }

  static verifyBookingListingsToggletIsVisible() {
    cy.get(
      approvalBookingsSelectors.bookingListingsToggle,
      Timeouts.MAX_TIMEOUT_120_SEC // TODO: decrease timeout once /api/admin/bookingApprovals is more stable
    ).should('be.visible');
  }
}
