"""Validation service for log:pass accounts (no mafile)."""

from pathlib import Path

from bs4 import BeautifulSoup
from loguru import logger

from app.services.steam_auth import _resolve_proxy, ProxyRequestStrategy, close_steam, extract_session_cookies
from app.services.steam_ban import check_ban
from app.services.steam_profile import fetch_profile
from app.services.steam_vac_checker import check_vac_and_limit
from app.core.proxy_manager import proxy_manager
from app.core.task_manager import task_manager


async def check_logpass_account(account: dict, params: dict, *, task_id: str) -> None:
    """Login with login:pass only, get steamid/nickname, check ban, update DB row."""
    try:
        from pysteamauth.auth import Steam
    except ImportError:
        raise RuntimeError("pysteamauth not installed")

    acc_id = account["id"]
    proxy = await _resolve_proxy(account)
    request_strategy = None
    if proxy:
        connector = proxy_manager.get_connector(proxy)
        request_strategy = ProxyRequestStrategy(connector)
        logger.debug(f"[checker] Using proxy for {account['login']}")

    steam = Steam(
        login=account["login"],
        password=account["password"],
        request_strategy=request_strategy,
    )

    try:
        await task_manager.set_step(task_id, 1, 3, "Авторизация", acc_id)

        # Pre-validate password before attempting RSA encryption (Steam RSA-2048 max 245 bytes)
        password = account.get("password") or ""
        if len(password.encode("utf-8")) > 245:
            raise ValueError(
                f"Password is too long ({len(password)} chars) — possible mafile data imported as password. "
                "Re-import the account in login:password format."
            )

        await steam.login_to_steam()

        # Save session cookies right after login
        try:
            session_cookies_json = extract_session_cookies(steam)
            if session_cookies_json:
                from app.database import get_db as _get_db
                _db = await _get_db()
                await _db.execute(
                    "UPDATE logpass_accounts SET session_cookies = ? WHERE id = ?",
                    (session_cookies_json, acc_id),
                )
                await _db.commit()
                logger.debug(f"[checker] {account['login']}: saved session cookies")
        except Exception as cookie_err:
            logger.warning(f"[checker] {account['login']}: failed to save cookies — {cookie_err}")

        from app.config import read_validation_settings
        val_settings = read_validation_settings()

        steam_id = str(steam.steamid)
        ban_status = ""
        vac_status = ""
        limit_status = ""
        vac_games: list[str] = []
        if val_settings.get("check_ban"):
            await task_manager.set_step(task_id, 2, 4, "Проверка бана", acc_id)
            ban_status = await check_ban(steam)
            vac_status, limit_status, vac_games = await check_vac_and_limit(steam)

        await task_manager.set_step(task_id, 3, 4, "Баланс / Страна", acc_id)
        from app.services.steam_store_checker import fetch_balance_and_country
        balance, country = await fetch_balance_and_country(steam)
        logger.info(f"[checker] {account['login']}: balance={balance or 'none'}, country={country or 'none'}")

        nickname = None
        steam_level = None
        avatar_url = None
        last_online = None
        if steam_id and steam_id != "0" and val_settings.get("fetch_profile"):
            await task_manager.set_step(task_id, 4, 4, "Получение профиля", acc_id)
            profile = await fetch_profile(steam_id, steam=steam)
            if profile:
                nickname = profile.get("nickname")
                steam_level = profile.get("steam_level")
                avatar_url = profile.get("avatar_url")
                last_online = profile.get("last_online")

        import json as _json
        from app.database import get_db
        db = await get_db()
        await db.execute(
            """UPDATE logpass_accounts
               SET steam_id = ?, nickname = ?, steam_level = ?, avatar_url = ?, last_online = ?,
                   ban_status = ?, vac_status = ?, limit_status = ?, vac_games = ?,
                   balance = ?, country = ?,
                   status = 'valid', updated_at = datetime('now')
               WHERE id = ?""",
            (steam_id, nickname, steam_level, avatar_url, last_online,
             ban_status, vac_status, limit_status,
             _json.dumps(vac_games) if vac_games else None,
             balance or None, country or None, acc_id),
        )
        await db.commit()
        logger.success(f"[checker] {account['login']} → valid, ban={ban_status}")

    except Exception as exc:
        from app.database import get_db
        db = await get_db()
        await db.execute(
            "UPDATE logpass_accounts SET status = 'invalid', updated_at = datetime('now') WHERE id = ?",
            (acc_id,),
        )
        await db.commit()
        logger.error(f"[checker] {account['login']} → {exc}")
        raise

    finally:
        await close_steam(steam)


async def _check_cs2_prime(steam, steam_id: str) -> str:
    """Check CS2 Prime status."""
    try:
        url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/730/?tab=primeaccount"
        resp = await steam.request(url, method="GET")
        html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
        if "no_personal_data_stored_message" in html:
            return "Disabled"
        if "personaldata_elements_container" in html and "Enabled" in html:
            return "Enabled"
        return "Disabled"
    except Exception as e:
        logger.debug(f"[full_parse] prime check error: {e}")
        return "Disabled"


async def _check_dota_trophy(steam, steam_id: str) -> str | None:
    """Check Dota 2 Trophy Score."""
    try:
        url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/570/?category=Stats&tab=Trophy"
        resp = await steam.request(url, method="GET")
        html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
        if "no_personal_data_stored_message" in html:
            return None
        if "personaldata_elements_container" in html:
            soup = BeautifulSoup(html, "html.parser")
            for row in soup.find_all("tr"):
                cells = row.find_all("td")
                if len(cells) >= 3:
                    try:
                        int(cells[0].get_text(strip=True))
                        score = cells[1].get_text(strip=True)
                        if score.isdigit():
                            return score
                    except (ValueError, AttributeError):
                        continue
        return None
    except Exception as e:
        logger.debug(f"[full_parse] trophy check error: {e}")
        return None


async def _check_dota_behavior(steam, steam_id: str) -> str | None:
    """Check Dota 2 Behavior Score."""
    try:
        url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/570/?category=Account&tab=MatchPlayerReportIncoming"
        resp = await steam.request(url, method="GET")
        html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
        if "no_personal_data_stored_message" in html:
            return None
        if "personaldata_elements_container" in html:
            soup = BeautifulSoup(html, "html.parser")
            for row in soup.find_all("tr"):
                cells = row.find_all("td")
                if cells:
                    last_cell = cells[-1].get_text(strip=True)
                    if last_cell.isdigit():
                        return last_cell
        return None
    except Exception as e:
        logger.debug(f"[full_parse] behavior check error: {e}")
        return None


async def _check_licenses(steam) -> str:
    """Get list of licenses (games) from Steam account."""
    try:
        resp = await steam.request("https://store.steampowered.com/account/licenses/", method="GET")
        html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
        soup = BeautifulSoup(html, "html.parser")
        table = soup.find("table", class_="account_table")
        if not table:
            return ""
        licenses = []
        rows = table.find_all("tr")
        for row in rows[1:]:
            cells = row.find_all("td")
            if len(cells) >= 2:
                game_cell = cells[1]
                remove_div = game_cell.find("div", class_="free_license_remove_link")
                if remove_div:
                    remove_div.decompose()
                name = game_cell.get_text(strip=True)
                if name:
                    licenses.append(name)
        return ", ".join(licenses)
    except Exception as e:
        logger.debug(f"[full_parse] licenses check error: {e}")
        return ""


async def full_parse_logpass_account(account: dict, params: dict, *, task_id: str) -> None:
    """Full parse: login, ban, profile, prime, trophy, behavior, licenses."""
    try:
        from pysteamauth.auth import Steam
    except ImportError:
        raise RuntimeError("pysteamauth not installed")

    acc_id = account["id"]
    proxy = await _resolve_proxy(account)
    request_strategy = None
    if proxy:
        connector = proxy_manager.get_connector(proxy)
        request_strategy = ProxyRequestStrategy(connector)

    steam = Steam(
        login=account["login"],
        password=account["password"],
        request_strategy=request_strategy,
    )

    try:
        await task_manager.set_step(task_id, 1, 7, "Авторизация", acc_id)
        await steam.login_to_steam()

        # Save session cookies
        try:
            session_cookies_json = extract_session_cookies(steam)
            if session_cookies_json:
                from app.database import get_db as _get_db
                _db = await _get_db()
                await _db.execute(
                    "UPDATE logpass_accounts SET session_cookies = ? WHERE id = ?",
                    (session_cookies_json, acc_id),
                )
                await _db.commit()
        except Exception as cookie_err:
            logger.warning(f"[full_parse] {account['login']}: failed to save cookies — {cookie_err}")

        steam_id = str(steam.steamid)

        await task_manager.set_step(task_id, 2, 7, "Проверка бана", acc_id)
        ban_status = await check_ban(steam)
        vac_status, limit_status, vac_games = await check_vac_and_limit(steam)

        nickname = avatar_url = last_online = None
        steam_level = None
        if steam_id and steam_id != "0":
            await task_manager.set_step(task_id, 3, 7, "Профиль", acc_id)
            profile = await fetch_profile(steam_id, steam=steam)
            if profile:
                nickname = profile.get("nickname")
                steam_level = profile.get("steam_level")
                avatar_url = profile.get("avatar_url")
                last_online = profile.get("last_online")

        await task_manager.set_step(task_id, 4, 7, "Баланс / Страна", acc_id)
        from app.services.steam_store_checker import fetch_balance_and_country
        balance, country = await fetch_balance_and_country(steam)
        logger.info(f"[full_parse] {account['login']}: balance={balance or 'none'}, country={country or 'none'}")

        prime = "Disabled"
        trophy = None
        behavior = None
        if steam_id and steam_id != "0":
            await task_manager.set_step(task_id, 5, 7, "Prime / Trophy", acc_id)
            prime = await _check_cs2_prime(steam, steam_id)
            trophy = await _check_dota_trophy(steam, steam_id)
            behavior = await _check_dota_behavior(steam, steam_id)

        await task_manager.set_step(task_id, 6, 7, "Лицензии", acc_id)
        license_str = await _check_licenses(steam)

        import json as _json
        await task_manager.set_step(task_id, 7, 7, "Сохранение", acc_id)
        from app.database import get_db
        db = await get_db()
        await db.execute(
            """UPDATE logpass_accounts
               SET steam_id = ?, nickname = ?, steam_level = ?, avatar_url = ?, last_online = ?,
                   ban_status = ?, vac_status = ?, limit_status = ?, vac_games = ?,
                   balance = ?, country = ?,
                   prime = ?, trophy = ?, behavior = ?, license = ?,
                   status = 'valid', updated_at = datetime('now')
               WHERE id = ?""",
            (steam_id, nickname, steam_level, avatar_url, last_online,
             ban_status, vac_status, limit_status,
             _json.dumps(vac_games) if vac_games else None,
             balance or None, country or None,
             prime, trophy, behavior, license_str, acc_id),
        )
        await db.commit()
        logger.success(f"[full_parse] {account['login']} → valid, ban={ban_status}, prime={prime}, trophy={trophy}, behavior={behavior}, licenses={len(license_str.split(', ')) if license_str else 0}")

    except Exception as exc:
        from app.database import get_db
        db = await get_db()
        await db.execute(
            "UPDATE logpass_accounts SET status = 'invalid', updated_at = datetime('now') WHERE id = ?",
            (acc_id,),
        )
        await db.commit()
        logger.error(f"[full_parse] {account['login']} → {exc}")
        raise

    finally:
        await close_steam(steam)
