import uuid

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


SETTING_NAME = "clinical_rotation_scheduling_enabled"


def seed_clinical_rotation_gate(apps, schema_editor):
    tt_setting = apps.get_model("api", "TtSetting")
    tt_setting.objects.get_or_create(
        param=SETTING_NAME,
        defaults={
            "value": "0",
            "comment": "Default-off gate for isolated clinical rotation scheduling",
        },
    )


def remove_clinical_rotation_gate(apps, schema_editor):
    tt_setting = apps.get_model("api", "TtSetting")
    tt_setting.objects.filter(param=SETTING_NAME, value="0").delete()


class Migration(migrations.Migration):
    dependencies = [
        ("api", "0108_add_tt_student_set_student_to_import_tables"),
    ]

    operations = [
        migrations.CreateModel(
            name="ClinicalRotationPlan",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("plan_id", models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
                ("deployment_scope", models.CharField(max_length=190)),
                ("session_id", models.CharField(max_length=255)),
                ("preview_operation_id", models.UUIDField()),
                ("status", models.CharField(choices=[("preview_pending", "Preview pending"), ("preview_ready", "Preview ready"), ("preview_infeasible", "Preview infeasible"), ("commit_pending", "Commit pending"), ("sync_pending", "Sync pending"), ("committed", "Committed"), ("stale", "Stale"), ("failed", "Failed"), ("expired", "Expired")], default="preview_pending", max_length=32)),
                ("revision", models.PositiveIntegerField(default=1)),
                ("normalized_request", models.JSONField(default=dict)),
                ("request_hash", models.CharField(max_length=71)),
                ("effective_constraint_setting", models.JSONField(default=dict)),
                ("constraint_breaking_mode", models.BooleanField(default=False)),
                ("input_fingerprint", models.CharField(max_length=71)),
                ("clinical_input_snapshot_id", models.CharField(max_length=190)),
                ("snapshot_content_hash", models.CharField(max_length=71)),
                ("clinical_input_snapshot", models.JSONField(default=dict)),
                ("preview_request_id", models.UUIDField(blank=True, null=True)),
                ("commit_request_id", models.UUIDField(blank=True, null=True)),
                ("engine_preview_token", models.TextField(blank=True, null=True)),
                ("engine_state_version", models.CharField(blank=True, max_length=255, null=True)),
                ("preview_hash", models.CharField(blank=True, max_length=71, null=True)),
                ("preview_result", models.JSONField(blank=True, null=True)),
                ("commit_result", models.JSONField(blank=True, null=True)),
                ("failure", models.JSONField(blank=True, null=True)),
                ("expires_at", models.DateTimeField()),
                ("confirmed_at", models.DateTimeField(blank=True, null=True)),
                ("committed_at", models.DateTimeField(blank=True, null=True)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("academic_term", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="api.ttacademicterm")),
                ("created_by", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="clinical_rotation_plans", to=settings.AUTH_USER_MODEL)),
                ("module", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="api.ttmodule")),
            ],
            options={"db_table": "clinical_rotation_plan"},
        ),
        migrations.CreateModel(
            name="ClinicalRotationPlanItem",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("round_index", models.PositiveIntegerField()),
                ("start_slot", models.IntegerField(blank=True, null=True)),
                ("end_slot_exclusive", models.IntegerField(blank=True, null=True)),
                ("staff_ids", models.JSONField(default=list)),
                ("location_ids", models.JSONField(default=list)),
                ("allocation_snapshot", models.JSONField(default=dict)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("activity", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="api.ttactivity")),
                ("activity_template", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="api.ttactivitytemplate")),
                ("plan", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name="items", to="api.clinicalrotationplan")),
                ("student_set", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to="api.ttstudentset")),
            ],
            options={"db_table": "clinical_rotation_plan_item", "ordering": ["round_index", "student_set_id"]},
        ),
        migrations.CreateModel(
            name="ClinicalRotationLeaseHandoff",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("plan_revision", models.PositiveIntegerField()),
                ("reservation_id", models.CharField(max_length=190, unique=True)),
                ("encrypted_lease_credential", models.TextField()),
                ("backend_key_version", models.CharField(max_length=64)),
                ("engine_key_version", models.CharField(max_length=64)),
                ("credential_digest", models.CharField(max_length=71)),
                ("canonical_members", models.JSONField(default=list)),
                ("lease_soft_expires_at", models.DateTimeField()),
                ("lease_soft_expires_at_text", models.CharField(max_length=64)),
                ("lease_state", models.CharField(choices=[("active", "Active"), ("release_pending", "Release pending"), ("released", "Released"), ("finalize_pending", "Finalize pending"), ("finalized", "Finalized")], default="active", max_length=32)),
                ("apply_state", models.CharField(choices=[("apply_pending", "Apply pending"), ("applied_sync_pending", "Applied, sync pending"), ("failed", "Failed")], default="apply_pending", max_length=32)),
                ("sync_state", models.CharField(default="pending", max_length=32)),
                ("sync_receipt_digest", models.CharField(blank=True, max_length=71, null=True)),
                ("response_digest", models.CharField(max_length=71)),
                ("response_status", models.CharField(default="claimed", max_length=32)),
                ("release_delivery_id", models.UUIDField(blank=True, null=True)),
                ("release_state", models.CharField(blank=True, max_length=32, null=True)),
                ("finalize_delivery_id", models.UUIDField(blank=True, null=True)),
                ("finalize_state", models.CharField(blank=True, max_length=32, null=True)),
                ("retry_count", models.PositiveIntegerField(default=0)),
                ("next_retry_at", models.DateTimeField(blank=True, db_index=True, null=True)),
                ("last_error_code", models.CharField(blank=True, max_length=120, null=True)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("plan", models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name="lease_handoff", to="api.clinicalrotationplan")),
            ],
            options={"db_table": "clinical_rotation_lease_handoff"},
        ),
        migrations.CreateModel(
            name="ClinicalRotationDelivery",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("delivery_id", models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
                ("plan_revision", models.PositiveIntegerField()),
                ("method", models.CharField(choices=[("clinical_rotation_preview", "Preview"), ("clinical_rotation_schedule", "Schedule"), ("clinical_rotation_release", "Release"), ("clinical_rotation_finalize", "Finalize"), ("clinical_rotation_schedule_reconcile", "Schedule reconcile")], max_length=64)),
                ("correlation_id", models.CharField(max_length=190)),
                ("request_digest", models.CharField(max_length=71)),
                ("status", models.CharField(choices=[("pending", "Pending"), ("publishing", "Publishing"), ("published", "Published"), ("retry", "Retry"), ("schedule_reconcile_required", "Schedule reconcile required"), ("failed", "Failed"), ("terminal", "Terminal receipt")], db_index=True, default="pending", max_length=40)),
                ("socket_id", models.CharField(blank=True, max_length=190, null=True)),
                ("attempts", models.PositiveIntegerField(default=0)),
                ("next_attempt_at", models.DateTimeField(blank=True, db_index=True, null=True)),
                ("claimed_at", models.DateTimeField(blank=True, null=True)),
                ("published_at", models.DateTimeField(blank=True, null=True)),
                ("last_error_code", models.CharField(blank=True, max_length=120, null=True)),
                ("created_at", models.DateTimeField(auto_now_add=True, db_index=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("handoff", models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name="deliveries", to="api.clinicalrotationleasehandoff")),
                ("plan", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="deliveries", to="api.clinicalrotationplan")),
            ],
            options={"db_table": "clinical_rotation_delivery"},
        ),
        migrations.CreateModel(
            name="ClinicalRotationResponseReceipt",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("request_id", models.CharField(max_length=190, unique=True)),
                ("response_id", models.CharField(max_length=190, unique=True)),
                ("method", models.CharField(max_length=64)),
                ("response_digest", models.CharField(max_length=71)),
                ("outcome", models.CharField(max_length=64)),
                ("sanitized_metadata", models.JSONField(default=dict)),
                ("topic", models.CharField(blank=True, max_length=255, null=True)),
                ("partition", models.IntegerField(blank=True, null=True)),
                ("offset", models.BigIntegerField(blank=True, null=True)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
            ],
            options={"db_table": "clinical_rotation_response_receipt"},
        ),
        migrations.CreateModel(
            name="ClinicalRotationSyncReceipt",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("plan_revision", models.PositiveIntegerField()),
                ("authoritative_generation", models.CharField(max_length=190)),
                ("canonical_readback_digest", models.CharField(max_length=71)),
                ("generation_evidence", models.JSONField(default=dict)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("plan", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="sync_receipts", to="api.clinicalrotationplan")),
            ],
            options={"db_table": "clinical_rotation_sync_receipt"},
        ),
        migrations.CreateModel(
            name="ClinicalRotationQuarantine",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("quarantine_id", models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
                ("fingerprint", models.CharField(max_length=71, unique=True)),
                ("request_id", models.CharField(blank=True, db_index=True, max_length=190, null=True)),
                ("response_digest", models.CharField(max_length=71)),
                ("reason", models.CharField(db_index=True, max_length=120)),
                ("sanitized_metadata", models.JSONField(default=dict)),
                ("encrypted_body", models.TextField(blank=True, null=True)),
                ("encryption_key_version", models.CharField(blank=True, max_length=64, null=True)),
                ("occurrences", models.PositiveIntegerField(default=1)),
                ("first_seen_at", models.DateTimeField(auto_now_add=True)),
                ("last_seen_at", models.DateTimeField(auto_now=True)),
            ],
            options={"db_table": "clinical_rotation_quarantine"},
        ),
        migrations.AddConstraint(model_name="clinicalrotationplan", constraint=models.UniqueConstraint(fields=("deployment_scope", "created_by", "preview_operation_id"), name="uq_cr_plan_preview_operation")),
        migrations.AddConstraint(model_name="clinicalrotationplan", constraint=models.CheckConstraint(condition=models.Q(("constraint_breaking_mode", False)), name="ck_cr_plan_breaking_false")),
        migrations.AddIndex(model_name="clinicalrotationplan", index=models.Index(fields=["status", "expires_at"], name="ix_cr_plan_status_exp")),
        migrations.AddIndex(model_name="clinicalrotationplan", index=models.Index(fields=["academic_term", "status"], name="ix_cr_plan_term_status")),
        migrations.AddConstraint(model_name="clinicalrotationplanitem", constraint=models.UniqueConstraint(fields=("plan", "activity"), name="uq_cr_item_plan_activity")),
        migrations.AddConstraint(model_name="clinicalrotationplanitem", constraint=models.UniqueConstraint(fields=("plan", "round_index", "student_set"), name="uq_cr_item_round_set")),
        migrations.AddConstraint(model_name="clinicalrotationplanitem", constraint=models.UniqueConstraint(fields=("plan", "round_index", "activity_template"), name="uq_cr_item_round_template")),
        migrations.AddConstraint(model_name="clinicalrotationleasehandoff", constraint=models.UniqueConstraint(fields=("plan", "plan_revision"), name="uq_cr_handoff_plan_revision")),
        migrations.AddConstraint(model_name="clinicalrotationdelivery", constraint=models.UniqueConstraint(fields=("plan", "plan_revision", "method"), name="uq_cr_delivery_plan_method")),
        migrations.AddIndex(model_name="clinicalrotationdelivery", index=models.Index(fields=["status", "next_attempt_at", "created_at"], name="ix_cr_delivery_eligible")),
        migrations.AddConstraint(model_name="clinicalrotationsyncreceipt", constraint=models.UniqueConstraint(fields=("plan", "plan_revision", "authoritative_generation"), name="uq_cr_sync_plan_generation")),
        migrations.RunPython(seed_clinical_rotation_gate, remove_clinical_rotation_gate),
    ]
