from __future__ import annotations

import hashlib
import json
from pathlib import Path
from typing import Any


ROOT = Path(__file__).resolve().parents[2]
TEMP = ROOT / "Temp"


def rp(path_str: str | Path) -> Path:
    path = Path(path_str)
    return path if path.is_absolute() else ROOT / path


def load_json(path: str | Path) -> dict[str, Any]:
    p = rp(path)
    if not p.exists():
        return {}
    try:
        payload = json.loads(p.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return payload if isinstance(payload, dict) else {}


def save_json(path: str | Path, payload: dict[str, Any]) -> Path:
    p = rp(path)
    p.parent.mkdir(parents=True, exist_ok=True)
    p.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
    return p


def sha256_hex(path: str | Path) -> str:
    p = rp(path)
    return hashlib.sha256(p.read_bytes()).hexdigest()


def first_non_null(*values: Any) -> Any:
    for value in values:
        if value is not None:
            return value
    return None


def extract_hctx(payload: dict[str, Any]) -> dict[str, Any]:
    h_apex = payload.get("hApex")
    data_apex = ((payload.get("data") or {}).get("_harness_context")) if isinstance(payload.get("data"), dict) else None
    if isinstance(h_apex, dict) and isinstance(data_apex, dict):
        merged = dict(data_apex)
        merged.update(h_apex)
        return merged
    if isinstance(h_apex, dict):
        return h_apex
    if isinstance(data_apex, dict):
        return data_apex
    return payload if isinstance(payload, dict) else {}


def rows(v: Any) -> list[dict[str, Any]]:
    if isinstance(v, list):
        return [x for x in v if isinstance(x, dict)]
    if isinstance(v, str) and v.strip():
        try:
            parsed = json.loads(v)
            return rows(parsed)
        except Exception:
            return []
    if isinstance(v, dict):
        for key in ("rows", "data", "tickers", "items"):
            candidate = v.get(key)
            if isinstance(candidate, list):
                return [x for x in candidate if isinstance(x, dict)]
    return []


def temp_json(name: str) -> dict[str, Any]:
    return load_json(TEMP / name)
