from __future__ import annotations

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth import get_user_model

from orgs.models import Organization, UserProfile


class Command(BaseCommand):
    help = "Bind an existing user to an Organization by creating or updating UserProfile."

    def add_arguments(self, parser):
        parser.add_argument(
            "--user",
            required=True,
            help="User identifier: username (default), email, or numeric ID",
        )
        parser.add_argument(
            "--org",
            required=True,
            help="Organization identifier: code (preferred) or numeric ID",
        )
        parser.add_argument(
            "--role",
            default=UserProfile.ROLE_MANAGER,
            choices=[c[0] for c in UserProfile.ROLE_CHOICES],
            help="Role to assign in the profile (default: manager)",
        )
        parser.add_argument(
            "--staff",
            action="store_true",
            help="Also mark the user as staff for web admin access",
        )

    def handle(self, *args, **options):
        user_ident: str = options["user"]
        org_ident: str = options["org"]
        role: str = options["role"]
        mark_staff: bool = bool(options.get("staff", False))

        U = get_user_model()

        # Resolve user by id, username, or email
        user = None
        if user_ident.isdigit():
            user = U.objects.filter(pk=int(user_ident)).first()
        if user is None:
            user = U.objects.filter(username=user_ident).first()
        if user is None:
            user = U.objects.filter(email__iexact=user_ident).first()
        if user is None:
            raise CommandError(f"User not found by id/username/email: {user_ident}")

        # Resolve organization by id or code (or name as fallback)
        org = None
        if org_ident.isdigit():
            org = Organization.objects.filter(pk=int(org_ident)).first()
        if org is None:
            org = Organization.objects.filter(code=org_ident).first()
        if org is None:
            org = Organization.objects.filter(name=org_ident).first()
        if org is None:
            raise CommandError(f"Organization not found by code/id/name: {org_ident}")

        # Create/update profile
        profile, created = UserProfile.objects.update_or_create(
            user=user,
            defaults={
                "organization": org,
                "role": role,
            },
        )

        if mark_staff and not user.is_staff:
            user.is_staff = True
            user.save(update_fields=["is_staff"])

        msg_act = "Created" if created else "Updated"
        staff_note = " (staff)" if user.is_staff else ""
        self.stdout.write(
            self.style.SUCCESS(
                f"{msg_act} profile: user={user.username} -> org={org.code} role={role}{staff_note}"
            )
        )
