"""
Brand Registry Service
- Stores Theme Packs (theme.json + assets refs)
- Serves immutable theme versions by brand_id
"""

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Any, Dict, Optional
from datetime import datetime
import json
import logging
import os
import uuid
from pathlib import Path

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

DATA_DIR = Path(os.getenv("BRAND_REGISTRY_DATA", "/data/brand-registry"))
THEMES_DIR = DATA_DIR / "brands"

app = FastAPI(
    title="Brand Registry Service",
    description="Single source of truth for brand themes",
    version="0.1.0"
)


class ThemePublishRequest(BaseModel):
    theme: Dict[str, Any]
    theme_version: Optional[str] = None
    metadata: Optional[Dict[str, Any]] = None


class ThemeResponse(BaseModel):
    brand_id: str
    theme_version: str
    theme: Dict[str, Any]
    metadata: Optional[Dict[str, Any]] = None
    created_at: str


def _ensure_dirs() -> None:
    THEMES_DIR.mkdir(parents=True, exist_ok=True)


def _theme_path(brand_id: str, theme_version: str) -> Path:
    return THEMES_DIR / brand_id / "themes" / theme_version / "theme.json"


def _meta_path(brand_id: str, theme_version: str) -> Path:
    return THEMES_DIR / brand_id / "themes" / theme_version / "meta.json"


def _list_versions(brand_id: str) -> list:
    base = THEMES_DIR / brand_id / "themes"
    if not base.exists():
        return []
    versions = [p.name for p in base.iterdir() if p.is_dir()]
    return sorted(versions)


@app.get("/")
async def root() -> Dict[str, Any]:
    _ensure_dirs()
    return {
        "service": "brand-registry",
        "status": "running",
        "data_dir": str(DATA_DIR),
        "version": "0.1.0"
    }


@app.get("/health")
async def health() -> Dict[str, Any]:
    _ensure_dirs()
    return {"status": "healthy"}


@app.post("/brands/{brand_id}/themes", response_model=ThemeResponse)
async def publish_theme(brand_id: str, payload: ThemePublishRequest) -> ThemeResponse:
    _ensure_dirs()
    theme_version = payload.theme_version or f"v1-{uuid.uuid4().hex[:8]}"
    theme_path = _theme_path(brand_id, theme_version)
    theme_path.parent.mkdir(parents=True, exist_ok=True)

    created_at = datetime.utcnow().isoformat() + "Z"
    meta = {
        "brand_id": brand_id,
        "theme_version": theme_version,
        "created_at": created_at,
        "metadata": payload.metadata or {}
    }

    theme_path.write_text(json.dumps(payload.theme, ensure_ascii=False, indent=2), encoding="utf-8")
    _meta_path(brand_id, theme_version).write_text(json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8")

    logger.info("Published theme: %s/%s", brand_id, theme_version)
    return ThemeResponse(
        brand_id=brand_id,
        theme_version=theme_version,
        theme=payload.theme,
        metadata=payload.metadata or {},
        created_at=created_at
    )


@app.get("/brands/{brand_id}/themes/{theme_version}", response_model=ThemeResponse)
async def get_theme(brand_id: str, theme_version: str) -> ThemeResponse:
    theme_path = _theme_path(brand_id, theme_version)
    if not theme_path.exists():
        raise HTTPException(status_code=404, detail="Theme not found")

    theme = json.loads(theme_path.read_text(encoding="utf-8"))
    meta_path = _meta_path(brand_id, theme_version)
    meta = json.loads(meta_path.read_text(encoding="utf-8")) if meta_path.exists() else {}

    return ThemeResponse(
        brand_id=brand_id,
        theme_version=theme_version,
        theme=theme,
        metadata=meta.get("metadata"),
        created_at=meta.get("created_at", "")
    )


@app.get("/brands/{brand_id}/latest", response_model=ThemeResponse)
async def get_latest(brand_id: str) -> ThemeResponse:
    versions = _list_versions(brand_id)
    if not versions:
        raise HTTPException(status_code=404, detail="No themes for brand")
    return await get_theme(brand_id, versions[-1])
