import sys, os

base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.insert(0, base_path)

import pytest
from playwright.sync_api import sync_playwright, Page
from utils.trace_cleaner import trace_cleaner

static_email = "testuserexpensify1+82@gmail.com"


@pytest.fixture
def setup_playwright():
    playwright = sync_playwright().start()

    browser = playwright.chromium.launch(
        headless=True, slow_mo=1000, args=["--disable-web-security", "--disable-features=IsolateOrigins,site-per-process"]
    )
    page = browser.new_page()
    # Yield page, browser, and playwright so that the test can manage tracing and cleanup
    yield page, browser, playwright
    # No cleanup here: test function is responsible for stopping tracing, exporting, cleaning trace, and closing browser/playwright


def login_user(page: Page, email: str, first_name: str, last_name: str):
    page.goto("https://dev.new.expensify.com:8082/")
    page.locator('input[type="email"]').fill(email)
    page.locator('button[tabindex="0"]').click()

    join_button = page.get_by_role("button", name="Join")
    join_button.click()
    page.locator("text='Track and budget expenses'").click()
    page.get_by_role("button", name="Continue").click()

    page.locator('input[name="fname"]').fill(first_name)
    page.locator('input[name="lname"]').fill(last_name)
    page.get_by_role("button", name="Continue").last.click()


def create_workspace_and_add_member(page: Page, member_email: str):
    page.locator('button[aria-label="Workspaces"]').click()
    page.get_by_test_id("WorkspaceSwitcherPage").get_by_role(
        "button", name="New workspace"
    ).click()
    page.locator('div[aria-label="Members"]').click()
    page.locator("button", has_text="Invite member").click()
    page.locator('input[aria-label="Name, email, or phone number"]').fill(member_email)
    page.locator("button", has_text=member_email).click()
    page.locator('button[data-listener="Enter"]', has_text="Next").click()
    page.locator('button[data-listener="Enter"]', has_text="Invite").click()
    page.locator('button[aria-label="Back"]').click()
    page.locator('button[aria-label="Back"]').click()


def browse_to_workspace(page: Page, workspace_name: str):
    page.locator('button[aria-label="Workspaces"]').click()
    try:
        page.locator(f'button[aria-label="{workspace_name}"]').click()
    except Exception:
        page.locator(f'button[aria-label="{workspace_name}"]').nth(1).click()
    page.locator(
        'button[aria-label="Navigates to a chat"]', has_text=workspace_name
    ).nth(0).click()


def submit_expense(page: Page, amount: int, merchant: str):
    page.locator('button[aria-label="Create"]').nth(2).click()
    page.locator('div[aria-label="Submit expense"]').click()
    page.locator('button[aria-label="Manual"]').click()
    page.locator('input[placeholder="0"]').fill(str(amount))
    page.locator('button[data-listener="Enter"]', has_text="Next").nth(0).click()
    page.locator('div[role="menuitem"]', has_text="Merchant").click()
    page.locator('input[aria-label="Merchant"]').fill(merchant)
    page.locator('button[data-listener="Enter"]', has_text="Save").click()
    page.locator('button[data-listener="Enter"]', has_text="Submit").click()


def wait_for_text_with_assertion(
    page: Page,
    locator,
    text: str,
    max_retries=10,
    interval=1,
    assertion_message="Text not found",
):
    for attempt in range(max_retries):
        try:
            if text in locator.inner_text():
                print(f"'{text}' found in the inner text.")
                return
        except Exception as e:
            print(f"Attempt {attempt + 1} failed with exception: {e}")
        page.wait_for_timeout(1000)
    raise AssertionError(assertion_message)


@pytest.mark.usefixtures("setup_playwright")
def test_duplicate_and_hold_expense(setup_playwright):
    page, browser, playwright = setup_playwright
    # Start tracing with desired options
    page.context.tracing.start(screenshots=True, snapshots=True, sources=True)
    try:
        user1_email = static_email
        user2_email = "testuser@gmail.com"
        first_name1, last_name1 = "Chris", "Brown"
        workspace_name = f"{first_name1} {last_name1}'s Workspace"

        login_user(page, user1_email, first_name1, last_name1)
        create_workspace_and_add_member(page, user2_email)
        browse_to_workspace(page, workspace_name)

        submit_expense(page, 100, "Merchant 1")
        submit_expense(page, 200, "Merchant 2")
        submit_expense(page, 100, "Merchant 1")

        page.locator(
            'button[aria-label="View details"]', has_text=f"{workspace_name} owes:"
        ).last.click()

        first_message = page.locator('div[aria-label="Cash"][data-tag="pressable"]').first

        wait_for_text_with_assertion(
            page,
            first_message,
            "Duplicate",
            max_retries=10,
            interval=1,
            assertion_message="Expected 'Duplicate' text not found in the first message.",
        )

        first_message.hover()
        page.locator('button[aria-label="Menu"]').click()
        page.locator('div[aria-label="Hold"]').click()
        page.locator('input[aria-label="Reason"]').fill("Random reason")
        page.locator('button[data-listener="Enter"]', has_text="Hold expense").click()

        wait_for_text_with_assertion(
            page,
            first_message,
            "Hold",
            max_retries=5,
            interval=1,
            assertion_message="Expense's text not updated to 'Hold' from 'Duplicate'.",
        )
    finally:
        trace_file = "/app/expensify/user_tool/output_browser1.zip"
        page.context.tracing.stop(path=trace_file)
        trace_cleaner(trace_file)
        browser.close()
        playwright.stop()