"""S5-S6: Model Roles registry checks."""

import json
import os
import re

from recoil_checks import register_check


def check_model_roles_valid(base, discovered):
    """S5: model_roles.json is valid JSON and every generation model exists in model_profiles."""
    passes, fails, warns = [], [], []
    roles_path = os.path.join(base, "config", "model_roles.json")
    profiles_path = os.path.join(base, "config", "model_profiles.json")

    if not os.path.isfile(roles_path):
        fails.append("model_roles.json not found")
        return {"pass": passes, "fail": fails, "warn": warns}

    try:
        with open(roles_path) as f:
            roles = json.load(f)
    except json.JSONDecodeError as e:
        fails.append(f"model_roles.json invalid JSON: {e}")
        return {"pass": passes, "fail": fails, "warn": warns}

    passes.append("model_roles.json valid JSON")

    # Load model_profiles for cross-check
    profile_ids = set()
    if os.path.isfile(profiles_path):
        try:
            with open(profiles_path) as f:
                profile_ids = set(json.load(f).keys())
        except json.JSONDecodeError:
            warns.append("Cannot cross-check — model_profiles.json parse error")

    # Check that image/video model IDs exist in model_profiles
    # (text, tts, qc models use different APIs and aren't in model_profiles)
    gen_categories = {"image", "video"}

    for cat_name, cat_data in roles.items():
        if cat_name.startswith("_") or not isinstance(cat_data, dict):
            continue
        for role, model_id in cat_data.items():
            if cat_name in gen_categories and profile_ids:
                if model_id in profile_ids:
                    passes.append(f"{cat_name}.{role} ({model_id}) in model_profiles")
                else:
                    fails.append(f"{cat_name}.{role} ({model_id}) NOT in model_profiles")
            else:
                passes.append(f"{cat_name}.{role}: {model_id}")

    return {"pass": passes, "fail": fails, "warn": warns}


def check_model_roles_freshness(base, discovered):
    """S6: No model IDs contain date-stamped preview suffixes older than 90 days."""
    passes, fails, warns = [], [], []
    roles_path = os.path.join(base, "config", "model_roles.json")

    if not os.path.isfile(roles_path):
        warns.append("model_roles.json not found — skipping freshness check")
        return {"pass": passes, "fail": fails, "warn": warns}

    try:
        with open(roles_path) as f:
            roles = json.load(f)
    except json.JSONDecodeError:
        warns.append("Cannot check freshness — JSON parse error")
        return {"pass": passes, "fail": fails, "warn": warns}

    from datetime import datetime, timedelta
    now = datetime.now()
    cutoff = now - timedelta(days=90)

    # Pattern: model-name-preview-MM-DD or model-name-preview-YYYY-MM-DD
    date_pattern = re.compile(r"preview-(\d{2,4})-(\d{2})(?:-(\d{2}))?$")

    stale_count = 0
    for cat_name, cat_data in roles.items():
        if cat_name.startswith("_") or not isinstance(cat_data, dict):
            continue
        for role, model_id in cat_data.items():
            match = date_pattern.search(model_id)
            if match:
                groups = match.groups()
                try:
                    if groups[2]:  # YYYY-MM-DD
                        year = int(groups[0])
                        month = int(groups[1])
                        day = int(groups[2])
                    else:  # MM-DD (assume current year, or last year if future)
                        month = int(groups[0])
                        day = int(groups[1])
                        year = now.year
                        candidate = datetime(year, month, day)
                        if candidate > now:
                            year -= 1

                    model_date = datetime(year, month, day)
                    if model_date < cutoff:
                        warns.append(
                            f"{cat_name}.{role}: {model_id} has date stamp "
                            f"{model_date.strftime('%Y-%m-%d')} (>{90} days old)"
                        )
                        stale_count += 1
                    else:
                        passes.append(f"{cat_name}.{role}: {model_id} date stamp is fresh")
                except (ValueError, OverflowError):
                    warns.append(f"{cat_name}.{role}: {model_id} has unparseable date suffix")

    if stale_count == 0:
        passes.append("No stale date-stamped preview models found")

    return {"pass": passes, "fail": fails, "warn": warns}


register_check("s5_model_roles_valid", "Model Roles Registry", check_model_roles_valid, section="api", quick=True)
register_check("s6_model_roles_freshness", "Model Roles Freshness", check_model_roles_freshness, section="api", quick=True)
