import django.db.models.deletion
from django.db import migrations, models


def consolidate_department_roles(apps, schema_editor):
    """Department names are employee metadata, not capability roles.

    Earlier installations may contain roles named ``Dept. <name>``. Move those
    assignments to one Researcher capability role so the RBAC editor reflects
    the product model without dropping the affected users' organization links.
    The old role rows are archived rather than deleted so an operator can
    inspect or restore their original permission bundles if needed.
    """
    Role = apps.get_model("core", "Role")
    UserRole = apps.get_model("core", "UserRole")
    Permission = apps.get_model("core", "Permission")
    Invitation = apps.get_model("core", "Invitation")

    legacy_roles = list(Role.objects.filter(name__istartswith="Dept. "))
    if not legacy_roles:
        return

    researcher = Role.objects.filter(slug="researcher").first()
    if researcher is None:
        researcher = Role.objects.filter(name__iexact="Researcher").first()
    if researcher is None:
        researcher = Role.objects.create(
            name="Researcher",
            slug="researcher",
            description="Research staff with personal work and request-tracking access.",
            is_system=True,
        )

    if not researcher.permissions.exists():
        staff = Role.objects.filter(slug="staff").first()
        if staff is not None:
            researcher.permissions.set(staff.permissions.all())
        else:
            baseline = [
                ("project", "view"),
                ("events", "view"),
                ("meetings", "view"),
                ("tasks", "view"),
                ("tasks", "create"),
                ("phonebook", "view"),
                ("publications", "view"),
                ("procurements", "view"),
                ("procurements", "create"),
                ("administrations", "view"),
                ("administrations", "create"),
            ]
            permission_ids = [
                permission.pk
                for permission in Permission.objects.all()
                if (permission.domain, permission.action) in baseline
            ]
            researcher.permissions.set(permission_ids)

    for legacy_role in legacy_roles:
        for assignment in UserRole.objects.filter(role=legacy_role):
            UserRole.objects.get_or_create(
                user_id=assignment.user_id,
                role=researcher,
                organization_id=assignment.organization_id,
                defaults={"assigned_by_id": assignment.assigned_by_id},
            )
        Invitation.objects.filter(role=legacy_role).update(role=researcher)
        UserRole.objects.filter(role=legacy_role).delete()
        legacy_role.name = f"Archived: {legacy_role.name}"[:80]
        legacy_role.slug = f"archived-{legacy_role.slug}"[:80]
        legacy_role.is_system = False
        legacy_role.save(update_fields=["name", "slug", "is_system"])


class Migration(migrations.Migration):
    dependencies = [("core", "0015_invitation_donor_role_user_donor_role")]

    operations = [
        migrations.AddField(
            model_name="role",
            name="manager_role",
            field=models.ForeignKey(
                blank=True,
                help_text="Optional role responsible for approvals and reporting for holders of this role.",
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name="managed_roles",
                to="core.role",
            ),
        ),
        migrations.RunPython(consolidate_department_roles, migrations.RunPython.noop),
    ]
