import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import static com.kms.katalon.core.testobject.ObjectRepository.findWindowsObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testng.keyword.TestNGBuiltinKeywords as TestNGKW
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import com.kms.katalon.core.windows.keyword.WindowsBuiltinKeywords as Windows
import internal.GlobalVariable as GlobalVariable
import org.openqa.selenium.Keys as Keys

/**
 * Login Test Case
 * Tags: AUTH, P1, SMOKE, 2FA
 * 
 * This test verifies user login with email authentication and 2FA email confirmation:
 * - Navigate to login page
 * - Enter valid credentials
 * - Handle 2FA verification
 * - Verify successful login and redirection
 * - Test session management
 */

// Test Case 1: Navigate to login page and verify initial state
println "=== Test Case 1: Initial Setup and Navigation ==="
WebUI.openBrowser('')
WebUI.maximizeWindow()
WebUI.navigateToUrl(GlobalVariable.url)
WebUI.waitForPageLoad(10, FailureHandling.STOP_ON_FAILURE)

// Verify page loaded correctly
String pageTitle = WebUI.getWindowTitle()
if (!pageTitle || pageTitle.trim() == '') {
    WebUI.fail("Login page failed to load")
}
println "✓ Login page loaded successfully: ${pageTitle}"

// Check if we're on the login page by verifying login form elements
boolean hasEmailField = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputEmail'), 5, FailureHandling.OPTIONAL)
boolean hasPasswordField = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputPassword'), 5, FailureHandling.OPTIONAL)
boolean hasLoginButton = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/button_Forgot password_btn btn-primary'), 5, FailureHandling.OPTIONAL)

println "Login form elements found: Email=${hasEmailField}, Password=${hasPasswordField}, Button=${hasLoginButton}"

if (!hasEmailField || !hasPasswordField || !hasLoginButton) {
    WebUI.fail("Login form elements not found - not on login page")
}

// Test Case 2: Verify login form structure
println "=== Test Case 2: Login Form Structure ==="

// Check for additional login form elements using proper Katalon objects
boolean hasLoginTitle = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/h1_Login'), 5, FailureHandling.OPTIONAL)
boolean hasSignInText = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/text_Sign In'), 5, FailureHandling.OPTIONAL)

if (hasLoginTitle || hasSignInText) {
    println "✓ Login page content verified"
} else {
    println "⚠ Login page content may not be correct"
}

// Check for remember me functionality
boolean hasRememberMe = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/checkbox_Remember me'), 5, FailureHandling.OPTIONAL)
if (hasRememberMe) {
    println "✓ Remember me functionality is available"
} else {
    println "⚠ Remember me functionality not found"
}

// Check for forgot password link
boolean hasForgotPassword = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/link_Forgot password'), 5, FailureHandling.OPTIONAL)
if (hasForgotPassword) {
    println "✓ Forgot password functionality is available"
} else {
    println "⚠ Forgot password functionality not found"
}

// Test Case 3: Enter login credentials
println "=== Test Case 3: Enter Login Credentials ==="

// Clear and enter email
WebUI.clearText(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputEmail'), FailureHandling.STOP_ON_FAILURE)
WebUI.setText(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputEmail'), GlobalVariable.username, FailureHandling.STOP_ON_FAILURE)

// Clear and enter password
WebUI.clearText(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputPassword'), FailureHandling.STOP_ON_FAILURE)
WebUI.setText(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputPassword'), GlobalVariable.password, FailureHandling.STOP_ON_FAILURE)

// Verify credentials were entered
String enteredEmail = WebUI.getAttribute(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputEmail'), 'value', FailureHandling.STOP_ON_FAILURE)
String enteredPassword = WebUI.getAttribute(findTestObject('Object Repository/Page_Login  Transactflow/input_LOGIN_inputPassword'), 'value', FailureHandling.STOP_ON_FAILURE)

if (enteredEmail == GlobalVariable.username) {
    println "✓ Email entered correctly"
} else {
    WebUI.fail("Email not entered correctly. Expected: ${GlobalVariable.username}, Got: ${enteredEmail}")
}

if (enteredPassword == GlobalVariable.password) {
    println "✓ Password entered correctly"
} else {
    WebUI.fail("Password not entered correctly")
}

// Get the date just before submitting the form for 2FA email tracking
Date today = new Date()
String todaysDate = today.format('yyyy/MM/dd')
String nowTime = today.format('HH:mm:ss')
GlobalVariable.LoginDate = todaysDate + ' ' + nowTime
println "Login attempt timestamp: ${GlobalVariable.LoginDate}"

// Test Case 4: Submit login form
println "=== Test Case 4: Submit Login Form ==="

// Click login button
WebUI.click(findTestObject('Object Repository/Page_Login  Transactflow/button_Forgot password_btn btn-primary'), FailureHandling.STOP_ON_FAILURE)

// Wait for response
WebUI.delay(3)

// Test Case 5: Handle 2FA verification if present
println "=== Test Case 5: Handle 2FA Verification ==="

// Check for 2FA field
boolean has2FAField = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/input_Remember this device for 30 days_inpu_99772f'), 5, FailureHandling.OPTIONAL)

if (has2FAField) {
    println "✓ 2FA field detected, proceeding with 2FA verification"
    
    // Check for 2FA page content using proper Katalon objects
    boolean has2FATitle = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/h1_2FA Verification'), 5, FailureHandling.OPTIONAL)
    boolean has2FAText = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/text_verification code'), 5, FailureHandling.OPTIONAL)
    
    if (has2FATitle || has2FAText) {
        println "✓ 2FA verification page loaded correctly"
    } else {
        println "⚠ 2FA verification page content may not be correct"
    }
    
    try {
        // Get 2FA code from email
        println "Attempting to get 2FA verification code from email..."
        String verificationCode = WebUI.callTestCase(findTestCase('Test Cases/01_Authentication/Read GMail 2fa Code'), null, FailureHandling.OPTIONAL)
        
        if (verificationCode && verificationCode.trim() != '') {
            println "✓ 2FA code received: ${verificationCode}"
            
            // Enter 2FA code
            WebUI.clearText(findTestObject('Object Repository/Page_Transactflow/input_Remember this device for 30 days_inpu_99772f'), FailureHandling.STOP_ON_FAILURE)
            WebUI.setText(findTestObject('Object Repository/Page_Transactflow/input_Remember this device for 30 days_inpu_99772f'), verificationCode, FailureHandling.STOP_ON_FAILURE)
            
            // Verify 2FA code was entered
            String entered2FACode = WebUI.getAttribute(findTestObject('Object Repository/Page_Transactflow/input_Remember this device for 30 days_inpu_99772f'), 'value', FailureHandling.STOP_ON_FAILURE)
            if (entered2FACode == verificationCode) {
                println "✓ 2FA code entered correctly"
            } else {
                WebUI.fail("2FA code not entered correctly. Expected: ${verificationCode}, Got: ${entered2FACode}")
            }
            
            // Submit 2FA form
            WebUI.click(findTestObject('Object Repository/Page_Transactflow/button_Remember this device for 30 days_ver_bfc570'), FailureHandling.STOP_ON_FAILURE)
            WebUI.delay(3)
            
            println "✓ 2FA verification form submitted"
        } else {
            println "⚠ No 2FA verification code received from email"
            WebUI.fail("2FA verification code not received")
        }
    } catch (Exception e) {
        println "⚠ 2FA verification failed: ${e.getMessage()}"
        WebUI.fail("2FA verification process failed: ${e.getMessage()}")
    }
} else {
    println "✓ No 2FA field detected, proceeding without 2FA verification"
}

// Test Case 6: Verify successful login and redirection
println "=== Test Case 6: Verify Successful Login ==="

// Wait for page load after login
WebUI.waitForPageLoad(10, FailureHandling.STOP_ON_FAILURE)

// Check if we're redirected to a different page (indicating successful login)
String newPageTitle = WebUI.getWindowTitle()
String newPageUrl = WebUI.getUrl()

println "Page title after login: ${newPageTitle}"
println "Page URL after login: ${newPageUrl}"

// Verify successful login by checking for dashboard/home elements using proper Katalon objects
boolean hasDashboardTitle = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/h1_Dashboard'), 5, FailureHandling.OPTIONAL)
boolean hasHomeTitle = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/h1_Home'), 5, FailureHandling.OPTIONAL)
boolean hasWelcomeText = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/text_Welcome'), 5, FailureHandling.OPTIONAL)

if (newPageTitle != pageTitle && newPageUrl != GlobalVariable.url) {
    println "✓ Login appears successful - page title and URL changed"
    
    // Check for dashboard/home content
    if (hasDashboardTitle || hasHomeTitle || hasWelcomeText) {
        println "✓ Dashboard/home page content detected"
    } else {
        println "⚠ Dashboard/home page content not clearly identified"
    }
    
    // Check for user session elements
    boolean hasLogoutButton = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/button_Logout'), 5, FailureHandling.OPTIONAL)
    boolean hasProfileLink = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/link_Profile'), 5, FailureHandling.OPTIONAL)
    
    if (hasLogoutButton || hasProfileLink) {
        println "✓ User session elements detected"
    } else {
        println "⚠ User session elements not found"
    }
    
    // Verify login state with functional testing
    try {
        // Check for user profile dropdown
        WebUI.waitForElementPresent(findTestObject('Object Repository/Page_Transactflow/userProfileDropdown'), 10, FailureHandling.OPTIONAL)
        
        // Get logged in username
        String loggedInUsername = WebUI.getText(findTestObject('Object Repository/Page_Transactflow/loggedInUsername'), FailureHandling.OPTIONAL)
        String sessionStatus = WebUI.getText(findTestObject('Object Repository/Page_Transactflow/sessionIndicator'), FailureHandling.OPTIONAL)
        
        println "Login state: Username=${loggedInUsername}, Session=${sessionStatus}"
        
        // Verify login state is correct
        if (loggedInUsername && loggedInUsername.trim().length() > 0) {
            println "✓ User is properly logged in: ${loggedInUsername}"
            
            // Verify username matches expected user
            if (loggedInUsername.toLowerCase().contains(GlobalVariable.username.toLowerCase())) {
                println "✓ Logged in username matches expected user"
            } else {
                println "⚠ Logged in username may not match expected user"
            }
        } else {
            println "❌ User login state is not properly set"
        }
        
        // Verify session is active
        if (sessionStatus && (sessionStatus.toLowerCase().contains('active') || sessionStatus.toLowerCase().contains('logged in'))) {
            println "✓ User session is active"
        } else {
            println "⚠ User session status may not be correct"
        }
        
    } catch (Exception e) {
        println "⚠ Could not verify login state: ${e.getMessage()}"
    }
    
} else {
    println "⚠ Login may have failed - still on same page or URL"
    
    // Check for error messages using proper Katalon objects
    boolean hasErrorMessage = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/div_Error message'), 5, FailureHandling.OPTIONAL)
    boolean hasInvalidCredentials = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/div_Invalid credentials'), 5, FailureHandling.OPTIONAL)
    
    if (hasErrorMessage || hasInvalidCredentials) {
        println "⚠ Error message detected - login failed"
        WebUI.fail("Login failed - error message detected")
    } else {
        println "⚠ Login status unclear - no clear success or error indicators"
    }
}

// Test Case 7: Test session management
println "=== Test Case 7: Session Management ==="

// Check if session is maintained by navigating to another page
try {
    WebUI.navigateToUrl(GlobalVariable.url + '/products')
    WebUI.waitForPageLoad(5, FailureHandling.OPTIONAL)
    
    // Check if we can access products page using proper Katalon objects
    boolean hasProductsTitle = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/h1_Products'), 5, FailureHandling.OPTIONAL)
    boolean hasShopContent = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/div_Shop content'), 5, FailureHandling.OPTIONAL)
    boolean redirectedToLogin = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Login  Transactflow/h1_Login'), 5, FailureHandling.OPTIONAL)
    
    // If we can access products page, session is working
    if (hasProductsTitle || hasShopContent) {
        println "✓ Session management working - can access protected pages"
    } else if (redirectedToLogin) {
        println "⚠ Session management failed - redirected to login page"
    } else {
        println "⚠ Session management status unclear"
    }
    
} catch (Exception e) {
    println "⚠ Session management test failed: ${e.getMessage()}"
}

// Test Case 8: Test logout functionality
println "=== Test Case 8: Logout Functionality ==="

// Navigate back to home/dashboard
WebUI.navigateToUrl(GlobalVariable.url + '/home')
WebUI.waitForPageLoad(5, FailureHandling.OPTIONAL)

// Look for logout button/link using proper Katalon objects
boolean hasLogoutButton = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/button_Logout'), 5, FailureHandling.OPTIONAL)
boolean hasLogoutLink = WebUI.verifyElementPresent(findTestObject('Object Repository/Page_Transactflow/link_Logout'), 5, FailureHandling.OPTIONAL)

if (hasLogoutButton || hasLogoutLink) {
    println "✓ Logout functionality is available"
    
    // Note: We don't actually logout here to avoid breaking subsequent tests
    // The logout test case will handle this separately
} else {
    println "⚠ Logout functionality not found"
}

println "=== Login Test Completed Successfully ==="
return true


