"""Automated Browser Verification for High-Density Enterprise Document Management Dashboard."""

import asyncio
import os
import shutil
import sys
from pathlib import Path
from playwright.async_api import async_playwright

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8")

SCREENSHOTS_DIR = Path("reports/screenshots")
SCREENSHOTS_DIR.mkdir(parents=True, exist_ok=True)

ARTIFACTS_DIR = Path(r"C:\Users\Admin\.gemini\antigravity\brain\17196ee7-e016-4798-b9ac-14599c8c9f66")
ARTIFACTS_DIR.mkdir(parents=True, exist_ok=True)

BASE_URL = "http://127.0.0.1:8000"


async def run_document_dashboard_verification():
    print("================================================================")
    print("  DSCons ERP - High-Density Document Dashboard Browser Test")
    print("================================================================")

    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(
            viewport={"width": 1440, "height": 900},
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 DSConsE2E",
        )
        page = await context.new_page()

        # Step 1: Login
        print("\n[Step 1] Logging in via /login...")
        await page.goto(f"{BASE_URL}/login", wait_until="networkidle")
        await page.fill("#auth-email", "admin@dscons.vn")
        await page.fill("#auth-password", "DSCons@2026#SecureAdmin")
        await page.click("#submit-btn")
        try:
            await page.wait_for_url("**/dashboard**", timeout=8000)
        except Exception:
            await page.wait_for_timeout(2000)
        print("  -> Authenticated successfully.")

        # Step 2: Navigate to Document Management Dashboard
        print("\n[Step 2] Navigating to /v1/erp/dashboard/documents...")
        await page.goto(f"{BASE_URL}/v1/erp/dashboard/documents", wait_until="networkidle")
        await page.wait_for_timeout(2000)

        # Verify page title
        title = await page.title()
        print(f"  -> Page Title: {title}")
        assert "Quản Lý Văn Bản" in title, f"Unexpected page title: {title}"

        # Step 3: Verify Command Bar & KPIs
        print("\n[Step 3] Checking Toolbar & Command Bar components...")
        omni_search = await page.query_selector("#omni-search")
        assert omni_search is not None, "Omni-search bar #omni-search not found!"
        print("  [OK] Omni-search bar (#omni-search) rendered.")

        chips = await page.query_selector_all(".status-chip")
        print(f"  -> Found {len(chips)} quick status filter chips.")
        assert len(chips) >= 5, f"Expected at least 5 status filter chips, got {len(chips)}!"

        # Step 4: Verify Tree & Facet Explorer (Left Pane)
        print("\n[Step 4] Checking Tree & Facet Explorer (Left Pane)...")
        tree = await page.query_selector("#doc-tree-explorer")
        assert tree is not None, "#doc-tree-explorer not found!"
        
        tree_items = await page.query_selector_all(".tree-nav-item")
        print(f"  -> Found {len(tree_items)} tree navigation items.")
        assert len(tree_items) >= 5, "Expected tree items to be populated!"

        # Step 5: Test Tree Collapse & Expand
        print("\n[Step 5] Testing Sidebar Tree collapse/expand toggle...")
        toggle_tree_btn = await page.query_selector("#btn-toggle-tree")
        assert toggle_tree_btn is not None, "Toggle tree button #btn-toggle-tree not found!"
        await toggle_tree_btn.click()
        await page.wait_for_timeout(300)
        is_collapsed = await page.evaluate("document.getElementById('doc-tree-explorer').classList.contains('collapsed')")
        print(f"  -> Clicked toggle: tree collapsed = {is_collapsed}")
        assert is_collapsed, "Tree explorer should have collapsed class!"
        
        # Click toggle again to restore
        await toggle_tree_btn.click()
        await page.wait_for_timeout(300)
        is_collapsed_after = await page.evaluate("document.getElementById('doc-tree-explorer').classList.contains('collapsed')")
        print(f"  -> Clicked toggle again: tree collapsed = {is_collapsed_after}")
        assert not is_collapsed_after, "Tree explorer should be restored to expanded state!"

        # Step 6: Verify High-Density Grid (Center Pane)
        print("\n[Step 6] Checking High-Density Document Grid...")
        # Wait for data rows to load
        await page.wait_for_selector("#doc-table-body tr", timeout=5000)
        table_rows = await page.query_selector_all("#doc-table-body tr")
        print(f"  -> Rendered {len(table_rows)} document rows in grid.")
        assert len(table_rows) >= 2, f"Expected at least 2 documents, found {len(table_rows)}"

        # Step 7: Screenshot initial grid view
        ss1 = SCREENSHOTS_DIR / "doc_dashboard_tri_pane_grid.png"
        await page.screenshot(path=str(ss1))
        print(f"  [OK] Screenshot saved: {ss1}")
        shutil.copy(ss1, ARTIFACTS_DIR / "doc_dashboard_tri_pane_grid.png")

        # Step 8: Test Search Filter
        print("\n[Step 8] Testing Omni-Search filtering...")
        await page.fill("#omni-search", "IB2600471890")
        await page.wait_for_timeout(500)
        filtered_rows = await page.query_selector_all("#doc-table-body tr")
        print(f"  -> Rows matching 'IB2600471890': {len(filtered_rows)}")
        assert len(filtered_rows) == 1, f"Expected exactly 1 matching row, got {len(filtered_rows)}"

        # Clear search
        await page.click("#btn-clear-search")
        await page.wait_for_timeout(500)
        all_rows = await page.query_selector_all("#doc-table-body tr")
        print(f"  -> Rows after clearing search: {len(all_rows)}")
        assert len(all_rows) >= 2, "Expected all rows back after clearing search!"

        # Step 9: Click a Document Row to inspect Contextual Detail Pane (Right Pane)
        print("\n[Step 9] Clicking document row to open Contextual Detail Pane...")
        first_row = await page.query_selector("#doc-table-body tr")
        await first_row.click()
        await page.wait_for_timeout(800)

        detail_pane = await page.query_selector("#doc-detail-pane")
        assert detail_pane is not None, "#doc-detail-pane not found!"
        is_detail_open = await page.evaluate("document.getElementById('doc-detail-pane').classList.contains('open')")
        print(f"  -> Detail pane opened: {is_detail_open}")
        assert is_detail_open, "Detail pane should have 'open' class!"

        # Step 10: Screenshot detail split view
        ss2 = SCREENSHOTS_DIR / "doc_dashboard_tri_pane_detail.png"
        await page.screenshot(path=str(ss2))
        print(f"  [OK] Screenshot saved: {ss2}")
        shutil.copy(ss2, ARTIFACTS_DIR / "doc_dashboard_tri_pane_detail.png")

        # Step 11: Test View Mode Toggle (Grid wide mode)
        print("\n[Step 11] Testing Grid wide mode / Split toggle...")
        btn_grid = await page.query_selector("#btn-view-grid")
        assert btn_grid is not None, "#btn-view-grid not found!"
        await btn_grid.click()
        await page.wait_for_timeout(500)

        ss3 = SCREENSHOTS_DIR / "doc_dashboard_grid_wide_mode.png"
        await page.screenshot(path=str(ss3))
        print(f"  [OK] Screenshot saved: {ss3}")
        shutil.copy(ss3, ARTIFACTS_DIR / "doc_dashboard_grid_wide_mode.png")

        # Switch back to split view
        btn_split = await page.query_selector("#btn-view-split")
        await btn_split.click()
        await page.wait_for_timeout(500)

        # Step 12: Close Detail Pane
        print("\n[Step 12] Closing detail pane...")
        close_btn = await page.query_selector(".btn-close-pane")
        if close_btn:
            await close_btn.click()
            await page.wait_for_timeout(300)
            is_detail_open_after = await page.evaluate("document.getElementById('doc-detail-pane').classList.contains('open')")
            print(f"  -> Detail pane closed: {not is_detail_open_after}")
            assert not is_detail_open_after, "Detail pane should be closed!"

        # Step 13: Test Create Modal & 2-Tier Taxonomy Dropdown
        print("\n[Step 13] Testing Create Modal & 2-Tier Taxonomy Dropdown...")
        btn_create = await page.query_selector("#btn-create-doc")
        assert btn_create is not None, "#btn-create-doc not found!"
        await btn_create.click()
        await page.wait_for_timeout(500)

        modal_visible = await page.evaluate("document.getElementById('create-modal').style.display === 'flex'")
        assert modal_visible, "Create modal should be open!"

        # Check optgroups
        optgroups = await page.query_selector_all("#form-doc-type optgroup")
        print(f"  -> Found {len(optgroups)} optgroups in #form-doc-type.")
        assert len(optgroups) >= 5, f"Expected at least 5 optgroups, got {len(optgroups)}"

        # Check initial next code preview contains -ĐS
        preview_text = await page.evaluate("document.getElementById('form-next-code-preview').textContent.trim()")
        print(f"  -> Initial next number preview: {preview_text}")
        assert preview_text.endswith("-ĐS"), f"Expected preview to end with -ĐS, got: {preview_text}"

        # Select 'TM' (Thuyết minh)
        await page.select_option("#form-doc-type", "TM")
        await page.evaluate("onFormDocTypeChange()")
        await page.wait_for_timeout(800)
        preview_tm = await page.evaluate("document.getElementById('form-next-code-preview').textContent.trim()")
        print(f"  -> Preview after selecting TM: {preview_tm}")
        assert "/TM-ĐS" in preview_tm, f"Expected /TM-ĐS in preview, got: {preview_tm}"

        # Select 'KHAC' (Tự nhập mã)
        await page.select_option("#form-doc-type", "KHAC")
        await page.evaluate("onFormDocTypeChange()")
        await page.wait_for_timeout(400)
        custom_wrap_visible = await page.evaluate("document.getElementById('form-custom-type-wrap').style.display !== 'none'")
        print(f"  -> Custom type input wrap visible: {custom_wrap_visible}")
        assert custom_wrap_visible, "Custom type input wrap should be visible when KHAC is selected!"

        # Input custom type 'HDNT'
        await page.fill("#form-custom-type-input", "HDNT")
        await page.evaluate("updateNextNumberPreview()")
        await page.wait_for_timeout(800)
        preview_custom = await page.evaluate("document.getElementById('form-next-code-preview').textContent.trim()")
        print(f"  -> Preview after entering custom code HDNT: {preview_custom}")
        assert "/HDNT-ĐS" in preview_custom, f"Expected /HDNT-ĐS in preview, got: {preview_custom}"

        # Screenshot Create Modal
        ss4 = SCREENSHOTS_DIR / "doc_dashboard_create_modal_taxonomy.png"
        await page.screenshot(path=str(ss4))
        print(f"  [OK] Screenshot saved: {ss4}")
        shutil.copy(ss4, ARTIFACTS_DIR / "doc_dashboard_create_modal_taxonomy.png")

        # Close Create Modal
        await page.evaluate("closeCreateModal()")
        await page.wait_for_timeout(400)

        # Step 14: Test Left Pane Tree Mega-Group & Document Type Filter
        print("\n[Step 14] Testing Left Pane Mega-Group selector and dynamic pills...")
        group_sel = await page.query_selector("#tree-group-select")
        assert group_sel is not None, "#tree-group-select not found!"

        # Select 'technical' mega-group
        await page.select_option("#tree-group-select", "technical")
        await page.evaluate("selectDocGroup('technical')")
        await page.wait_for_timeout(800)

        # Scroll tree explorer to show Group 4 without shifting page body
        await page.evaluate("""() => {
            const tree = document.getElementById('doc-tree-explorer');
            const sel = document.getElementById('tree-group-select');
            if (tree && sel) {
                tree.scrollTop = sel.offsetTop - 80;
            }
            document.body.scrollTop = 0;
            document.documentElement.scrollTop = 0;
            window.scrollTo(0, 0);
        }""")
        await page.wait_for_timeout(300)

        tech_pills = await page.query_selector_all("#tree-doc-type-chips .tree-pill")
        tech_pill_texts = [await p.inner_text() for p in tech_pills]
        print(f"  -> Technical group pills: {tech_pill_texts}")
        assert "TM" in tech_pill_texts or "BV" in tech_pill_texts, "Expected technical sub-types in pills!"

        # Screenshot state showing technical mega-group and pills
        ss5 = SCREENSHOTS_DIR / "doc_dashboard_tree_taxonomy_filter.png"
        await page.screenshot(path=str(ss5))
        print(f"  [OK] Screenshot saved: {ss5}")
        shutil.copy(ss5, ARTIFACTS_DIR / "doc_dashboard_tree_taxonomy_filter.png")

        # Reset filters
        await page.evaluate("resetAllFilters()")
        await page.wait_for_timeout(800)

        # Step 15: Test High-Density Column Resizing & Persistence
        print("\n[Step 15] Testing Column Resizing, localStorage persistence, and Reset button...")
        # Ensure page and table scroll are at origin
        await page.evaluate("""() => {
            document.body.scrollTop = 0;
            document.documentElement.scrollTop = 0;
            window.scrollTo(0, 0);
            const wrap = document.querySelector('.doc-table-wrap');
            if (wrap) { wrap.scrollTop = 0; wrap.scrollLeft = 0; }
        }""")
        await page.wait_for_timeout(300)

        # Get the 'title' column header and its resizer
        th_title = await page.query_selector('th[data-col="title"]')
        assert th_title is not None, "Header th[data-col='title'] not found!"
        resizer_title = await page.query_selector('th[data-col="title"] .col-resizer')
        assert resizer_title is not None, "Column resizer for title not found!"

        # Initial width of title column
        init_box = await th_title.bounding_box()
        init_width = init_box["width"]
        print(f"  -> Initial 'title' column width: {init_width:.1f}px")

        # Drag resizer to expand width (+150px)
        resizer_box = await resizer_title.bounding_box()
        start_x = resizer_box["x"] + resizer_box["width"] / 2
        start_y = resizer_box["y"] + resizer_box["height"] / 2

        await page.mouse.move(start_x, start_y)
        await page.mouse.down()
        for i in range(1, 16):
            await page.mouse.move(start_x + i * 10, start_y)
            await page.wait_for_timeout(20)
        await page.mouse.up()
        await page.wait_for_timeout(300)

        new_box = await th_title.bounding_box()
        new_width = new_box["width"]
        print(f"  -> Resized 'title' column width: {new_width:.1f}px (diff: {new_width - init_width:.1f}px)")
        assert new_width > init_width + 100, f"Expected column width to increase significantly, got {new_width}"

        # Check localStorage persistence
        saved_widths = await page.evaluate("localStorage.getItem('dscons_doc_col_widths')")
        print(f"  -> Persisted widths in localStorage: {saved_widths}")
        assert saved_widths is not None and "title" in saved_widths, "Column width was not persisted to localStorage!"

        # Screenshot column resized state
        ss6 = SCREENSHOTS_DIR / "doc_dashboard_column_resized.png"
        await page.screenshot(path=str(ss6))
        print(f"  [OK] Screenshot saved: {ss6}")
        shutil.copy(ss6, ARTIFACTS_DIR / "doc_dashboard_column_resized.png")

        # Test Reset Column Widths button (#btn-reset-cols)
        btn_reset_cols = await page.query_selector("#btn-reset-cols")
        assert btn_reset_cols is not None, "Reset column widths button #btn-reset-cols not found!"
        await btn_reset_cols.click()
        await page.wait_for_timeout(400)

        reset_box = await th_title.bounding_box()
        reset_width = reset_box["width"]
        print(f"  -> Width after clicking reset button: {reset_width:.1f}px")
        assert abs(reset_width - 320) < 15, f"Expected width to return close to default 320px, got {reset_width}"

        # Test double-click to reset single column: Drag again and then dblclick
        resizer2 = await page.query_selector('th[data-col="title"] .col-resizer')
        box2 = await resizer2.bounding_box()
        start_x2 = box2["x"] + box2["width"] / 2
        start_y2 = box2["y"] + box2["height"] / 2
        await page.mouse.move(start_x2, start_y2)
        await page.mouse.down()
        for i in range(1, 10):
            await page.mouse.move(start_x2 + i * 10, start_y2)
            await page.wait_for_timeout(20)
        await page.mouse.up()
        await page.wait_for_timeout(300)

        # Double click the resizer
        resizer3 = await page.query_selector('th[data-col="title"] .col-resizer')
        await resizer3.dblclick()
        await page.wait_for_timeout(400)

        dbl_reset_box = await th_title.bounding_box()
        dbl_reset_width = dbl_reset_box["width"]
        print(f"  -> Width after double clicking resizer: {dbl_reset_width:.1f}px")
        assert abs(dbl_reset_width - 320) < 15, f"Expected single column double click to reset, got {dbl_reset_width}"

        print("\n================================================================")
        print("  ALL BROWSER AUTOMATION TESTS PASSED (100% SUCCESS)")
        print("================================================================")
        await browser.close()


if __name__ == "__main__":
    asyncio.run(run_document_dashboard_verification())
