"""Artifact and registry projections produced during finalization."""

from __future__ import annotations

from datetime import date
from decimal import Decimal
from pathlib import Path

from checkin_cli.nutrition_onboarding_contract import canonical_digest
from checkin_cli.nutrition_onboarding_fs import atomic_write_private_json
from checkin_cli.nutrition_onboarding_models import NutritionOnboardingBaseline


def write_artifact(path: Path, document: dict[str, object]) -> dict[str, object]:
    payload = dict(document)
    payload["digest"] = canonical_digest(payload)
    atomic_write_private_json(path, payload)
    return payload


def optional_float(value: Decimal | None) -> float | None:
    return float(value) if value is not None else None


def registry_profile(baseline: NutritionOnboardingBaseline) -> dict[str, object]:
    restrictions = (
        *baseline.intolerances.items,
        *baseline.religious_ethical_exclusions.items,
    )
    return {
        "primary_goal": baseline.goal_type.value,
        "starting_context": "nutrition-onboarding-v1",
        "dietary_restrictions": list(restrictions),
        "allergies": list(baseline.allergies.items),
        "food_preferences": list(baseline.dietary_preferences.items),
        "disliked_foods": list(baseline.disliked_foods.items),
        "supplements": [],
        "cooking_access": baseline.cooking_access or None,
        "budget_band": baseline.budget_band or None,
        "meal_count": baseline.meal_count,
        "schedule_constraints": baseline.schedule_constraints or None,
        "training_context": baseline.activity_rationale or None,
    }


def registry_plan(plan: object, *, meal_count: int) -> dict[str, object]:
    return {
        "starts_on": plan.starts_on.isoformat(),
        "focus": "nutrition_90_training_10",
        "weeks": [
            {
                **week.model_dump(mode="json"),
                "meal_structure": [
                    f"식사 {index}" for index in range(1, meal_count + 1)
                ],
                "nutrition_focus": "승인된 열량·매크로 범위 준수",
            }
            for week in plan.weeks
        ],
    }


def adjustment_policy_document(
    baseline: NutritionOnboardingBaseline,
    *,
    starts_on: date,
    timestamp: str,
    owner_receipt: str,
) -> dict[str, object]:
    goal = baseline.goal_type.value
    desired_min = "-1.00" if goal == "loss" else "0.10" if goal == "gain" else "-0.25"
    desired_max = "-0.25" if goal == "loss" else "0.50" if goal == "gain" else "0.25"
    return {
        "schema_version": "1.0",
        "policy_version": "1.0",
        "effective_at_kst": timestamp,
        "effective_from": starts_on.isoformat(),
        "goal_mode": goal,
        "approved": True,
        "minimum_observation_days": 7,
        "minimum_current_samples": 4,
        "minimum_total_samples": 10,
        "minimum_adherent_days": 5,
        "weight_trend_method": "two_non_overlapping_seven_day_means",
        "adherence_inputs": ["calories", "meal_plan"],
        "actual_intake_inputs": ["calories"],
        "activity_change_inputs": ["training"],
        "adjustment_thresholds": {
            "minimum_current_samples": 4,
            "minimum_total_samples": 10,
            "minimum_adherent_days": 5,
            "goal_mode": goal,
        },
        "maximum_step_kcal": 100,
        "calorie_step": 100,
        "calorie_floor": 1500,
        "calorie_ceiling": 4500,
        "cooldown_days": 7,
        "desired_weekly_change_min": desired_min,
        "desired_weekly_change_max": desired_max,
        "safety_hold": False,
        "escalation_rules": ["contradictory_adherence", "safety_hold"],
        "safety_stop_rules": ["medical_review", "eating_disorder_risk"],
        "manual_override_receipt_required": True,
        "reviewed_by": owner_receipt,
    }
