from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.db import transaction

from core.models import Role, MenuPermission, UserProfile, WebsiteSettings


class Command(BaseCommand):
    help = "Buat dummy data core: roles, users quick login, dan WebsiteSettings"

    def add_arguments(self, parser):
        parser.add_argument(
            "--reset-passwords",
            action="store_true",
            help="Paksa set ulang password sesuai spesifikasi login.html",
        )

    def handle(self, *args, **options):
        reset_passwords = options.get("reset_passwords", False)

        with transaction.atomic():
            self._ensure_website_settings()
            roles_by_name = self._ensure_roles()
            view_menu_permissions = self._ensure_default_menu_permissions()
            users_created = self._ensure_quick_login_users(roles_by_name, view_menu_permissions, reset_passwords)

        self.stdout.write(self.style.SUCCESS(
            f"Selesai membuat dummy data core. Users dibuat/diperbarui: {users_created}"
        ))

    def _ensure_website_settings(self):
        WebsiteSettings.get_settings()
        self.stdout.write("WebsiteSettings siap.")

    def _ensure_roles(self):
        """Create all roles defined in Role.ROLE_CHOICES if missing."""
        roles_by_name = {}
        for name, display in Role.ROLE_CHOICES:
            role, _ = Role.objects.get_or_create(
                name=name,
                defaults={"display_name": display, "description": display, "is_active": True},
            )
            # Pastikan display_name terisi bila berubah
            if role.display_name != display:
                role.display_name = display
                role.save(update_fields=["display_name"])
            roles_by_name[name] = role
        self.stdout.write(f"Roles siap: {len(roles_by_name)}")
        return roles_by_name

    def _ensure_default_menu_permissions(self):
        """Ensure minimal 'view' MenuPermission for each module to make UI accessible."""
        view_perms = []
        for module, _label in MenuPermission.MODULE_CHOICES:
            codename = f"{module}.view"
            perm, _ = MenuPermission.objects.get_or_create(
                module=module,
                action="view",
                defaults={
                    "name": f"{module} - view",
                    "description": f"Izin melihat modul {module}",
                    "codename": codename,
                    "is_active": True,
                },
            )
            view_perms.append(perm)
        self.stdout.write(f"MenuPermission (view) siap: {len(view_perms)}")
        return view_perms

    def _ensure_quick_login_users(self, roles_by_name, view_menu_permissions, reset_passwords):
        """Create/update users per login.html quick buttons and assign roles."""
        User = get_user_model()

        # username -> {roles: [...], password: str, flags}
        mappings = {
            # Admin level
            "superadmin": {
                "roles": ["super_admin", "admin"],
                "password": "admin123",
                "is_superuser": True,
                "is_staff": True,
            },
            "admin": {
                "roles": ["admin"],
                "password": "admin123",
                "is_superuser": False,
                "is_staff": True,
            },
            # Manager level
            "datamanager": {"roles": ["data_manager"], "password": "password123", "is_staff": True},
            "beneficiarymanager": {"roles": ["beneficiary_manager"], "password": "password123", "is_staff": True},
            "businessmanager": {"roles": ["business_manager"], "password": "password123", "is_staff": True},
            "complaintmanager": {"roles": ["complaint_manager"], "password": "password123", "is_staff": True},
            "documentmanager": {"roles": ["document_manager"], "password": "password123", "is_staff": True},
            "tourismmanager": {"roles": ["tourism_manager"], "password": "password123", "is_staff": True},
            "posyandummanager": {"roles": ["posyandu_manager"], "password": "password123", "is_staff": True},
            "newsmanager": {"roles": ["news_manager"], "password": "password123", "is_staff": True},
            "villageprofilemanager": {"roles": ["village_profile_manager"], "password": "password123", "is_staff": True},
            "organizationmanager": {"roles": ["organization_manager"], "password": "password123", "is_staff": True},
            # Organization specific
            "karangtarunamanager": {"roles": ["karang_taruna_manager"], "password": "password123", "is_staff": True},
            "kepemudaanmanager": {"roles": ["kepemudaan_manager"], "password": "password123", "is_staff": True},
            "pkkmanager": {"roles": ["pkk_manager"], "password": "password123", "is_staff": True},
            "lembagaadatmanager": {"roles": ["lembaga_adat_manager"], "password": "password123", "is_staff": True},
            "perangkatdesamanager": {"roles": ["perangkat_desa_manager"], "password": "password123", "is_staff": True},
            # User level
            "reportsviewer": {"roles": ["viewer"], "password": "password123", "is_staff": False},
            "dataentry": {"roles": ["village_staff"], "password": "password123", "is_staff": False},
            "viewer": {"roles": ["viewer"], "password": "password123", "is_staff": False},
        }

        created_or_updated = 0
        for username, cfg in mappings.items():
            user, created = User.objects.get_or_create(
                username=username,
                defaults={
                    "email": f"{username}@example.com",
                    "first_name": username.capitalize(),
                    "last_name": "User",
                    "is_staff": cfg.get("is_staff", False),
                    "is_superuser": cfg.get("is_superuser", False),
                },
            )

            # Update staff/superuser flags if changed
            updated_flags = False
            if user.is_staff != cfg.get("is_staff", False):
                user.is_staff = cfg.get("is_staff", False)
                updated_flags = True
            if user.is_superuser != cfg.get("is_superuser", False):
                user.is_superuser = cfg.get("is_superuser", False)
                updated_flags = True
            if updated_flags:
                user.save(update_fields=["is_staff", "is_superuser"])

            # Set or reset password if newly created or requested
            if created or reset_passwords:
                user.set_password(cfg["password"])
                user.save(update_fields=["password"])

            # Ensure profile exists
            UserProfile.objects.get_or_create(user=user)

            # Assign roles
            desired_roles = [roles_by_name[r] for r in cfg["roles"] if r in roles_by_name]
            user.roles.set(desired_roles)

            # Grant minimal menu permissions to all assigned roles (view only)
            for role in desired_roles:
                role.menu_permissions.add(*view_menu_permissions)

            created_or_updated += 1

        return created_or_updated


