"""
Management command to load default LLM models for common providers.

Usage:
    python manage.py load_default_llm_models
    python manage.py load_default_llm_models --force   # update existing models
"""

from decimal import Decimal

from django.core.management.base import BaseCommand

from llm_manager.models import LLMApi, LLMModel


DEFAULT_APIS = [
    {
        "name": "OpenAI",
        "api_type": "openai",
        "base_url": "https://api.openai.com/v1",
    },
]

DEFAULT_MODELS = [
    # ── Chat models ────────────────────────────────────────────────────
    {
        "api_name": "OpenAI",
        "name": "gpt-4o",
        "display_name": "GPT-4o",
        "model_type": "chat",
        "context_window": 128000,
        "max_output_tokens": 16384,
        "input_cost_per_1k": Decimal("0.0025"),
        "output_cost_per_1k": Decimal("0.01"),
        "supports_cache": True,
        "cached_cost_per_1k": Decimal("0.00125"),
        "supports_vision": True,
        "supports_function_calling": True,
        "supports_json_mode": True,
    },
    {
        "api_name": "OpenAI",
        "name": "gpt-4o-mini",
        "display_name": "GPT-4o Mini",
        "model_type": "chat",
        "context_window": 128000,
        "max_output_tokens": 16384,
        "input_cost_per_1k": Decimal("0.00015"),
        "output_cost_per_1k": Decimal("0.0006"),
        "supports_cache": True,
        "cached_cost_per_1k": Decimal("0.000075"),
        "supports_vision": True,
        "supports_function_calling": True,
        "supports_json_mode": True,
    },
    # ── Embedding models ───────────────────────────────────────────────
    {
        "api_name": "OpenAI",
        "name": "text-embedding-3-large",
        "display_name": "Text Embedding 3 Large",
        "model_type": "embedding",
        "context_window": 8191,
        "vector_dimensions": 3072,
        "input_cost_per_1k": Decimal("0.00013"),
        "output_cost_per_1k": Decimal("0"),
    },
    {
        "api_name": "OpenAI",
        "name": "text-embedding-3-small",
        "display_name": "Text Embedding 3 Small",
        "model_type": "embedding",
        "context_window": 8191,
        "vector_dimensions": 1536,
        "input_cost_per_1k": Decimal("0.00002"),
        "output_cost_per_1k": Decimal("0"),
    },
]


class Command(BaseCommand):
    help = "Load default LLM APIs and models."

    def add_arguments(self, parser):
        parser.add_argument(
            "--force",
            action="store_true",
            help="Update existing model records with defaults.",
        )

    def handle(self, *args, **options):
        force = options["force"]

        # Create default APIs
        api_map = {}
        for api_data in DEFAULT_APIS:
            api, created = LLMApi.objects.get_or_create(
                name=api_data["name"],
                defaults={
                    "api_type": api_data["api_type"],
                    "base_url": api_data["base_url"],
                    "is_active": True,
                },
            )
            api_map[api_data["name"]] = api
            if created:
                self.stdout.write(self.style.SUCCESS(f"Created API: {api.name}"))
            else:
                self.stdout.write(self.style.WARNING(f"API already exists: {api.name}"))

        # Create default models
        for model_data in DEFAULT_MODELS:
            api_name = model_data.pop("api_name")
            api = api_map.get(api_name)
            if not api:
                self.stdout.write(self.style.ERROR(f"API '{api_name}' not found, skipping model."))
                model_data["api_name"] = api_name  # restore
                continue

            defaults = {k: v for k, v in model_data.items() if k != "name"}
            model, created = LLMModel.objects.get_or_create(
                api=api,
                name=model_data["name"],
                defaults=defaults,
            )

            if created:
                self.stdout.write(self.style.SUCCESS(f"  Created model: {model.name}"))
            elif force:
                for key, val in defaults.items():
                    setattr(model, key, val)
                model.save()
                self.stdout.write(self.style.SUCCESS(f"  Updated model: {model.name}"))
            else:
                self.stdout.write(self.style.WARNING(f"  Model exists: {model.name}"))

            model_data["api_name"] = api_name  # restore

        self.stdout.write(self.style.SUCCESS("Default LLM models loaded."))
