from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def _iso(ts: datetime | None) -> str:
    dt = ts or datetime.now(timezone.utc)
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return dt.astimezone(timezone.utc).isoformat()


def append_journal_event(
    journal_path: str | Path,
    *,
    event_type: str,
    coin: str,
    side: str,
    price: float,
    size: float,
    dry_run: bool,
    reason: str = "",
    realized_pnl_usd: float = 0.0,
    ts: datetime | None = None,
    extra: dict[str, Any] | None = None,
) -> dict[str, Any]:
    path = Path(journal_path).expanduser()
    path.parent.mkdir(parents=True, exist_ok=True)
    event: dict[str, Any] = {
        "ts": _iso(ts),
        "event_type": event_type,
        "coin": coin.upper(),
        "side": side,
        "price": float(price),
        "size": float(size),
        "dry_run": bool(dry_run),
        "reason": reason,
        "realized_pnl_usd": float(realized_pnl_usd),
    }
    if extra:
        event["extra"] = extra
    with path.open("a", encoding="utf-8") as f:
        f.write(json.dumps(event, sort_keys=True) + "\n")
    return event


def read_journal_events(journal_path: str | Path) -> list[dict[str, Any]]:
    path = Path(journal_path).expanduser()
    if not path.exists():
        return []
    events = []
    with path.open("r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line:
                events.append(json.loads(line))
    return events
