"""
JSON-LD @context and URI strategy for the StatFYI ontology.

Defines the shared @context used by all JSON-LD emitters/parsers, and
URI builder functions for concepts, fields, and schemes.
"""

from __future__ import annotations

import os

DEFAULT_BASE_URI = "https://statfyi.com/ontology/"

_base_uri: str | None = None


def get_base_uri() -> str:
    """Return the ontology base URI (env override or default)."""
    global _base_uri
    if _base_uri is None:
        _base_uri = os.environ.get("PYCHARTER_ONTOLOGY_BASE_URI", DEFAULT_BASE_URI)
        if not _base_uri.endswith("/"):
            _base_uri += "/"
    return _base_uri


def set_base_uri(uri: str) -> None:
    """Override the base URI at runtime (e.g. from ``scheme.base_uri``)."""
    global _base_uri
    _base_uri = uri if uri.endswith("/") else uri + "/"


def concept_uri(concept_id: str) -> str:
    """Build a concept URI: ``{base}concept/{ConceptId}``."""
    return f"{get_base_uri()}concept/{concept_id}"


def field_uri(contract_id: str, field_name: str) -> str:
    """Build a field URI: ``{base}contract/{contract}/field/{field}``."""
    return f"{get_base_uri()}contract/{contract_id}/field/{field_name}"


def scheme_uri(scheme_id: str) -> str:
    """Build a scheme URI: ``{base}scheme/{scheme_id}``."""
    return f"{get_base_uri()}scheme/{scheme_id}"


# ── Shared @context ──────────────────────────────────────────────────────────

JSONLD_CONTEXT: dict = {
    # Standard vocabularies
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "dct": "http://purl.org/dc/terms/",
    "prov": "http://www.w3.org/ns/prov#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    # Custom namespace
    "statfyi": DEFAULT_BASE_URI,
    # ── Concept-level aliases ────────────────────────────────────────────
    "prefLabel": "skos:prefLabel",
    "altLabel": "skos:altLabel",
    "definition": "skos:definition",
    "broader": {"@id": "skos:broader", "@type": "@id"},
    "narrower": {"@id": "skos:narrower", "@type": "@id"},
    "notation": "skos:notation",
    "example": "skos:example",
    "exactMatch": {"@id": "skos:exactMatch", "@type": "@id"},
    "deprecated": {"@id": "owl:deprecated", "@type": "xsd:boolean"},
    "isReplacedBy": {"@id": "dct:isReplacedBy", "@type": "@id"},
    "versionInfo": "owl:versionInfo",
    "inScheme": {"@id": "skos:inScheme", "@type": "@id"},
    # ── Field-mapping aliases ────────────────────────────────────────────
    "mapsTo": {"@id": "statfyi:mapsTo", "@type": "@id"},
    "tag": "statfyi:tag",
    "creator": "dct:creator",
    "description": "dct:description",
    "wasDerivedFrom": {"@id": "prov:wasDerivedFrom", "@type": "@id"},
    "wasGeneratedBy": "prov:wasGeneratedBy",
    # ── Relationship predicates (W3C-mapped) ─────────────────────────────
    "hasPart": {"@id": "dct:hasPart", "@type": "@id"},
    "isPartOf": {"@id": "dct:isPartOf", "@type": "@id"},
    "related": {"@id": "skos:related", "@type": "@id"},
    # ── Relationship predicates (legacy / custom) ──────────────────────
    "references": {"@id": "statfyi:references", "@type": "@id"},
    "derivedFrom": {"@id": "statfyi:derivedFrom", "@type": "@id"},
    "sameAs": {"@id": "statfyi:sameAs", "@type": "@id"},
    "relatedTo": {"@id": "statfyi:relatedTo", "@type": "@id"},
    # ── Knowledge schema predicates (custom) ───────────────────────────
    "dependsOn": {"@id": "statfyi:dependsOn", "@type": "@id"},
    "precedes": {"@id": "statfyi:precedes", "@type": "@id"},
    "causes": {"@id": "statfyi:causes", "@type": "@id"},
    "implements": {"@id": "statfyi:implements", "@type": "@id"},
    "governs": {"@id": "statfyi:governs", "@type": "@id"},
    "describes": {"@id": "statfyi:describes", "@type": "@id"},
    "equivalentTo": {"@id": "statfyi:equivalentTo", "@type": "@id"},
    # ── Node classification ────────────────────────────────────────────
    "nodeKind": "statfyi:nodeKind",
}
