from django.core.management.base import BaseCommand
from django.contrib.auth.models import Group
from django.db import transaction

from apps.accounts.models import User
from apps.organizations.models import Hospital
from apps.px_sources.models import PXSource, SourceUser


class Command(BaseCommand):
    help = "Create E2E test users for Playwright testing - one per role"

    def add_arguments(self, parser):
        parser.add_argument("--password", default="Dev@123456", help="Password for test users")
        parser.add_argument("--delete-existing", action="store_true", help="Delete existing e2e test users first")
        parser.add_argument("--dry-run", action="store_true", help="Preview without making changes")

    def handle(self, *args, **options):
        password = options["password"]
        delete_existing = options["delete_existing"]
        dry_run = options["dry_run"]

        self.stdout.write(self.style.SUCCESS("\n=== Creating E2E Test Users ===\n"))

        if dry_run:
            self.stdout.write(self.style.WARNING("DRY RUN - No changes will be made\n"))

        with transaction.atomic():
            hospital = Hospital.objects.filter(code="NUZHA-DEV").first()
            if not hospital:
                self.stdout.write(self.style.ERROR("Hospital NUZHA-DEV not found. Run setup_dev_environment first."))
                return

            self.stdout.write(f"Using hospital: {hospital.name} ({hospital.code})")
            self.stdout.write(f"Password: {password}\n")

            px_source = None
            for source in PXSource.objects.filter(is_active=True):
                px_source = source
                break
            if not px_source:
                px_source = PXSource.objects.create(
                    code="E2E-TEST",
                    name_en="E2E Test Source",
                    name_ar="مصدر اختبار E2E",
                    source_type="internal",
                    contact_email="e2e@px360.test",
                    is_active=True,
                )
                self.stdout.write(f"  Created PXSource: {px_source.code}")

            users_config = [
                {
                    "email": "e2e-px-admin@px360.test",
                    "role": "PX Admin",
                    "first_name": "E2E",
                    "last_name": "PX Admin",
                    "hospital": None,
                    "is_staff": False,
                },
                {
                    "email": "e2e-hospital-admin@px360.test",
                    "role": "Hospital Admin",
                    "first_name": "E2E",
                    "last_name": "Hospital Admin",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-dept-manager@px360.test",
                    "role": "Department Manager",
                    "first_name": "E2E",
                    "last_name": "Dept Manager",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-px-employee@px360.test",
                    "role": "PX Employee",
                    "first_name": "E2E",
                    "last_name": "PX Employee",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-physician@px360.test",
                    "role": "Physician",
                    "first_name": "E2E",
                    "last_name": "Physician",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-nurse@px360.test",
                    "role": "Nurse",
                    "first_name": "E2E",
                    "last_name": "Nurse",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-staff@px360.test",
                    "role": "Staff",
                    "first_name": "E2E",
                    "last_name": "Staff",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-viewer@px360.test",
                    "role": "Viewer",
                    "first_name": "E2E",
                    "last_name": "Viewer",
                    "hospital": hospital,
                    "is_staff": False,
                },
                {
                    "email": "e2e-source-user@px360.test",
                    "role": "PX Source User",
                    "first_name": "E2E",
                    "last_name": "Source User",
                    "hospital": hospital,
                    "is_staff": False,
                    "create_source_profile": True,
                },
                {
                    "email": "e2e-champion@px360.test",
                    "role": "Department Manager",
                    "first_name": "E2E",
                    "last_name": "Champion",
                    "hospital": hospital,
                    "is_staff": False,
                    "is_champion": True,
                },
            ]

            if delete_existing and not dry_run:
                deleted = User.objects.filter(email__endswith="@px360.test").delete()
                self.stdout.write(f"  Deleted {deleted[0]} existing E2E users\n")

            created_count = 0
            for config in users_config:
                email = config["email"]
                role_name = config["role"]

                if dry_run:
                    self.stdout.write(f"  Would create: {email} ({role_name})")
                    if config.get("create_source_profile"):
                        self.stdout.write(f"    + SourceUser profile linked to {px_source.code}")
                    continue

                try:
                    group = Group.objects.get(name=role_name)
                except Group.DoesNotExist:
                    self.stdout.write(self.style.WARNING(f"  SKIP {email}: Group '{role_name}' not found"))
                    continue

                user, created = User.objects.get_or_create(
                    email=email,
                    defaults={
                        "first_name": config["first_name"],
                        "last_name": config["last_name"],
                        "hospital": config["hospital"],
                        "is_active": True,
                        "is_staff": config["is_staff"],
                    },
                )

                if created:
                    user.set_password(password)
                    created_count += 1
                    self.stdout.write(self.style.SUCCESS(f"  CREATED: {email} ({role_name})"))
                else:
                    user.groups.clear()
                    self.stdout.write(f"  EXISTS:  {email} ({role_name})")

                user.groups.add(group)
                user.save()

                if config.get("is_champion"):
                    from apps.organizations.models import Staff, Department
                    dept = Department.objects.filter(hospital=config["hospital"]).first()
                    if dept:
                        champion_staff, _ = Staff.objects.get_or_create(
                            user=user,
                            defaults={
                                "first_name": user.first_name,
                                "last_name": user.last_name,
                                "hospital": config["hospital"],
                                "department": dept,
                                "status": "active",
                            },
                        )
                        dept.champion = champion_staff
                        dept.save(update_fields=["champion"])
                        user.department = dept
                        user.save(update_fields=["department"])
                        self.stdout.write(f"    + Set as champion for {dept.name}")

                if config.get("create_source_profile"):
                    _, created_su = SourceUser.objects.get_or_create(
                        user=user,
                        source=px_source,
                        defaults={"is_active": True, "hospital": hospital},
                    )
                    if not created_su:
                        SourceUser.objects.filter(user=user).update(hospital=hospital)
                    self.stdout.write(f"    + SourceUser profile ({px_source.code})")

            self.stdout.write(self.style.SUCCESS(f"\nDone. Created {created_count} new E2E test users."))
            self.stdout.write(f"Total E2E users: {User.objects.filter(email__endswith='@px360.test').count()}")
