//
//  RedeemTests.swift
//  Pi 
//  Copyright © 2021 Evidation Health Inc. All rights reserved.
//
//  UI Test for testing redemption flow. Removing from test plan because the offer is archived

import XCTest

class RedeemTests: PiTestBase {
    // Variable to delete the app
    override var deleteApp: Bool { true }
    /*
     * UI test for testing redeem flow using virtual visa card
     */
    func testRedeemFlowForVirtualVisa() {
        // Init the various pages
        let virtualVisaPage = VirtualVisaCardPage(application: app)
        let actionsPage = ActionsPage(application: app)
        
        // Add custom offer, login and assert the presence of the offer
        addCustomOfferAndAssert()
        
        // Complete the offer and validate points
        completeCustomOfferAndValidatePoints()
        
        // Checking if by pressing from Actions tab on the points goes to points tab
        actionsPage.enterActionsTab()
        app.staticTexts["Current Balance"].tap()
        
        // Cashing out, entering redeem flow and choosing a redemption option
        let safariApp = cashOutAndSelectRedeemOption(redeemOption: " VIRTUAL VISA")
        
        // Validating virtual visa page, enter details and redeem
        virtualVisaPage.validateVirtualVisaPage(forApp: safariApp)
        virtualVisaPage.enterVirtualAccountDetails(forApp: safariApp)
        virtualVisaPage.acceptAgreementAndRedeem(forApp: safariApp)
        
        // Validate redeemed page and exiting safari
        let redeem_button = safariApp.buttons["REDEEM $10"]
        if (redeem_button.waitForExistence(timeout: 15)) {
            redeem_button.tap()
        }
        virtualVisaPage.validateRedeemedPage(forApp: safariApp)
        safariApp.terminate()
        
        // Validating redemption history comes by activating app, swiping down to refresh the app
        validateCashRedeemedHistory()
    }
    
    /*
     * UI test for testing redeem flow using Walmart gift card
     */
    func testRedeemFlowForWalmartGiftCard() {
        // Init the various pages
        let giftCardPages = GiftCardPages(application: app)
        
        // Add custom offer, login and assert the presence of the offer
        addCustomOfferAndAssert()
        
        // Complete the offer and validate points
        completeCustomOfferAndValidatePoints()
        
        // Cashing out, entering redeem flow and choosing a redemption option
        let safariApp = cashOutAndSelectRedeemOption(redeemOption: " GIFT CARDS")
        
        // Validate we are on gift card page, check the various options and enter the required option(Walmart)
        giftCardPages.validateGiftCardPage(forApp: safariApp)
        giftCardPages.validateGiftCardOptions(forApp: safariApp)
        giftCardPages.enterGiftCardOption(forApp: safariApp, option: "Walmart gift card")
        
        // Redeem the corresponding gift card(Walmart), validate it is redeemed and exit safari
        giftCardPages.redeemGiftCard(forApp: safariApp, option: "Walmart gift card")
        giftCardPages.validateGiftCardRedeemed(forapp: safariApp)
        safariApp.terminate()
        
        // Validating redemption history comes by activating app, swiping down to refresh the app
        validateCashRedeemedHistory()
    }
    
    /*
     * UI test for testing redeem flow using Target gift card
     */
    func testRedeemFlowForTargetGiftCard() {
        // Init the various pages
        let giftCardPages = GiftCardPages(application: app)
        
        // Add custom offer, login and assert the presence of the offer
        addCustomOfferAndAssert()
        
        // Complete the offer and validate points
        completeCustomOfferAndValidatePoints()
        
        // Cashing out, entering redeem flow and choosing a redemption option
        let safariApp = cashOutAndSelectRedeemOption(redeemOption: " GIFT CARDS")
        
        // Validate we are on gift card page, check the various options and enter the required option(Target)
        giftCardPages.validateGiftCardPage(forApp: safariApp)
        giftCardPages.validateGiftCardOptions(forApp: safariApp)
        giftCardPages.enterGiftCardOption(forApp: safariApp, option: "Target gift card")
        
        // Redeem the corresponding gift card(Target), validate it is redeemed and exit safari
        giftCardPages.redeemGiftCard(forApp: safariApp, option: "Target gift card")
        giftCardPages.validateGiftCardRedeemed(forapp: safariApp)
        safariApp.terminate()
        
        // Validating redemption history comes by activating app, swiping down to refresh the app
        validateCashRedeemedHistory()
    }
    
    /*
     * UI test for testing redeem flow using Starbucks gift card
     */
    func testRedeemFlowForStarbucksGiftCard() {
        // Init the various pages
        let giftCardPages = GiftCardPages(application: app)
        
        // Add custom offer, login and assert the presence of the offer
        addCustomOfferAndAssert()
        
        // Complete the offer and validate points
        completeCustomOfferAndValidatePoints()
        
        // Cashing out, entering redeem flow and choosing a redemption option
        let safariApp = cashOutAndSelectRedeemOption(redeemOption: " GIFT CARDS")
        
        // Validate we are on gift card page, check the various options and enter the required option(Starbucks)
        giftCardPages.validateGiftCardPage(forApp: safariApp)
        giftCardPages.validateGiftCardOptions(forApp: safariApp)
        giftCardPages.enterGiftCardOption(forApp: safariApp, option: "Starbucks gift card")
        
        // Redeem the corresponding gift card(Starbucks), validate it is redeemed and exit safari
        giftCardPages.redeemGiftCard(forApp: safariApp, option: "Starbucks gift card")
        giftCardPages.validateGiftCardRedeemed(forapp: safariApp)
        safariApp.terminate()
        
        // Validating redemption history comes by activating app, swiping down to refresh the app
        validateCashRedeemedHistory()
    }
    
    /*
     * UI test for testing redeem flow using Amazon gift card
     */
    func testRedeemFlowForAmazonGiftCard() {
        // Init the various pages
        let giftCardPages = GiftCardPages(application: app)
        
        // Add custom offer, login and assert the presence of the offer
        addCustomOfferAndAssert()
        
        // Complete the offer and validate points
        completeCustomOfferAndValidatePoints()
        
        // Cashing out, entering redeem flow and choosing a redemption option
        let safariApp = cashOutAndSelectRedeemOption(redeemOption: " GIFT CARDS")
        
        // Validate we are on gift card page, check the various options and enter the required option(Amazon)
        giftCardPages.validateGiftCardPage(forApp: safariApp)
        giftCardPages.validateGiftCardOptions(forApp: safariApp)
        giftCardPages.enterGiftCardOption(forApp: safariApp, option: "Amazon.com gift card")
        
        // Redeem the corresponding gift card(Amazon), validate it is redeemed and exit safari
        giftCardPages.redeemGiftCard(forApp: safariApp, option: "Amazon.com gift card")
        giftCardPages.validateGiftCardRedeemed(forapp: safariApp)
        safariApp.terminate()
        
        // Validating redemption history comes by activating app, swiping down to refresh the app
        validateCashRedeemedHistory()
    }
    
    /*
     * Method addCustomOfferAndAssert is to add custom article offer to the user, logging in and validating its presence
     */
    private func addCustomOfferAndAssert() {
        let landingPage = LandingPage(application: app)
        let loginPage = SignInPage(application: app)
        let actionsPage = ActionsPage(application: app)
        let customArticleOfferPage = Custom10kArticleOffer(application: app)
        
        // Calculating the date of birth and user email
        let date_value = DateUtility().generateDOB(currentAge: 25)
        let user_email = EmailGenerationUtil.generateUniqueTestUserEmail(userName: BasePage(application: app).USER_EMAIL_HOST)
        
        // Creating user through BE endpoints
        user = SeedPiUser().createUserUsingAPIEndpoints(userEmail: user_email,
                                                        userFirstName: BasePage(application: app).USER_FIRST_NAME,
                                                        userLastName: BasePage(application: app).USER_LAST_NAME,
                                                        userDOB: date_value,
                                                        userPhone: BasePage(application: app).USER_PHONE_NUMER,
                                                        userPassword: BasePage(application: app).USER_PASSWORD)
        
        // Creating user
//        let userValues = SeedPiUser().createUserUsingQAEndpoint(email: user_email,
//                                                                password: "Evidation1",
//                                                                completeOnBoard: true)
        
        // Adding the experience to be used for redemption
        AddExperience().addExperienceWithEmail(userEmail: user_email,
                                               experienceIdentifier: "7fpBWWrPx8TdKY3a87p4eC")
        
        // Login with seeded user
        landingPage.landingPageTitleVerify()
        landingPage.clickOnSigningButton()
        loginPage.login(userName: user.getUserEmail(), password: user.getUserPassword())
        
        // Asserting tasks tab
        XCTAssert(app.staticTexts["Tasks"].waitForExistence(timeout: 40))
        actionsPage.actionsPageActiveVerify()
        
        // Asserting the offer is present and enter the offer
        customArticleOfferPage.assertCustomArticleOffer(position: 0)
    }
    
    /*
     * Method completeCustomOfferAndValidatePoints is to complete the offer and validate points
     */
    private func completeCustomOfferAndValidatePoints() {
        let actionsPage = ActionsPage(application: app)
        let pointsPage = PointsPage(application: app)
        let customArticleOfferPage = Custom10kArticleOffer(application: app)
        
        // Enter the offer
        customArticleOfferPage.enterCustomArticleOffer(position: 0)
        
        // Complete the custom article offer
        customArticleOfferPage.completeCustomArticleOffer()
        
        // Validating points in actions page
        actionsPage.validatePointsActionsPage(pointsValue: " 10,000")
        
        // Verify points in points page
        pointsPage.enterPointsTab()
        pointsPage.validatePointsLearnMorePage()
        pointsPage.verifyPointsTabPage()
        pointsPage.verifyPointsAwardedForCompletingOffer(offerText: "Read article: Points Offer for Redemption Tests", pointsValue: "+ 10,000")
    }
    
    /*
     * Method cashOutAndSelectRedeemOption is to cash out and enter redeem flow to choose an option
     */
    private func cashOutAndSelectRedeemOption(redeemOption: String) -> XCUIApplication {
        let pointsPage = PointsPage(application: app)
        let safariPage = SafariPage(application: app)
        let redeemPage = RedeemPage(application: app)
        
        // Pressing the cash out button and navigating until tremendous page
        pointsPage.pressCashOutButton(cashOutValue: "10.00")
        pointsPage.redeemGiftCardPage()
        pointsPage.handleAlert(alertTitle: "Confirm reward", alertButton: "Confirm")
        
        // Activating safari app, asserting redeem page and press REDEEM button
        let safariApp = safariPage.activateSafariApp()
        redeemPage.validateRedeemPage(forApp: safariApp)
        redeemPage.assertRedeemButtonAndTap(forApp: safariApp)
        
        // Validating redemption options page and clicking on virtual visa option
        redeemPage.validateRedeemOptions(forApp: safariApp)
        redeemPage.tapRedemptionOption(forApp: safariApp, optionValue: redeemOption)
        
        return safariApp
    }
    
    /*
     * Method validateCashRedeemedHistory is to check the points has been cashed out
     */
    private func validateCashRedeemedHistory() {
        let pointsPage = PointsPage(application: app)
        
        // Activate the app, validate cash is redeemed
        pointsPage.app.activate()
        pointsPage.app.swipeDown()
        pointsPage.app.swipeDown()
        pointsPage.waitForElementToExist(element: app.buttons["Cash out $0.00"], timeout: 15)
        pointsPage.verifyPointsAwardedForCompletingOffer(offerText: "Points redeemed", pointsValue: "- 10,000")
    }
}
