"""
Sprint point capacity: per-user weekly story point capacity.

PyGitWeb has no database, so this follows the same JSON-file pattern as
auth_config.py and settings_config.py: persisted at ~/.pygitweb/capacity.json
(or PYGITWEB_CAPACITY_CONFIG).
"""

from __future__ import annotations

import json
import os
from datetime import date
from pathlib import Path

from pydantic import BaseModel, Field

DEFAULT_CAPACITY_CONFIG_PATH = Path.home() / ".pygitweb" / "capacity.json"
DEFAULT_WEEKLY_CAPACITY_POINTS = 20


def capacity_config_path() -> Path:
    explicit = os.environ.get("PYGITWEB_CAPACITY_CONFIG", "").strip()
    if explicit:
        return Path(explicit).expanduser()
    return DEFAULT_CAPACITY_CONFIG_PATH


def iso_week_key(d: date) -> str:
    """ISO week identifier, e.g. 2026-W38."""
    year, week, _ = d.isocalendar()
    return f"{year:04d}-W{week:02d}"


def current_iso_week() -> str:
    return iso_week_key(date.today())


class UserCapacity(BaseModel):
    default_points: int = DEFAULT_WEEKLY_CAPACITY_POINTS
    weeks: dict[str, int] = Field(default_factory=dict)


class CapacityConfig(BaseModel):
    users: dict[str, UserCapacity] = Field(default_factory=dict)


def load_capacity_config() -> CapacityConfig:
    path = capacity_config_path()
    if not path.is_file():
        return CapacityConfig()
    try:
        return CapacityConfig.model_validate_json(path.read_text(encoding="utf-8"))
    except ValueError:
        return CapacityConfig()


def write_capacity_config(config: CapacityConfig) -> None:
    path = capacity_config_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(config.model_dump(mode="json"), indent=2) + "\n", encoding="utf-8")


def get_user_week_capacity(username: str, iso_week: str) -> int:
    """Points capacity for a user in a given ISO week (falls back to their default, then the global default)."""
    config = load_capacity_config()
    user = config.users.get(username)
    if user is None:
        return DEFAULT_WEEKLY_CAPACITY_POINTS
    return user.weeks.get(iso_week, user.default_points)


def set_user_week_capacity(username: str, iso_week: str, points: int) -> CapacityConfig:
    config = load_capacity_config()
    user = config.users.get(username) or UserCapacity()
    user.weeks[iso_week] = points
    config.users[username] = user
    write_capacity_config(config)
    return config