"""asyncpg Record → JSON-serializovatelný dict + helper pro jsonb z fn_*."""

from __future__ import annotations

import json
from datetime import date, datetime, timezone
from decimal import Decimal
from typing import Any
from uuid import UUID

import asyncpg


def record_to_dict(r: asyncpg.Record) -> dict[str, Any]:
    out: dict[str, Any] = {}
    for k in r.keys():
        v = r[k]
        if v is None:
            out[k] = None
        elif isinstance(v, datetime):
            if v.tzinfo is None:
                v = v.replace(tzinfo=timezone.utc)
            out[k] = v.isoformat()
        elif isinstance(v, date):
            out[k] = v.isoformat()
        elif isinstance(v, Decimal):
            out[k] = float(v)
        elif isinstance(v, UUID):
            out[k] = str(v)
        elif isinstance(v, (dict, list, str, int, float, bool)):
            out[k] = v
        elif isinstance(v, (bytes, memoryview)):
            out[k] = bytes(v).decode("utf-8", errors="replace")
        else:
            out[k] = str(v)
    return out


async def fetch_json(conn: asyncpg.Connection, query: str, *args: Any) -> Any:
    """fetchval pro dotazy vracející jsonb (např. select ems.fn_*(...))."""
    v = await conn.fetchval(query, *args)
    if v is None:
        return None
    if isinstance(v, (dict, list)):
        return v
    if isinstance(v, (bytes, memoryview)):
        return json.loads(bytes(v).decode("utf-8"))
    if isinstance(v, str):
        return json.loads(v)
    return v
