# Generated by Django 4.2.9 on 2024-02-07 15:58
from contextlib import suppress

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


def assign_hedged_currency(apps, schema_editor):
    Product = apps.get_model("wbportfolio", "Product")
    InstrumentPortfolioThroughModel = apps.get_model("wbportfolio", "InstrumentPortfolioThroughModel")

    for product in Product.objects.filter(index_hedged_currency__isnull=False).distinct():
        for rel in InstrumentPortfolioThroughModel.objects.filter(instrument_id=product.instrument_ptr_id):
            portfolio = rel.portfolio
            portfolio.hedged_currency = product.index_hedged_currency
            portfolio.save()


def modify_portfolio(apps, schema_editor):
    Portfolio = apps.get_model("wbportfolio", "Portfolio")
    PortfolioPortfolioThroughModel = apps.get_model("wbportfolio", "PortfolioPortfolioThroughModel")
    InstrumentPortfolioThroughModel = apps.get_model("wbportfolio", "InstrumentPortfolioThroughModel")
    TradeProposal = apps.get_model("wbportfolio", "TradeProposal")
    Transaction = apps.get_model("wbportfolio", "Transaction")
    Instrument = apps.get_model("wbfdm", "Instrument")
    Portfolio.objects.filter(portfolio_type="MODEL").update(is_manageable=True)
    PortfolioPortfolioThroughModel.objects.filter(is_primary=True).update(type="PRIMARY")
    PortfolioPortfolioThroughModel.objects.filter(is_theme=True).delete()
    for instrument in Instrument.objects.filter(portfolios__isnull=False).distinct():
        with suppress(InstrumentPortfolioThroughModel.DoesNotExist):
            assert_portfolio = InstrumentPortfolioThroughModel.objects.get(
                instrument=instrument, asset_portfolio=True
            ).portfolio
            primary_portfolio_rel = InstrumentPortfolioThroughModel.objects.get(
                instrument=instrument, primary_portfolio=True
            )
            if assert_portfolio != primary_portfolio_rel.portfolio:
                try:
                    primary_relationship = PortfolioPortfolioThroughModel.objects.get(
                        portfolio=assert_portfolio, type="PRIMARY"
                    )
                except PortfolioPortfolioThroughModel.DoesNotExist:
                    primary_relationship = PortfolioPortfolioThroughModel.objects.create(
                        portfolio=assert_portfolio,
                        dependency_portfolio=primary_portfolio_rel.portfolio,
                        type="PRIMARY",
                    )
                if primary_portfolio_rel.portfolio != primary_relationship.dependency_portfolio:
                    if not primary_portfolio_rel.portfolio.assets.exists():
                        pass
                    else:
                        last_date = primary_portfolio_rel.portfolio.assets.latest("date").date
                        if (
                            primary_portfolio_rel.portfolio.assets.exclude(underlying_instrument__is_cash=True).filter(
                                date=last_date
                            )
                        ).count() == 1:
                            primary_relationship.dependency_portfolio = primary_portfolio_rel.portfolio
                            primary_relationship.save()
                        else:
                            raise ValueError("cannot be here")
                Transaction.objects.filter(portfolio=primary_portfolio_rel.portfolio).update(
                    portfolio=assert_portfolio
                )
                primary_portfolio_rel.delete()
        if InstrumentPortfolioThroughModel.objects.filter(instrument=instrument).count() > 1:
            InstrumentPortfolioThroughModel.objects.filter(
                instrument=instrument, primary_portfolio=False, asset_portfolio=False
            ).delete()
    for p in Portfolio.objects.filter(assets__isnull=True, transactions__isnull=True):
        TradeProposal.objects.filter(model_portfolio=p).update(model_portfolio=models.F("portfolio"))
        p.delete()

    for rel in InstrumentPortfolioThroughModel.objects.filter(model_portfolio=True):
        with suppress(InstrumentPortfolioThroughModel.DoesNotExist):
            asset_portfolio = InstrumentPortfolioThroughModel.objects.get(
                instrument=rel.instrument, asset_portfolio=True
            ).portfolio
            if assert_portfolio != rel.portfolio:
                PortfolioPortfolioThroughModel.objects.update_or_create(
                    portfolio=asset_portfolio, dependency_portfolio=rel.portfolio, defaults={"type": "MODEL"}
                )
    # Cleanup


class Migration(migrations.Migration):
    dependencies = [
        ("wbfdm", "0012_instrumentprice_created_instrumentprice_modified"),
        ("currency", "0001_initial"),
        ("wbportfolio", "0053_remove_product_group"),
    ]

    operations = [
        migrations.RenameModel(
            old_name="PortfolioInstrumentPreferedClassificationThroughModel",
            new_name="PortfolioInstrumentPreferredClassificationThroughModel",
        ),
        migrations.RenameField(
            model_name="portfolio",
            old_name="prefered_instrument_classifications",
            new_name="preferred_instrument_classifications",
        ),
        migrations.AddField(
            model_name="portfolio",
            name="hedged_currency",
            field=models.ForeignKey(
                blank=True,
                help_text="The hedged currency of the portfolio.",
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="hedged_portfolios",
                to="currency.currency",
                verbose_name="Hedged Currency",
            ),
        ),
        migrations.AddField(
            model_name="portfolio",
            name="is_manageable",
            field=models.BooleanField(default=False),
        ),
        migrations.AddField(
            model_name="portfolioportfoliothroughmodel",
            name="type",
            field=models.CharField(
                choices=[("PRIMARY", "Primary"), ("MODEL", "Model"), ("BENCHMARK", "Benchmark")],
                default="PRIMARY",
                verbose_name="Type",
            ),
        ),
        migrations.RunSQL(
            sql="SET CONSTRAINTS ALL IMMEDIATE;",
        ),
        migrations.RunPython(assign_hedged_currency),
        migrations.RunPython(modify_portfolio),
        migrations.RunSQL(
            sql="SET CONSTRAINTS ALL DEFERRED;",
        ),
        migrations.RemoveField(
            model_name="instrumentportfoliothroughmodel",
            name="base_instrument",
        ),
        migrations.RemoveField(
            model_name="instrumentportfoliothroughmodel",
            name="model_portfolio",
        ),
        migrations.RemoveField(
            model_name="portfolio",
            name="portfolio_type",
        ),
        migrations.RemoveField(
            model_name="portfolioportfoliothroughmodel",
            name="is_primary",
        ),
        migrations.RemoveField(
            model_name="portfolioportfoliothroughmodel",
            name="is_theme",
        ),
        migrations.RemoveField(
            model_name="product",
            name="index_hedged_currency",
        ),
        migrations.RemoveField(
            model_name="instrumentportfoliothroughmodel",
            name="asset_portfolio",
        ),
        migrations.RemoveField(
            model_name="instrumentportfoliothroughmodel",
            name="primary_portfolio",
        ),
        migrations.AlterField(
            model_name="instrumentportfoliothroughmodel",
            name="instrument",
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE, related_name="through_portfolios", to="wbfdm.instrument"
            ),
        ),
        migrations.AlterField(
            model_name="portfolio",
            name="instruments",
            field=models.ManyToManyField(
                blank=True,
                help_text="Instruments linked to this instrument",
                related_name="portfolios",
                through="wbportfolio.InstrumentPortfolioThroughModel",
                to="wbfdm.instrument",
                verbose_name="Instruments",
            ),
        ),
        migrations.AlterField(
            model_name="portfolio",
            name="preferred_instrument_classifications",
            field=models.ManyToManyField(
                blank=True,
                limit_choices_to=models.Q(("instrument_type__is_classifiable", True)),
                related_name="preferred_portfolio_classifications",
                through="wbportfolio.PortfolioInstrumentPreferredClassificationThroughModel",
                to="wbfdm.instrument",
                verbose_name="The Preferred classification per instrument",
            ),
        ),
        migrations.AlterField(
            model_name="portfolioinstrumentpreferredclassificationthroughmodel",
            name="classification",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name="preferred_classification_throughs",
                to="wbfdm.classification",
            ),
        ),
        migrations.AlterField(
            model_name="portfolioinstrumentpreferredclassificationthroughmodel",
            name="classification_group",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name="preferred_classification_group_throughs",
                to="wbfdm.classificationgroup",
            ),
        ),
        migrations.AlterField(
            model_name="portfolioinstrumentpreferredclassificationthroughmodel",
            name="instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("instrument_type__is_classifiable", True)),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="preferred_classification_portfolio",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="portfolioinstrumentpreferredclassificationthroughmodel",
            name="portfolio",
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                related_name="preferred_classification_instruments",
                to="wbportfolio.portfolio",
            ),
        ),
        migrations.AddConstraint(
            model_name="portfolioportfoliothroughmodel",
            constraint=models.UniqueConstraint(
                condition=models.Q(("type", "ACTUAL")), fields=("portfolio", "type"), name="unique_actual"
            ),
        ),
        migrations.AddConstraint(
            model_name="portfolioportfoliothroughmodel",
            constraint=models.UniqueConstraint(
                condition=models.Q(("type", "MODEL")), fields=("portfolio", "type"), name="unique_model"
            ),
        ),
        migrations.AddConstraint(
            model_name="portfolioportfoliothroughmodel",
            constraint=models.UniqueConstraint(
                condition=models.Q(("type", "BENCHMARK")), fields=("portfolio", "type"), name="unique_benchmark"
            ),
        ),
        migrations.AddConstraint(
            model_name="instrumentportfoliothroughmodel",
            constraint=models.UniqueConstraint(fields=("instrument",), name="unique_instrument"),
        ),
        migrations.AddConstraint(
            model_name="instrumentportfoliothroughmodel",
            constraint=models.UniqueConstraint(
                fields=("instrument", "portfolio"), name="unique_portfolio_relationship"
            ),
        ),
    ]
