#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from urllib.parse import urlparse, parse_qs
import re
import time
from playwright.sync_api import sync_playwright, TimeoutError as PWTimeout, Page

# ===== funkce pro přiřazení jednoho požadavku =====
def assign_request_to_buzalka(page: Page, request_uuid: str) -> None:
    """
    Otevře kartu požadavku podle UUID a přiřadí ji MUDr. Buzalka (já).
    Po uložení změny zavře dialog a vypíše potvrzení.
    """
    url = f"https://my.medevio.cz/mudr-buzalkova/klinika/pozadavky?pozadavek={request_uuid}"
    page.goto(url, wait_until="domcontentloaded", timeout=60_000)

    combo = page.locator('div[role="combobox"][aria-labelledby="queue-select-label"]')
    combo.wait_for(state="visible")
    combo.click()

    option = page.get_by_role("option", name=re.compile(r"MUDr\.?\s*Buzalka", re.I))
    option.click()

    page.wait_for_load_state("networkidle")

    page.locator("button.MuiDialog-close").click()
    print(f"✔ Požadavek {request_uuid} přiřazen: MUDr. Buzalka (já)")

# ===== hlavní část: projít listing a řešit chřipku =====
POZADAVKY_URL = "https://my.medevio.cz/mudr-buzalkova/klinika/pozadavky"
# POZADAVKY_URL = "https://my.medevio.cz/mudr-buzalkova/klinika/pozadavky?neprirazene=1"

STATE_FILE = "medevio_storage.json"

from playwright.sync_api import Page
import time

def _find_scroll_container(page: Page):
    """Return an ElementHandle of the real scrollable container, or None -> use window."""
    handle = page.evaluate_handle("""
() => {
  const isScrollable = el => !!el && (el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth);

  const row = document.querySelector('tr[data-testid="patient-request-row"]');
  if (row) {
    let el = row.parentElement;
    while (el) {
      const style = getComputedStyle(el);
      const overflowY = style.overflowY;
      if (isScrollable(el) && (overflowY === 'auto' || overflowY === 'scroll')) return el;
      el = el.parentElement;
    }
  }
  const guesses = [
    '[role="rowgroup"]', '[role="table"]', '.MuiTableContainer-root',
    '[data-testid="requests-table"]', '.MuiContainer-root', 'main'
  ];
  for (const sel of guesses) {
    const el = document.querySelector(sel);
    if (el) {
      const style = getComputedStyle(el);
      const overflowY = style.overflowY;
      if (isScrollable(el) && (overflowY === 'auto' || overflowY === 'scroll')) return el;
    }
  }
  return null;
}
""")
    # If JS returned null, convert to Python None
    try:
        if handle is None or handle.json_value() is None:
            return None
    except Exception:
        return None
    return handle

def _has_handle(page: Page, handle) -> bool:
    """Check the handle still points to a live element; else False -> use window."""
    if not handle:
        return False
    try:
        return bool(page.evaluate("(el)=>!!el", handle))
    except Exception:
        return False

def _scroll_step(page: Page, container_handle, px=800):
    if _has_handle(page, container_handle):
        try:
            page.evaluate(
                "(args) => { const [el, dy] = args; el.scrollBy(0, dy); }",
                [container_handle, px]
            )
            return
        except Exception:
            pass
    # Fallback to window
    page.evaluate("dy => window.scrollBy(0, dy)", px)

def _scroll_to_bottom(page: Page, container_handle):
    if _has_handle(page, container_handle):
        try:
            page.evaluate("(el) => el.scrollTo(0, el.scrollHeight)", container_handle)
            return
        except Exception:
            pass
    page.evaluate("() => window.scrollTo(0, document.body.scrollHeight)")

def _click_load_more_if_any(page: Page) -> bool:
    btn = page.locator("button:has-text('Načíst více'), button:has-text('Zobrazit další'), button:has-text('Load more')")
    if btn.count() and btn.is_visible():
        btn.click()
        return True
    return False

def load_all_requests(page: Page, max_rounds: int = 200, stagnation_limit: int = 4) -> None:
    """
    Incrementally loads the entire list of requests.
    Stops after 'stagnation_limit' rounds without row growth, or after max_rounds.
    """
    page.wait_for_selector('tr[data-testid="patient-request-row"]', timeout=20000)

    container = _find_scroll_container(page)
    prev_count = page.locator('tr[data-testid="patient-request-row"]').count()
    stagnant = 0

    for _ in range(max_rounds):
        if _click_load_more_if_any(page):
            page.wait_for_load_state("networkidle")

        # small incremental scrolls
        for _ in range(4):
            _scroll_step(page, container, px=800)
            time.sleep(0.15)

        # touch bottom at least once
        _scroll_to_bottom(page, container)

        # settle
        page.wait_for_load_state("networkidle")
        spinners = page.locator('[role="progressbar"], .MuiCircularProgress-root')
        if spinners.count():
            try:
                spinners.first.wait_for(state="detached", timeout=5000)
            except Exception:
                pass

        # growth check
        curr_count = page.locator('tr[data-testid="patient-request-row"]').count()
        if curr_count <= prev_count:
            stagnant += 1
        else:
            stagnant = 0
            prev_count = curr_count

        if stagnant >= stagnation_limit:
            break


def get_uuid_from_href(href: str) -> str | None:
    try:
        q = parse_qs(urlparse(href).query)
        val = q.get("pozadavek", [None])[0]
        return val
    except Exception:
        return None

def is_flu_request(text: str) -> bool:
    # libovolná varianta slova „chřipk“ (chřipka, chřipky, …), case-insensitive, s diakritikou i bez
    return bool(re.search(r"ch(r|ř)ipk", text, re.IGNORECASE))

def main():
    with sync_playwright() as pw:
        browser = pw.chromium.launch(headless=False)
        context = browser.new_context(storage_state=STATE_FILE)
        page = context.new_page()

        page.goto(POZADAVKY_URL, wait_until="domcontentloaded", timeout=60_000)

        body = (page.text_content("body") or "").lower()
        if any(x in body for x in ["přihlášení", "přihlásit", "sign in", "login"]):
            raise SystemExit("Vypadá to, že nejsi přihlášený – obnov prosím medevio_storage.json.")

        try:
            page.wait_for_selector('tr[data-testid="patient-request-row"]', timeout=20_000)
        except PWTimeout:
            raise SystemExit("Nenašel jsem řádky požadavků (selector tr[data-testid=patient-request-row]).")



        # after navigating to the listing and ensuring first rows are visible:
        load_all_requests(page)
        rows = page.locator('tr[data-testid="patient-request-row"]')
        print("Loaded rows:", rows.count())

        for i in range(count):
            row = rows.nth(i)

            # UUID z href
            a_with_req = row.locator('a[href*="pozadavky?pozadavek="]').first
            href = a_with_req.get_attribute("href") if a_with_req.count() else None
            req_id = get_uuid_from_href(href) if href else None
            if not req_id:
                continue

            # Text požadavku (pro filtr „chřipka“)
            text_p = row.locator('td:nth-child(3) p.MuiTypography-body1, td:nth-child(4) p.MuiTypography-body1').first
            text_req = text_p.inner_text().strip() if text_p.count() else ""
            if not text_req:
                aria = row.locator('td:nth-child(3) [aria-label], td:nth-child(4) [aria-label]').first
                text_req = (aria.get_attribute("aria-label") or "").strip() if aria.count() else ""

            if not is_flu_request(text_req):
                # není to chřipkový požadavek – přeskočit
                continue

            # Zjištění přiřazení z avatara v listingu
            avatar = row.locator('[data-testid="queue-avatar"]').first
            assigned_to = (avatar.get_attribute("aria-label") or "").strip() if avatar.count() else ""
            initials = avatar.inner_text().strip() if avatar.count() else ""

            already_mine = ("buzalka" in assigned_to.lower()) or (initials.upper() == "VB")

            if already_mine:
                print(f"= SKIP (už přiřazeno mně): {req_id} | {text_req}")
                continue

            print(f"→ Přiřazuji chřipkový požadavek: {req_id} | {text_req}")
            assign_request_to_buzalka(page, req_id)
            time.sleep(1)

        context.close()
        browser.close()

if __name__ == "__main__":
    main()
