import os
import time
from pathlib import Path
from pypom import Page

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

from pages.desktop.developers.manage_versions import ManageVersions


class SubmitAddon(Page):
    """A class holding all the components used for addon submissions in DevHub"""

    _my_addons_page_logo_locator = (By.CSS_SELECTOR, ".site-titles")
    _submission_form_header_locator = (By.CSS_SELECTOR, ".is_addon")
    _addon_distribution_header_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process h3",
    )
    _developer_notification_box_locator = (By.CSS_SELECTOR, ".notification-box")
    _distribution_page_explainer_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process p:nth-of-type(1)",
    )
    _distribution_agreement_checkbox_locator = (By.ID, "id_distribution_agreement")
    _distribution_agreement_link_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process li:nth-of-type(1) a",
    )
    _review_policies_checkbox_locator = (By.ID, "id_review_policy")
    _review_policies_link_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process li:nth-of-type(2) a",
    )
    _user_consent_text_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process p:nth-of-type(2)",
    )
    _recaptcha_locator = (By.ID, "id_recaptcha")
    _recaptcha_checkbox_locator = (By.ID, "recaptcha-anchor")
    _recaptcha_checkbox_is_selected_locator = (
        By.CSS_SELECTOR,
        'span[aria-checked="true"]',
    )
    _accept_agreement_button = (By.ID, "accept-agreement")
    _cancel_agreement_button = (By.CSS_SELECTOR, ".submit-buttons a")
    _dev_accounts_info_link_locator = (By.CSS_SELECTOR, ".addon-submission-process p a")

    _listed_option_locator = (By.CSS_SELECTOR, 'input[value="listed"]')
    _listed_option_helptext_locator = (
        By.CSS_SELECTOR,
        "label[for='id_channel_0'] span[class='helptext']",
    )
    _unlisted_option_locator = (By.CSS_SELECTOR, 'input[value="unlisted"]')
    _unlisted_option_helptext_locator = (
        By.CSS_SELECTOR,
        "label[for='id_channel_1'] span[class='helptext']",
    )
    _distribution_and_signing_helptext_locator = (
        By.CSS_SELECTOR,
        ".addon-submit-distribute p:nth-of-type(3)",
    )
    _addon_policies_helptext_locator = (
        By.CSS_SELECTOR,
        ".addon-submit-distribute p:nth-of-type(4)",
    )
    _change_distribution_link_locator = (By.CSS_SELECTOR, ".addon-submit-distribute a")
    _continue_button_locator = (By.CSS_SELECTOR, ".addon-submission-field button")
    _file_upload_process_helptext_locator = (By.CSS_SELECTOR, ".new-addon-file p")
    _upload_file_button_locator = (By.CSS_SELECTOR, "#upload-addon")
    _accepted_file_types_locator = (By.CLASS_NAME, "upload-details")
    _compatibility_helptext_locator = (By.CSS_SELECTOR, ".compatible-apps label")
    _compatibility_error_message_locator = (By.CSS_SELECTOR, ".errorlist li")
    _firefox_compat_checkbox_locator = (By.CSS_SELECTOR, ".app.firefox input")
    _android_compat_checkbox_locator = (By.CSS_SELECTOR, ".app.android input")
    _android_compat_pop_up = (By.ID, "modal-confirm-android-compatibility")
    _android_compat_yes_button = (By.CSS_SELECTOR, "#modal-confirm-android-compatibility > form > div > button")
    _create_theme_subheader_locator = (
        By.CSS_SELECTOR,
        ".addon-create-theme-section h3",
    )
    _create_theme_button_locator = (By.ID, "wizardlink")
    _submit_file_button_locator = (By.ID, "submit-upload-file-finish")
    _addon_validation_success_locator = (By.CSS_SELECTOR, "#upload-status-bar.bar-success")
    _validation_fail_bar_locator = (By.CLASS_NAME, "bar-fail")
    _validation_support_link_locator = (By.CSS_SELECTOR, "#upload-status-results a")
    _validation_failed_message_locator = (
        By.CSS_SELECTOR,
        "#upload-status-results strong",
    )
    _validation_warning_message_locator = (By.CSS_SELECTOR, ".submission-warning p")
    _validation_summary_link_locator = (By.CSS_SELECTOR, ".submission-warning a")
    _validation_fail_reason_locator = (By.CSS_SELECTOR, "#upload_errors li")
    _validation_status_text_locator = (By.ID, "upload-status-text")
    _validation_success_message_locator = (By.ID, "upload-status-results")
    _failed_validation_message_locator = (By.CSS_SELECTOR, "#upload-status-results > strong:nth-child(2)")


    @property
    def my_addons_page_logo(self):
        self.wait.until(
            EC.visibility_of_element_located(self._my_addons_page_logo_locator)
        )
        return self.find_element(*self._my_addons_page_logo_locator)

    @property
    def submission_form_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._submission_form_header_locator)
        )
        return self.find_element(*self._submission_form_header_locator)

    @property
    def submission_form_subheader(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_distribution_header_locator)
        )
        return self.find_element(*self._addon_distribution_header_locator)

    @property
    def developer_notification_box(self):
        self.wait.until(
            EC.visibility_of_element_located(self._developer_notification_box_locator)
        )
        return self.find_element(*self._developer_notification_box_locator)

    @property
    def distribution_page_explainer(self):
        self.wait.until(
            EC.visibility_of_element_located(self._distribution_page_explainer_locator)
        )
        return self.find_element(*self._distribution_page_explainer_locator).text

    @property
    def distribution_agreement_checkbox(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._distribution_agreement_checkbox_locator
            )
        )
        return self.find_element(*self._distribution_agreement_checkbox_locator)

    @property
    def distribution_agreement_article_link(self):
        self.wait.until(
            EC.visibility_of_element_located(self._distribution_agreement_link_locator)
        )
        return self.find_element(*self._distribution_agreement_link_locator)

    @property
    def review_policies_checkbox(self):
        self.wait.until(
            EC.visibility_of_element_located(self._review_policies_checkbox_locator)
        )
        return self.find_element(*self._review_policies_checkbox_locator)

    @property
    def review_policies_article_link(self):
        self.wait.until(
            EC.visibility_of_element_located(self._review_policies_link_locator)
        )
        return self.find_element(*self._review_policies_link_locator)

    def click_extension_workshop_article_link(self, link, text):
        """Clicks on the Distribution agreement and the Policies links
        which open an Extension Workshop article page in a new tab"""
        link.click()
        self.wait.until(
            EC.number_of_windows_to_be(2),
            message=f"Number of windows was {len(self.driver.window_handles)}, expected 2",
        )
        new_tab = self.driver.window_handles[1]
        self.driver.switch_to.window(new_tab)
        self.wait.until(
            EC.text_to_be_present_in_element((By.CSS_SELECTOR, ".page-hero h1"), text)
        )
        self.driver.close()
        # return to the main tab
        self.driver.switch_to.window(self.driver.window_handles[0])

    @property
    def user_consent_text(self):
        self.wait.until(
            EC.visibility_of_element_located(self._user_consent_text_locator)
        )
        return self.find_element(*self._user_consent_text_locator).text

    @property
    def recaptcha(self):
        self.wait.until(EC.visibility_of_element_located(self._recaptcha_locator))
        return self.find_element(*self._recaptcha_locator)

    def click_recaptcha_checkbox(self):
        """reCAPTCHA is stored in an iframe; switch to the iframe and click on the checkbox"""
        el = self.find_element(By.CSS_SELECTOR, 'iframe[title="reCAPTCHA"]')
        self.driver.switch_to.frame(el)
        self.find_element(*self._recaptcha_checkbox_locator).click()

    @property
    def accept_agreement(self):
        self.wait.until(EC.visibility_of_element_located(self._accept_agreement_button))
        return self.find_element(*self._accept_agreement_button)

    @property
    def cancel_agreement(self):
        self.wait.until(EC.visibility_of_element_located(self._cancel_agreement_button))
        return self.find_element(*self._cancel_agreement_button)

    def click_dev_accounts_info_link(self):
        """click on the Developer account info link and check that the
        correct Extension Workshop article is opened"""
        self.find_element(*self._dev_accounts_info_link_locator).click()
        self.wait.until(
            EC.text_to_be_present_in_element(
                (By.CSS_SELECTOR, ".page-hero h1"), "Developer accounts"
            )
        )

    @property
    def listed_option_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(self._listed_option_helptext_locator)
        )
        return self.find_element(*self._listed_option_helptext_locator).text

    @property
    def unlisted_option_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(self._unlisted_option_helptext_locator)
        )
        return self.find_element(*self._unlisted_option_helptext_locator)

    @property
    def update_url_link(self):
        return self.unlisted_option_helptext.find_element(By.CSS_SELECTOR, "a")

    @property
    def listed_option_radiobutton(self):
        self.wait.until(EC.visibility_of_element_located(self._listed_option_locator))
        return self.find_element(*self._listed_option_locator)

    def select_listed_option(self):
        self.wait.until(EC.element_to_be_clickable(self._listed_option_locator))
        self.find_element(*self._listed_option_locator).click()

    def select_unlisted_option(self):
        self.wait.until(EC.element_to_be_clickable(self._unlisted_option_locator))
        self.find_element(*self._unlisted_option_locator).click()

    @property
    def distribution_and_signing_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._distribution_and_signing_helptext_locator
            )
        )
        return self.find_element(*self._distribution_and_signing_helptext_locator)

    @property
    def distribution_and_signing_link(self):
        return self.distribution_and_signing_helptext.find_element(By.CSS_SELECTOR, "a")

    @property
    def addon_policies_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_policies_helptext_locator)
        )
        return self.find_element(*self._addon_policies_helptext_locator)

    @property
    def addon_policies_link(self):
        return self.addon_policies_helptext.find_element(By.CSS_SELECTOR, "a")

    def change_version_distribution(self):
        """Changes the distribution (listed/unlisted) when submitting a new version"""
        self.find_element(*self._change_distribution_link_locator).click()
        self.wait.until(EC.visibility_of_element_located(self._listed_option_locator))

    def click_continue(self):
        self.find_element(*self._continue_button_locator).click()

    @property
    def file_upload_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(self._file_upload_process_helptext_locator)
        )
        return self.find_elements(*self._file_upload_process_helptext_locator)

    def upload_addon(self, addon):
        """Selects an addon from the 'sample-addons' folder and uploads it"""
        button = self.find_element(*self._upload_file_button_locator)
        archive = Path(f"{os.getcwd()}/sample-addons/{addon}")
        button.send_keys(str(archive))

    @property
    def accepted_file_types(self):
        self.wait.until(
            EC.visibility_of_element_located(self._accepted_file_types_locator)
        )
        return self.find_element(*self._accepted_file_types_locator).text

    @property
    def compatibility_helptext(self):
        self.wait.until(
            EC.visibility_of_element_located(self._compatibility_helptext_locator)
        )
        return self.find_elements(*self._compatibility_helptext_locator)[0].text

    @property
    def compatibility_error_message(self):
        self.wait.until(
            EC.visibility_of_element_located(self._compatibility_error_message_locator)
        )
        return self.find_element(*self._compatibility_error_message_locator).text

    @property
    def firefox_compat_checkbox(self):
        return self.find_element(*self._firefox_compat_checkbox_locator)

    @property
    def android_compat_checkbox(self):
        self.wait.until(
            EC.visibility_of_element_located(self._android_compat_checkbox_locator)
        )
        return self.find_element(*self._android_compat_checkbox_locator)

    @property
    def android_compat_pop_up(self):
        self.wait.until(
            EC.visibility_of_element_located(self._android_compat_pop_up)
        )
        return self.find_element(*self._android_compat_pop_up)

    @property
    def android_compat_yes_button(self):
        self.wait.until(
            EC.visibility_of_element_located(self._android_compat_yes_button)
        )
        return self.find_element(*self._android_compat_yes_button)

    @property
    def create_theme_subheader(self):
        self.wait.until(
            EC.visibility_of_element_located(self._create_theme_subheader_locator)
        )
        return self.find_element(*self._create_theme_subheader_locator).text

    def click_create_theme_button(self):
        self.find_element(*self._create_theme_button_locator).click()
        return ThemeWizard(self.driver, self.base_url).wait_for_page_to_load()

    def is_validation_successful(self):
        """Wait for addon validation to complete; if not successful, the test will fail"""
        self.wait.until(
            EC.visibility_of_element_located(self._addon_validation_success_locator)
        )

    @property
    def failed_validation_bar(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_fail_bar_locator)
        )
        return self.find_element(*self._validation_fail_bar_locator)

    @property
    def validation_status_title(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_status_text_locator)
        )
        return self.find_element(*self._validation_status_text_locator).text

    def click_validation_support_link(self):
        self.find_element(*self._validation_support_link_locator).click()
        self.wait.until(
            EC.number_of_windows_to_be(2),
            message=f"Number of windows was {len(self.driver.window_handles)}, expected 2",
        )
        new_tab = self.driver.window_handles[1]
        self.driver.switch_to.window(new_tab)
        self.wait.until(EC.url_contains("/mozilla/addons-linter/"))
        self.driver.close()
        # return to the main tab
        self.driver.switch_to.window(self.driver.window_handles[0])

    def is_validation_failed(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_fail_bar_locator)
        )

    @property
    def validation_failed_message(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_failed_message_locator)
        )
        return self.find_element(*self._validation_failed_message_locator).text

    @property
    def validation_failed_reason(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_fail_reason_locator)
        )
        return self.find_elements(*self._validation_fail_reason_locator)

    @property
    def validation_warning_message(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_warning_message_locator)
        )
        return self.find_element(*self._validation_warning_message_locator).text

    def click_validation_summary(self):
        self.find_element(*self._validation_summary_link_locator).click()
        self.wait.until(
            EC.number_of_windows_to_be(2),
            message=f"Number of windows was {len(self.driver.window_handles)}, expected 2",
        )
        new_tab = self.driver.window_handles[1]
        self.driver.switch_to.window(new_tab)
        self.wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "results")))
        return ValidationResults(self.driver, self.base_url)

    @property
    def success_validation_message(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_success_message_locator)
        )
        return self.find_element(*self._validation_success_message_locator)

    def click_continue_upload_button(self):
        self.find_element(*self._submit_file_button_locator).click()
        return UploadSource(self.driver, self.base_url)

    def submit_button_disabled(self):
        self.find_element(*self._submit_file_button_locator).get_attribute("disabled")

    @property
    def failed_validation_message(self):
        return self.find_element(*self._failed_validation_message_locator)


class ValidationResults(Page):
    _validation_results_header_locator = (
        By.CSS_SELECTOR,
        "div[class='section'] header h2",
    )
    _validation_summary_shelf_locator = (By.CLASS_NAME, "tiers")
    _validation_general_results_locator = (By.ID, "suite-results-tier-1")
    _validation_security_results_locator = (By.ID, "suite-results-tier-2")
    _validation_extension_results_locator = (By.ID, "suite-results-tier-3")
    _validation_localization_results_locator = (By.ID, "suite-results-tier-4")
    _validation_compatibility_results_locator = (By.ID, "suite-results-tier-5")

    @property
    def validation_results_header(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_results_header_locator)
        )
        return self.find_element(*self._validation_results_header_locator).text

    @property
    def validation_summary_shelf(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_results_header_locator)
        )
        return self.find_element(*self._validation_summary_shelf_locator)

    @property
    def validation_general_results(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_general_results_locator)
        )
        return self.find_element(*self._validation_general_results_locator)

    @property
    def validation_security_results(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_security_results_locator)
        )
        return self.find_element(*self._validation_security_results_locator)

    @property
    def validation_extension_results(self):
        self.wait.until(
            EC.visibility_of_element_located(self._validation_extension_results_locator)
        )
        return self.find_element(*self._validation_extension_results_locator)

    @property
    def validation_localization_results(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._validation_localization_results_locator
            )
        )
        return self.find_element(*self._validation_localization_results_locator)

    @property
    def validation_compatibility_results(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._validation_compatibility_results_locator
            )
        )
        return self.find_element(*self._validation_compatibility_results_locator)


class UploadSource(Page):
    _submit_source_code_page_header_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process h3",
    )
    _yes_submit_source_radio_button_locator = (By.ID, "id_has_source_0")
    _no_submit_source_radio_button_locator = (By.ID, "id_has_source_1")
    _choose_source_file_button_locator = (By.ID, "id_source")
    _continue_button_locator = (
        By.CSS_SELECTOR,
        ".submission-buttons button:nth-child(1)",
    )
    _upload_source_error_message_locator = (By.CSS_SELECTOR, ".errorlist li")
    _cancel_and_disable_version_locator = (
        By.CSS_SELECTOR,
        ".confirm-submission-cancel",
    )
    _cancel_and_disable_explainer_text_locator = (
        By.CSS_SELECTOR,
        "#modal-confirm-submission-cancel p",
    )
    _cancel_version_confirm_button_locator = (
        By.CSS_SELECTOR,
        ".modal-confirm-submission-cancel .delete-button",
    )
    _yes_cancel_and_disable_version = (By.CSS_SELECTOR, "button.delete-button:nth-child(1)")
    _do_not_cancel_version_link_locator = (By.CSS_SELECTOR, "#modal-confirm-submission-cancel > form > div > a")
    _release_notes_field_locator = (By.ID, "trans-release_notes")
    _notes_to_reviewer_locator = (By.ID, "id_approval_notes")
    _version_submitted_text_locator = (By.CLASS_NAME, ".addon-submission-process h3")

    @property
    def submit_source_page_header(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._submit_source_code_page_header_locator
            )
        )
        return self.find_element(*self._submit_source_code_page_header_locator).text

    def select_yes_to_submit_source(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._yes_submit_source_radio_button_locator
            )
        )
        self.find_element(*self._yes_submit_source_radio_button_locator).click()

    def select_no_to_omit_source(self):
        self.find_element(*self._no_submit_source_radio_button_locator).click()

    def choose_source(self, file):
        button = self.find_element(*self._choose_source_file_button_locator)
        archive = Path(f"{os.getcwd()}/sample-addons/{file}")
        button.send_keys(str(archive))

    def continue_unlisted_submission(self):
        self.find_element(*self._continue_button_locator).click()
        return SubmissionConfirmationPage(
            self.driver, self.base_url
        ).wait_for_page_to_load()

    def continue_listed_submission(self):
        self.find_element(*self._continue_button_locator).click()
        return ListedAddonSubmissionForm(
            self.driver, self.base_url
        ).wait_for_page_to_load()

    @property
    def source_upload_fail_message(self):
        self.wait.until(
            EC.visibility_of_element_located(self._upload_source_error_message_locator)
        )
        return self.find_element(*self._upload_source_error_message_locator).text

    def click_cancel_and_disable_version(self):
        self.find_element(*self._cancel_and_disable_version_locator).click()

    @property
    def cancel_and_disable_explainer_text(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._cancel_and_disable_explainer_text_locator
            )
        )
        return self.find_element(*self._cancel_and_disable_explainer_text_locator).text

    def click_do_not_cancel_version(self):
        return self.find_element(*self._do_not_cancel_version_link_locator).click()

    def confirm_cancel_and_disable_version(self):
        self.find_element(*self._yes_cancel_and_disable_version).click()
        return ManageVersions(self.driver, self.base_url).wait_for_page_to_load()

    def release_notes_field(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._release_notes_field_locator
            )
        )
        return self.find_element(*self._release_notes_field_locator)

    def notes_to_reviewers_field(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._notes_to_reviewer_locator
            )
        )
        return self.find_element(*self._notes_to_reviewer_locator)

    def version_submitted_text(self):
        self.wait.until(
            EC.visibility_of_element_located(
                self._version_submitted_text_locator
            )
        )
        return self.find_element(*self._version_submitted_text_locator).text

class ListedAddonSubmissionForm(Page):
    _addon_name_field_locator = (By.CSS_SELECTOR, "#trans-name input:nth-child(1)")
    _edit_addon_slug_link_locator = (By.ID, "edit_slug")
    _edit_addon_slug_field_locator = (By.ID, "id_slug")
    _addon_summary_field_locator = (By.ID, "id_summary_0")
    _addon_detail_fields_info_text_locator = (By.CSS_SELECTOR, ".edit-addon-details")
    _summary_character_count_locator = (
        By.CSS_SELECTOR,
        ".char-count[data-for-startswith='id_summary_'] > b",
    )
    _addon_description_field_locator = (By.ID, "id_description_0")
    _is_experimental_checkbox_locator = (By.ID, "id_is_experimental")
    _requires_payment_checkbox_locator = (By.ID, "id_requires_payment")
    _categories_section_locator = (By.ID, "addon-categories-edit")
    _categories_locator = (
        By.CSS_SELECTOR,
        ".addon-app-cats:nth-of-type(1) > ul input",
    )
    # _android_categories_locator = (
    #     By.CSS_SELECTOR,
    #     ".addon-app-cats:nth-of-type(2) > ul input",
    # )
    _email_input_field_locator = (By.ID, "id_support_email_0")
    _support_site_input_field_locator = (By.ID, "id_support_url_0")
    _license_options_locator = (By.CLASS_NAME, "license")
    _license_details_link_locator = (By.CSS_SELECTOR, ".xx.extra")
    _custom_license_name_locator = (By.ID, "id_license-name")
    _custom_license_text_locator = (By.ID, "id_license-text")
    _privacy_policy_checkbox_locator = (By.ID, "id_has_priv")
    _privacy_policy_textarea_locator = (By.ID, "id_privacy_policy_0")
    _reviewer_notes_textarea_locator = (By.ID, "id_approval_notes")
    _submit_addon_button_locator = (
        By.CSS_SELECTOR,
        ".submission-buttons button:nth-child(1)",
    )
    _cancel_addon_submission_button_locator = (
        By.CSS_SELECTOR,
        ".submission-buttons button:nth-child(2)",
    )
    # _theme_categories_locator = (By.CSS_SELECTOR, '#addon-categories-edit > ul input') - temporary not available
    _theme_categories_locator = (By.CSS_SELECTOR, ".addon-app-cats")
    _theme_category_abstract_locator = (By.CSS_SELECTOR, "#id_categories > div:nth-child(1) > label")
    _theme_licence_sharing_rights_locator = (
        By.CSS_SELECTOR,
        "#cc-chooser ul:nth-of-type(1) input",
    )
    _theme_license_commercial_use_locator = (
        By.CSS_SELECTOR,
        "#cc-chooser ul:nth-of-type(2) input",
    )
    _theme_license_creation_rights_locator = (
        By.CSS_SELECTOR,
        "#cc-chooser ul:nth-of-type(3) input",
    )
    _selected_theme_license_locator = (By.CSS_SELECTOR, "#cc-license")
    _open_theme_licenses_list_locator = (By.CLASS_NAME, "select-license")
    _theme_licenses_list_locator = (By.CSS_SELECTOR, "#id_license-builtin input")

    def wait_for_page_to_load(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_summary_field_locator)
        )
        return self

    def set_addon_name(self, value):
        self.find_element(*self._addon_name_field_locator).send_keys(value)

    def clear_addon_name(self):
        self.find_element(*self._addon_name_field_locator).clear()

    @property
    def theme_category_abstract(self):
        return self.find_element(*self._theme_category_abstract_locator)

    @property
    def addon_name_field(self):
        self.wait.until(
            EC.visibility_of_element_located(self._addon_name_field_locator)
        )
        return self.find_element(*self._addon_name_field_locator)

    def edit_addon_slug(self, value):
        self.find_element(*self._edit_addon_slug_link_locator).click()
        edit_field = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located(self._edit_addon_slug_field_locator)
        )
        edit_field.send_keys(value)

    def set_addon_summary(self, value):
        self.find_element(*self._addon_summary_field_locator).send_keys(value)

    def addon_detail_fields_info_text(self):
        self.find_elements(*self._addon_detail_fields_info_text_locator)

    @property
    def summary_character_count(self):
        self.wait.until(
            EC.visibility_of_element_located(self._summary_character_count_locator)
        )
        return self.find_element(*self._summary_character_count_locator).text

    def set_addon_description(self, value):
        self.find_element(*self._addon_description_field_locator).send_keys(value)

    @property
    def is_experimental(self):
        self.wait.until(
            EC.visibility_of_element_located(self._is_experimental_checkbox_locator)
        )
        return self.find_element(*self._is_experimental_checkbox_locator)

    @property
    def requires_payment(self):
        self.wait.until(
            EC.visibility_of_element_located(self._requires_payment_checkbox_locator)
        )
        return self.find_element(*self._requires_payment_checkbox_locator)

    @property
    def categories_section(self):
        self.wait.until(
            EC.visibility_of_element_located(self._categories_section_locator)
        )
        return self.find_element(*self._categories_section_locator)

    def select_categories(self, count):
        self.find_elements(*self._categories_locator)[count].click()

    # def select_android_categories(self, count):
    #     self.find_elements(*self._android_categories_locator)[count].click()

    def select_theme_categories(self, count):
        self.find_elements(*self._theme_categories_locator)[count].click()

    def email_input_field(self, value):
        self.find_element(*self._email_input_field_locator).send_keys(value)

    def support_site_input_field(self, value):
        self.find_element(*self._support_site_input_field_locator).send_keys(value)

    @property
    def select_license_options(self):
        self.wait.until(EC.visibility_of_element_located(self._license_options_locator))
        return self.find_elements(*self._license_options_locator)

    def license_option_names(self, count, value):
        return self.select_license_options[count].get_attribute(value)

    def license_details_link(self):
        self.wait.until(
            EC.visibility_of_element_located(self._license_details_link_locator)
        )
        self.find_element(*self._license_details_link_locator).click()

    def set_custom_license_name(self, value):
        self.wait.until(
            EC.visibility_of_element_located(self._custom_license_name_locator)
        )
        self.find_element(*self._custom_license_name_locator).send_keys(value)

    def set_custom_license_text(self, value):
        self.wait.until(
            EC.visibility_of_element_located(self._custom_license_text_locator)
        )
        self.find_element(*self._custom_license_text_locator).send_keys(value)

    def select_theme_licence_sharing_rights(self, count):
        self.wait.until(
            EC.visibility_of_element_located(self._theme_licence_sharing_rights_locator)
        )
        self.find_elements(*self._theme_licence_sharing_rights_locator)[count].click()

    def select_theme_license_commercial_use(self, count):
        self.wait.until(
            EC.visibility_of_element_located(self._theme_license_commercial_use_locator)
        )
        self.find_elements(*self._theme_license_commercial_use_locator)[count].click()

    def select_theme_license_creation_rights(self, count):
        self.find_elements(*self._theme_license_creation_rights_locator)[count].click()

    @property
    def generated_theme_license(self):
        self.wait.until(
            EC.visibility_of_element_located(self._selected_theme_license_locator)
        )
        return self.find_element(*self._selected_theme_license_locator)

    def open_theme_licenses_list(self):
        self.wait.until(
            EC.visibility_of_element_located(self._open_theme_licenses_list_locator)
        )
        self.find_element(*self._open_theme_licenses_list_locator).click()

    def select_theme_license_from_list(self):
        self.wait.until(
            EC.visibility_of_element_located(self._theme_licenses_list_locator)
        )
        self.find_elements(*self._theme_licenses_list_locator)

    def set_privacy_policy(self, value):
        self.wait.until(
            EC.element_to_be_clickable(self._privacy_policy_checkbox_locator)
        )
        self.find_element(*self._privacy_policy_checkbox_locator).click()
        self.find_element(*self._privacy_policy_textarea_locator).send_keys(value)

    def set_reviewer_notes(self, value):
        self.find_element(*self._reviewer_notes_textarea_locator).send_keys(value)

    def submit_addon(self):
        self.find_element(*self._submit_addon_button_locator).click()
        return SubmissionConfirmationPage(
            self.driver, self.base_url
        ).wait_for_page_to_load()

    def cancel_submission(self):
        self.find_element(*self._cancel_addon_submission_button_locator).click()
        from pages.desktop.developers.edit_addon import EditAddon

        return EditAddon(self.driver, self.base_url).wait_for_page_to_load()


class ThemeWizard(Page):
    _wizard_header_locator = (By.CSS_SELECTOR, ".addon-submission-process > h3")
    _theme_name_input_field = (By.ID, "theme-name")
    _upload_theme_image_button_locator = (By.ID, "header-img")
    _uploaded_image_preview_locator = (By.CLASS_NAME, "preview.loaded")
    _change_image_button_locator = (By.CLASS_NAME, "reset")
    _browser_preview_locator = (By.ID, "preview-svg-root")
    _browser_preview_header_image_locator = (By.ID, "svg-header-img")
    _submit_theme_button_locator = (By.CLASS_NAME, "button.upload")
    _cancel_submission_button_locator = (
        By.CSS_SELECTOR,
        ".submission-buttons .delete-button",
    )

    def wait_for_page_to_load(self):
        self.wait.until(EC.visibility_of_element_located((By.ID, "theme-header")))
        return self

    @property
    def wizard_header(self):
        self.wait.until(EC.visibility_of_element_located(self._wizard_header_locator))
        return self.find_element(*self._wizard_header_locator).text

    def set_theme_name(self, value):
        self.find_element(*self._theme_name_input_field).send_keys(value)

    def upload_theme_header(self, img):
        button = self.find_element(*self._upload_theme_image_button_locator)
        header_img = Path(f"{os.getcwd()}/img/{img}")
        button.send_keys(str(header_img))

    @property
    def uploaded_image_preview(self):
        self.wait.until(
            EC.visibility_of_element_located(self._uploaded_image_preview_locator)
        )
        return self.find_element(*self._uploaded_image_preview_locator)

    @property
    def uploaded_image_source(self):
        """Fetch the source of the uploaded theme image"""
        return self.uploaded_image_preview.get_attribute("src")

    @property
    def browser_preview(self):
        self.wait.until(EC.visibility_of_element_located(self._browser_preview_locator))
        return self.find_element(*self._browser_preview_locator)

    @property
    def browser_preview_image(self):
        """Fetch the source of tha generated theme preview image"""
        return self.find_element(
            *self._browser_preview_header_image_locator
        ).get_attribute("href")

    def submit_theme(self):
        self.find_element(*self._submit_theme_button_locator).click()
        time.sleep(5)
        return ListedAddonSubmissionForm(
            self.driver, self.base_url
        ).wait_for_page_to_load()

    def cancel_submission(self):
        self.find_element(*self._cancel_submission_button_locator).click()
        return SubmitAddon(self.driver, self.base_url).wait_for_page_to_load()


class SubmissionConfirmationPage(Page):
    _confirmation_page_header_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process h3",
    )
    _confirmation_messages_locator = (By.CSS_SELECTOR, ".addon-submission-process p")
    _manage_listing_button_locator = (By.LINK_TEXT, "Go to My Submissions")
    _edit_version_button_locator = (
        By.CSS_SELECTOR,
        ".addon-submission-process p:nth-child(6) > a",
    )
    _edit_listing_button_locator = (By.LINK_TEXT, "Manage Listing")
    _theme_preview_locator = (By.CSS_SELECTOR, ".addon-submission-process img")

    def wait_for_page_to_load(self):
        self.wait.until(
            EC.visibility_of_element_located(self._confirmation_page_header_locator)
        )
        return self

    @property
    def submission_confirmation_messages(self):
        self.wait.until(
            EC.visibility_of_element_located(self._confirmation_messages_locator)
        )
        return self.find_elements(*self._confirmation_messages_locator)

    def click_manage_listing_button(self):
        self.wait.until(EC.element_to_be_clickable(self._manage_listing_button_locator))
        self.find_element(*self._manage_listing_button_locator).click()
        from pages.desktop.developers.addons_manage import ManageAddons

        return ManageAddons(self.driver, self.base_url).wait_for_page_to_load()

    def click_edit_version_button(self):
        self.wait.until(EC.element_to_be_clickable(self._edit_version_button_locator))
        self.find_element(*self._edit_version_button_locator).click()
        return ManageVersions(self.driver, self.base_url)

    def click_edit_listing_button(self):
        self.wait.until(EC.element_to_be_clickable(self._edit_listing_button_locator))
        self.find_element(*self._edit_listing_button_locator).click()
        from pages.desktop.developers.edit_addon import EditAddon

        return EditAddon(self.driver, self.base_url).wait_for_page_to_load()

    @property
    def generated_theme_preview(self):
        return self.find_element(*self._theme_preview_locator)
