"""
Run a mobile-friendly LoL signal receiver page.

Open the page on a phone, tap an event button, and the server writes
data/lpl_signals/<event_slug>/signals.jsonl.
"""
from __future__ import annotations

import os
import sys
import json
import asyncio
from pathlib import Path
from typing import Any

import aiohttp
import click
from aiohttp import web
from dotenv import load_dotenv
from loguru import logger

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT not in sys.path:
    sys.path.insert(0, ROOT)

from analysis.lpl_orderbook.signal_server import make_app  # noqa: E402
from analysis.lpl_orderbook.activity_trades import select_target_markets  # noqa: E402
from analysis.safe_btc5.clients import GAMMA_BASE  # noqa: E402


def _json_list(raw: Any) -> list[Any]:
    if raw is None:
        return []
    if isinstance(raw, list):
        return raw
    if isinstance(raw, str):
        try:
            value = json.loads(raw)
        except json.JSONDecodeError:
            return []
        return value if isinstance(value, list) else []
    return []


async def _fetch_event(event_slug: str) -> dict[str, Any]:
    timeout = aiohttp.ClientTimeout(total=20)
    headers = {"User-Agent": "Mozilla/5.0"}
    async with aiohttp.ClientSession(timeout=timeout, headers=headers) as http:
        async with http.get(f"{GAMMA_BASE}/events/slug/{event_slug}") as resp:
            resp.raise_for_status()
            data = await resp.json()
            return data if isinstance(data, dict) else {}


def _main_markets(event_slug: str, event: dict[str, Any]) -> dict[str, Any]:
    targets = select_target_markets(event_slug, event.get("markets") or [], None)
    output: dict[str, Any] = {}
    for target in targets:
        output[target.kind] = {
            "slug": target.slug,
            "condition_id": target.condition_id,
            "market_id": target.market_id,
            "question": target.question,
            "teams": [
                {
                    "name": target.outcomes[idx] if idx < len(target.outcomes) else "",
                    "token_id": token_id,
                }
                for idx, token_id in enumerate(target.token_ids[:2])
            ],
        }
    return output


async def _fetch_market_config(event_slug: str) -> tuple[str, str, str, str, dict[str, Any]]:
    if not event_slug:
        return "A", "B", "", "", {}
    event = await _fetch_event(event_slug)
    markets = _main_markets(event_slug, event)
    moneyline = markets.get("moneyline") or {}
    teams = moneyline.get("teams") or []
    if len(teams) >= 2:
        return (
            str(teams[0].get("name") or "A"),
            str(teams[1].get("name") or "B"),
            str(teams[0].get("token_id") or ""),
            str(teams[1].get("token_id") or ""),
            markets,
        )
    raise RuntimeError(f"moneyline market not found for event_slug={event_slug}")


def _setup_logging() -> None:
    logger.remove()
    logger.add(
        sys.stderr,
        level=os.environ.get("LOG_LEVEL", "INFO").upper(),
        format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level:<7}</level> | {message}",
        colorize=True,
    )


@click.command()
@click.option("--host", default="0.0.0.0", show_default=True)
@click.option("--port", default=8090, show_default=True, type=int)
@click.option(
    "--output-root",
    default="data/lpl_signals",
    show_default=True,
    type=click.Path(file_okay=False, path_type=Path),
)
@click.option(
    "--token",
    default="",
    help="Optional signal token. Defaults to SIGNAL_SERVER_TOKEN env when omitted.",
)
@click.option("--event-slug", default="", help="Preset event slug. Defaults to SIGNAL_EVENT_SLUG env.")
@click.option("--default-market", default="game1", show_default=True)
@click.option("--editable", is_flag=True, help="Allow editing preset event/team/token fields.")
@click.option("--hide-token", is_flag=True, help="Do not expose token in the page.")
def main(
    host: str,
    port: int,
    output_root: Path,
    token: str,
    event_slug: str,
    default_market: str,
    editable: bool,
    hide_token: bool,
) -> None:
    load_dotenv()
    _setup_logging()
    token = token or os.getenv("SIGNAL_SERVER_TOKEN", "")
    event_slug = event_slug or os.getenv("SIGNAL_EVENT_SLUG", "")
    try:
        team_a, team_b, team_a_token_id, team_b_token_id, markets = asyncio.run(
            _fetch_market_config(event_slug)
        )
    except Exception as exc:
        logger.warning(f"无法从 Gamma 获取队名/token，使用占位: {exc}")
        team_a, team_b, team_a_token_id, team_b_token_id, markets = "A", "B", "", "", {}
    logger.info(
        f"启动 LoL signal server: http://{host}:{port} output_root={output_root} "
        f"auth={'on' if token else 'off'} event_slug={event_slug} "
        f"team_a={team_a}:{team_a_token_id} team_b={team_b}:{team_b_token_id}"
    )
    web.run_app(
        make_app(
            output_root=output_root,
            token=token,
            event_slug=event_slug,
            team_a=team_a,
            team_b=team_b,
            team_a_token_id=team_a_token_id,
            team_b_token_id=team_b_token_id,
            markets=markets,
            default_market=default_market,
            lock_config=not editable,
            expose_token=not hide_token,
        ),
        host=host,
        port=port,
    )


if __name__ == "__main__":
    main()
