"""`python manage.py run_seeds` — run all .seeds/*.py scripts idempotently.

Discovery:
  - Scans backend/.seeds/ for *.py files in sorted order
  - Each file may define seed() and/or seed_for_tenant(tenant)
  - seed()              runs once (platform-level)
  - seed_for_tenant()   runs once per active Tenant

Usage:
  python manage.py run_seeds
  python manage.py run_seeds --tenant momenin
  python manage.py run_seeds --dry-run
"""

from __future__ import annotations

import importlib.util
import sys
from pathlib import Path
from typing import Any

from django.core.management.base import BaseCommand, CommandError
from django.db import transaction


SEEDS_DIR = Path(__file__).resolve().parent.parent.parent.parent.parent / ".seeds"


def _load_seed_module(path: Path) -> Any:
    spec = importlib.util.spec_from_file_location(path.stem, path)
    if spec is None or spec.loader is None:
        raise CommandError(f"Cannot load seed file: {path}")
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


class Command(BaseCommand):
    help = "Run all .seeds/*.py scripts idempotently (platform + per-tenant)."

    def add_arguments(self, parser):
        parser.add_argument(
            "--tenant",
            dest="tenant_slug",
            default=None,
            help="Run seeds only for a specific tenant slug.",
        )
        parser.add_argument(
            "--dry-run",
            action="store_true",
            default=False,
            help="List seeds that would run without executing them.",
        )

    @transaction.atomic
    def handle(self, *args: object, **options: object) -> None:
        dry_run: bool = options["dry_run"]
        tenant_slug: str | None = options["tenant_slug"]

        if not SEEDS_DIR.exists():
            self.stdout.write(self.style.WARNING(f"Seeds directory not found: {SEEDS_DIR}"))
            return

        seed_files = sorted(SEEDS_DIR.glob("*.py"))
        if not seed_files:
            self.stdout.write(self.style.NOTICE("No seed files found."))
            return

        from simorgh.apps.tenants.models import Tenant, TenantStatus

        if tenant_slug:
            tenants = list(Tenant.objects.filter(slug=tenant_slug, status=TenantStatus.ACTIVE))
            if not tenants:
                raise CommandError(f"Active tenant with slug {tenant_slug!r} not found.")
        else:
            tenants = list(Tenant.objects.filter(status=TenantStatus.ACTIVE))

        for seed_path in seed_files:
            self.stdout.write(f"\n  Seed: {seed_path.name}")
            if dry_run:
                self.stdout.write(self.style.NOTICE("    [dry-run] skipping"))
                continue

            mod = _load_seed_module(seed_path)
            has_global = hasattr(mod, "seed")
            has_tenant = hasattr(mod, "seed_for_tenant")

            if has_global:
                try:
                    mod.seed()
                    self.stdout.write(self.style.SUCCESS("    [global] OK"))
                except Exception as exc:
                    self.stdout.write(self.style.ERROR(f"    [global] FAILED: {exc}"))
                    raise

            if has_tenant:
                for tenant in tenants:
                    try:
                        mod.seed_for_tenant(tenant)
                        self.stdout.write(self.style.SUCCESS(f"    [{tenant.slug}] OK"))
                    except Exception as exc:
                        self.stdout.write(self.style.ERROR(f"    [{tenant.slug}] FAILED: {exc}"))
                        raise

            if not has_global and not has_tenant:
                self.stdout.write(self.style.WARNING(
                    "    No seed() or seed_for_tenant() found — skipping"
                ))

        self.stdout.write("")
        self.stdout.write(self.style.SUCCESS("Seeds complete."))
