"""
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