"""
Ephemeral per-chat flag: "this chat picked a network and is now expected to
send a transaction hash for it".

Set right after a network button is pressed (core/handlers.handle_explorer_network_selected)
and consumed (read once and cleared) by the next text message from that chat.

Backed by a small JSON file (same pattern as services/referral_state.py)
rather than an in-process dict, so it survives across Passenger/Flask worker
processes.
"""

import json
import os
import threading
import time

from .. import config

_lock = threading.Lock()
_TABLE = "explorer_wait_state"

# If the user never sends a hash, don't let the flag linger forever.
_TTL_SECONDS = 15 * 60


def _path() -> str:
    return os.path.join(config.DATA_DIR, f"{_TABLE}.json")


def _load() -> dict:
    path = _path()
    if not os.path.exists(path):
        return {}
    with open(path, "r", encoding="utf-8") as fh:
        try:
            return json.load(fh)
        except json.JSONDecodeError:
            return {}


def _save(data: dict) -> None:
    os.makedirs(config.DATA_DIR, exist_ok=True)
    with open(_path(), "w", encoding="utf-8") as fh:
        json.dump(data, fh, ensure_ascii=False, indent=2)


def mark_awaiting_hash(chat_id, network: str) -> None:
    """Call right after the user picks a network for the tx-hash lookup."""
    if chat_id is None:
        return
    with _lock:
        data = _load()
        data[str(chat_id)] = {"network": network, "ts": time.time()}
        _save(data)


def consume_awaiting_hash(chat_id):
    """
    Return the pending network name and clear the flag if `chat_id` is
    currently expected to reply with a tx hash; return None otherwise
    (including an expired flag). Always clears the stored entry so the flag
    is single-use.
    """
    if chat_id is None:
        return None
    with _lock:
        data = _load()
        entry = data.pop(str(chat_id), None)
        if entry is not None:
            _save(data)
    if entry is None:
        return None
    if (time.time() - entry.get("ts", 0)) > _TTL_SECONDS:
        return None
    return entry.get("network")
