from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class LoginPage:
    #URL = "https://hypermedialearning.sanggadewa.my.id/login"
    URL = "https://hypermedialearning.project2025.id/public/login"
    DASHBOARD_URL_PART = "/dashboard"

    # ===============================
    # LOCATORS
    # ===============================
    EMAIL = (By.ID, "email")
    PASSWORD = (By.ID, "password")
    REMEMBER_ME = (By.NAME, "remember")
    BUTTON_LOGIN = (By.XPATH, "//button[@type='submit']")

    ERROR_MESSAGE = (By.CLASS_NAME, "invalid-feedback")
    GLOBAL_ERROR = (
        By.XPATH,
        "//*[contains(text(),'These credentials do not match our records')]"
    )

    SSO_GOOGLE_BUTTON = (By.XPATH, "//a[contains(@href,'/auth/google')]")

    # ===============================
    # INIT
    # ===============================
    def __init__(self, driver):
        self.driver = driver
        self.wait = WebDriverWait(driver, 10)

    # ===============================
    # PAGE ACTIONS
    # ===============================
    def open(self):
        self.driver.get(self.URL)

    def fill_email(self, value: str):
        field = self.wait.until(
            EC.visibility_of_element_located(self.EMAIL)
        )
        field.clear()
        field.send_keys(value)

    def fill_password(self, value: str):
        field = self.wait.until(
            EC.visibility_of_element_located(self.PASSWORD)
        )
        field.clear()
        field.send_keys(value)

    def click_login(self):
        self.wait.until(
            EC.element_to_be_clickable(self.BUTTON_LOGIN)
        ).click()

    def click_remember_me(self):
        checkbox = self.wait.until(
            EC.element_to_be_clickable(self.REMEMBER_ME)
        )
        if not checkbox.is_selected():
            checkbox.click()

    def click_google_sso(self):
        self.wait.until(
            EC.element_to_be_clickable(self.GOOGLE_SSO_BUTTON)
        ).click()

    # ===============================
    # BUSINESS / HELPER METHODS
    # ===============================
    def login(self, email: str, password: str):
        self.fill_email(email)
        self.fill_password(password)
        self.click_login()

    def is_login_success(self) -> bool:
        try:
            self.wait.until(
                lambda d: self.DASHBOARD_URL_PART in d.current_url
            )
            return True
        except:
            return False

    def is_login_failed(self) -> bool:
        return self.has_error_message()

    def has_error_message(self) -> bool:
        return any(
            el.text.strip()
            for el in self.driver.find_elements(*self.ERROR_MESSAGE)
        )

    def has_global_error(self) -> bool:
        try:
            return self.driver.find_element(
                *self.GLOBAL_ERROR
            ).is_displayed()
        except:
            return False

    def is_field_required(self, field_name: str) -> bool:
        fields = {
            "email": self.EMAIL,
            "password": self.PASSWORD
        }

        locator = fields.get(field_name)
        if not locator:
            raise ValueError(f"Field '{field_name}' tidak dikenali")

        element = self.driver.find_element(*locator)
        return element.get_attribute("required") is not None

    def get_email_validation_message(self):
        email = self.driver.find_element(By.ID, "email")
        return self.driver.execute_script(
            "return arguments[0].validationMessage;",
            email
        )

    def submit(self):
        self.click_login()

    def has_html5_validation(self, field_name: str) -> bool:
        field = self.get_field(field_name)
        return field.get_attribute("validationMessage") != ""
    
    def get_field(self, field_name: str):
        fields = {
            "email": self.EMAIL,
            "password": self.PASSWORD,
        }

        locator = fields.get(field_name)
        if not locator:
            raise ValueError(f"Field '{field_name}' tidak dikenali di LoginPage")

        return self.driver.find_element(*locator)
    
    def click_remember_me(self):
        checkbox = self.wait.until(
            EC.element_to_be_clickable(self.REMEMBER_ME)
        )
        if not checkbox.is_selected():
            checkbox.click()

    def is_remember_me_checked(self) -> bool:
        checkbox = self.driver.find_element(*self.REMEMBER_ME)
        return checkbox.is_selected()

    def click_sso_google(self):
        self.wait.until(
            EC.element_to_be_clickable(self.SSO_GOOGLE_BUTTON)
        ).click()

    def is_redirected_to_google(self) -> bool:
        self.wait.until(
            lambda d: "accounts.google.com" in d.current_url
        )
        return "accounts.google.com" in self.driver.current_url





