import uuid

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

import training.constants


class Migration(migrations.Migration):
    dependencies = [
        ("players", "0003_player_form_morale_match_experience_engine"),
        ("seasons", "0003_season_competition_orchestration"),
        ("training", "0002_player_match_experience_development"),
    ]

    operations = [
        migrations.AddField(
            model_name="playerdevelopmentprogress",
            name="consumed_points",
            field=models.DecimalField(decimal_places=6, default="0.000000", max_digits=18),
        ),
        migrations.RemoveConstraint(
            model_name="playerdevelopmentprogress",
            name="development_points_nonnegative",
        ),
        migrations.AddConstraint(
            model_name="playerdevelopmentprogress",
            constraint=models.CheckConstraint(condition=Q(total_points__gte=0, consumed_points__gte=0), name="development_points_nonnegative"),
        ),
        migrations.AddConstraint(
            model_name="playerdevelopmentprogress",
            constraint=models.CheckConstraint(condition=Q(consumed_points__lte=F("total_points")), name="development_consumed_lte_total"),
        ),
        migrations.CreateModel(
            name="PlayerRatingMaterializationRun",
            fields=[
                ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ("trigger_type", models.CharField(choices=[("TRAINING", "Training session"), ("MATCH", "Match experience"), ("MANUAL", "Manual materialization"), ("SEASON_CREDIT", "Season-end credit sweep"), ("SEASON_END", "Season-end aging")], max_length=20)),
                ("source_reference", models.UUIDField(blank=True, null=True)),
                ("observed_on", models.DateField()),
                ("age_years", models.PositiveSmallIntegerField()),
                ("overall_before", models.PositiveSmallIntegerField()),
                ("overall_after", models.PositiveSmallIntegerField()),
                ("potential", models.PositiveSmallIntegerField()),
                ("total_credit_consumed", models.DecimalField(decimal_places=6, default="0.000000", max_digits=18)),
                ("retirement_eligible", models.BooleanField(default=False)),
                ("evidence_payload", models.JSONField()),
                ("evidence_hash", models.CharField(max_length=64)),
                ("policy_key", models.CharField(max_length=100)),
                ("policy_version", models.CharField(max_length=30)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("player", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="rating_materialization_runs", to="players.player")),
            ],
            options={"ordering": ["created_at", "player_id"]},
        ),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.UniqueConstraint(condition=Q(source_reference__isnull=False), fields=("player", "trigger_type", "source_reference"), name="uq_ratingmat_player_trigger_ref")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=Q(age_years__lte=100), name="ratingmat_age_lte_100")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=Q(overall_before__gte=1, overall_before__lte=100, overall_after__gte=1, overall_after__lte=100), name="ratingmat_overall_1_100")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=Q(potential__gte=1, potential__lte=100), name="ratingmat_potential_1_100")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=Q(overall_after__lte=F("potential")), name="ratingmat_overall_lte_potential")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=Q(total_credit_consumed__gte=0), name="ratingmat_credit_nonnegative")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=~Q(evidence_hash=""), name="ratingmat_hash_nonempty")),
        migrations.AddConstraint(model_name="playerratingmaterializationrun", constraint=models.CheckConstraint(condition=~Q(policy_key=""), name="ratingmat_policy_nonempty")),
        migrations.AddIndex(model_name="playerratingmaterializationrun", index=models.Index(fields=["player", "-created_at"], name="ratingmat_player_hist_idx")),
        migrations.AddIndex(model_name="playerratingmaterializationrun", index=models.Index(fields=["trigger_type", "observed_on"], name="ratingmat_trigger_date_idx")),
        migrations.CreateModel(
            name="PlayerAttributeRatingChange",
            fields=[
                ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ("attribute_name", models.CharField(max_length=40)),
                ("rating_before", models.PositiveSmallIntegerField()),
                ("rating_after", models.PositiveSmallIntegerField()),
                ("rating_delta", models.SmallIntegerField()),
                ("credit_available_before", models.DecimalField(decimal_places=6, default="0.000000", max_digits=18)),
                ("credit_consumed", models.DecimalField(decimal_places=6, default="0.000000", max_digits=18)),
                ("credit_available_after", models.DecimalField(decimal_places=6, default="0.000000", max_digits=18)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("run", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="attribute_changes", to="training.playerratingmaterializationrun")),
            ],
            options={"ordering": ["run_id", "attribute_name"]},
        ),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.UniqueConstraint(fields=("run", "attribute_name"), name="uq_ratingchange_run_attribute")),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.CheckConstraint(condition=Q(attribute_name__in=training.constants.TRAINABLE_PLAYER_ATTRIBUTES), name="ratingchange_valid_attribute")),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.CheckConstraint(condition=Q(rating_before__gte=1, rating_before__lte=100, rating_after__gte=1, rating_after__lte=100), name="ratingchange_rating_1_100")),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.CheckConstraint(condition=Q(rating_delta=F("rating_after") - F("rating_before")), name="ratingchange_delta_math")),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.CheckConstraint(condition=Q(credit_available_before__gte=0, credit_consumed__gte=0, credit_available_after__gte=0), name="ratingchange_credit_nonnegative")),
        migrations.AddConstraint(model_name="playerattributeratingchange", constraint=models.CheckConstraint(condition=Q(credit_consumed__lte=F("credit_available_before")), name="ratingchange_consumed_lte_available")),
        migrations.CreateModel(
            name="PlayerSeasonAgingResult",
            fields=[
                ("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ("age_years", models.PositiveSmallIntegerField()),
                ("base_decline_points", models.PositiveSmallIntegerField(default=0)),
                ("applied_decline_points", models.PositiveSmallIntegerField(default=0)),
                ("training_protection", models.DecimalField(decimal_places=4, default="0.0000", max_digits=6)),
                ("retirement_eligible", models.BooleanField(default=False)),
                ("evidence_payload", models.JSONField()),
                ("evidence_hash", models.CharField(max_length=64)),
                ("policy_key", models.CharField(max_length=100)),
                ("policy_version", models.CharField(max_length=30)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("materialization_run", models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name="aging_result", to="training.playerratingmaterializationrun")),
                ("player", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="season_aging_results", to="players.player")),
                ("season", models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name="player_aging_results", to="seasons.season")),
            ],
            options={"ordering": ["season_id", "player_id"]},
        ),
        migrations.AddConstraint(model_name="playerseasonagingresult", constraint=models.UniqueConstraint(fields=("player", "season"), name="uq_player_aging_season")),
        migrations.AddConstraint(model_name="playerseasonagingresult", constraint=models.CheckConstraint(condition=Q(age_years__lte=100), name="aging_age_lte_100")),
        migrations.AddConstraint(model_name="playerseasonagingresult", constraint=models.CheckConstraint(condition=Q(applied_decline_points__lte=F("base_decline_points")), name="aging_applied_lte_base")),
        migrations.AddConstraint(model_name="playerseasonagingresult", constraint=models.CheckConstraint(condition=Q(training_protection__gte=0, training_protection__lte=1), name="aging_protection_0_1")),
        migrations.AddConstraint(model_name="playerseasonagingresult", constraint=models.CheckConstraint(condition=~Q(evidence_hash=""), name="aging_hash_nonempty")),
        migrations.AddIndex(model_name="playerseasonagingresult", index=models.Index(fields=["season", "retirement_eligible"], name="aging_season_retire_idx")),
    ]
