from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

from .base import wait


class PostPage:
    def __init__(self, test):
        self.test = test

    def get_table_rows(self):
        # Post-May08b: #id_post_table is now a <ul> of <li class="post-line">
        # rows (no <ol> numbering). The CSS selector still works since the
        # id is preserved.
        return self.test.browser.find_elements(By.CSS_SELECTOR, "#id_post_table .post-line")

    @wait
    def wait_for_row_in_post_table(self, line_text, line_number=None):
        # `line_number` retained for backwards compat with callers that
        # passed a position counter — ignored now (lines order by created_at,
        # numbering is gone). Match by text containment instead.
        rows = self.get_table_rows()
        row_texts = [row.text for row in rows]
        self.test.assertTrue(
            any(line_text in t for t in row_texts),
            f"Line text {line_text!r} not in any row: {row_texts!r}",
        )

    def get_line_input_box(self):
        # /billboard/ new-post applet uses #id_text (creates a fresh Post);
        # post.html aperture uses #id_post_line_text (appends to existing).
        # `add_post_line` is called from both contexts, so probe in order.
        boxes = self.test.browser.find_elements(By.ID, "id_post_line_text")
        if boxes:
            return boxes[0]
        return self.test.browser.find_element(By.ID, "id_text")

    def add_post_line(self, line_text):
        new_line_no = len(self.get_table_rows()) + 1
        self.get_line_input_box().send_keys(line_text)
        self.get_line_input_box().send_keys(Keys.ENTER)
        self.wait_for_row_in_post_table(line_text, new_line_no)
        return self

    def get_share_box(self):
        return self.test.browser.find_element(
            By.CSS_SELECTOR,
            'input[name="recipient"]',
        )

    def get_shared_with_list(self):
        return self.test.browser.find_elements(
            By.CSS_SELECTOR,
            ".post-recipient"
        )

    def share_post_with(self, email):
        # Bud-btn flow (post-Brief sprint): click bottom-left handshake,
        # type the email in the slide-out, click the .btn-confirm OK, wait
        # for the recipient chip.
        bud_btn = self.test.browser.find_element(By.ID, "id_bud_btn")
        bud_btn.click()
        recipient = self.test.wait_for(
            lambda: self.test.browser.find_element(By.ID, "id_recipient")
        )
        recipient.send_keys(email)
        ok = self.test.browser.find_element(
            By.CSS_SELECTOR, "#id_bud_panel .btn.btn-confirm"
        )
        ok.click()
        self.test.wait_for(
            lambda: self.test.assertIn(
                email, [item.text for item in self.get_shared_with_list()]
            )
        )

    def get_post_owner(self):
        # `<span id="id_post_owner" hidden>` — Selenium .text returns "" for
        # hidden elements, so read textContent attribute instead.
        return self.test.browser.find_element(
            By.ID, "id_post_owner"
        ).get_attribute("textContent")
