# Generated by Django 4.2.8 on 2023-12-22 07:36

from contextlib import suppress

import django.db.models.deletion
from django.apps import apps as django_apps
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.management import create_contenttypes
from django.contrib.contenttypes.models import ContentType
from django.db import migrations, models
from django.utils import timezone
from wbcore.contrib.io.models import ImportedObjectProviderRelationship

InstrumentTypeMap = {
    "ADR": ("american_depository_receipt", "American Depository Receipt (ADR)"),
    "CF": ("close_ended_fund", "Close Ended Fund"),
    "MutualFund": ("mutual_fund", "Mutual Fund"),
    "EQ": ("equity", "Equity"),
    "Equity": ("equity", "Equity"),
    "PrivateEquity": ("private_equity", "Private Equity"),
    "ETF": ("exchange_traded_fund", "Exchange Traded Fund"),
    "ETC": ("exchange_traded_commodity", "Exchange Traded Commodity"),
    "ETP": ("exchange_traded_product", "Exchange Traded Product"),
    "ETN": ("exchange_traded_note", "Exchange Traded Note"),
    "WARRANT": ("warrant", "Warrant"),
    "GDR": ("global_depository_receipt", "Global Depository Receipt (GDR)"),
    "GS": ("genussschein", "Genussschein"),
    "TRUST": ("investment_trust", "Investment Trust"),
    "NVDR": ("non_voting_depository_receipt", "Non-voting depository receipt (NVDR)"),
    "PREF": ("preference_share", "Preference Share"),
    "COMP": ("company", "Company"),
    "QT": ("quote", "Quote"),
    "Product": ("product", "Product"),
    "Index": ("index", "Index"),
    "ProductGroup": ("product_group", "Product Group"),
    "Cash": ("cash", "Cash"),
    "InterestRateDerivative": ("interest_rate_derivative", "Interest Rate Derivative"),
}


def migrate_instrument_type(apps, schema_editor):
    Instrument = apps.get_model("wbfdm", "Instrument")
    InstrumentType = apps.get_model("wbfdm", "InstrumentType")
    for old_instrument_type, (instrument_type_key, instrument_type_label) in InstrumentTypeMap.items():
        label_splits = instrument_type_label.split(" ")
        short_name = (
            "".join(word[0].upper() for word in label_splits) if len(label_splits) > 1 else instrument_type_label
        )
        instrument_type = InstrumentType.objects.get_or_create(
            key=instrument_type_key, defaults={"name": instrument_type_label, "short_name": short_name}
        )[0]
        Instrument.objects.filter(old_instrument_type=old_instrument_type).update(instrument_type=instrument_type)


def migrate_bbg_code(apps, _schema_editor):
    Exchange = apps.get_model("wbfdm", "Exchange")
    for exchange in Exchange.objects.all():
        exchange.bbg_exchange_codes = [exchange.bbg_exchange]
        exchange.save()


def post_migrate_script(apps, schema_editor):
    from wbcore.contrib.authentication.models import User

    Instrument = apps.get_model("wbfdm", "Instrument")

    # apps.get_model("wbfdm", "InstrumentPrice").objects.update(created=models.F("date"))
    # ensure content type are created at this point
    create_contenttypes(django_apps.get_app_config("wbfdm"))

    # move old permission to new permission
    for old_permission in Permission.objects.filter(content_type__app_label="wbportfolio"):
        with suppress(Permission.DoesNotExist, ContentType.DoesNotExist):
            new_permission = Permission.objects.get(
                codename=old_permission.codename.replace("wbportfolio", "wbfdm"),
                content_type=ContentType.objects.get(app_label="wbfdm", model=old_permission.content_type.model),
            )
            for user in User.objects.filter(user_permissions=old_permission):
                user.user_permissions.remove(old_permission)
                user.user_permissions.add(new_permission)
            for group in Group.objects.filter(permissions=old_permission):
                group.permissions.remove(old_permission)
                group.permissions.add(new_permission)

    for cb_insight_rel in ImportedObjectProviderRelationship.objects.filter(
        content_type__model="equity", provider__key="cbinsights"
    ):
        with suppress(Instrument.DoesNotExist):
            instrument = Instrument.objects.get(id=cb_insight_rel.object_id)
            instrument.source = "cbinsights"
            instrument.source_id = cb_insight_rel.provider_identifier
            instrument.save()

    for refinitiv_insight_rel in ImportedObjectProviderRelationship.objects.filter(
        content_type__model="instrument", provider__key="refinitiv"
    ):
        with suppress(Instrument.DoesNotExist):
            instrument = Instrument.objects.get(id=refinitiv_insight_rel.object_id)
            instrument.source = "refinitiv"
            instrument.source_id = refinitiv_insight_rel.provider_identifier
            instrument.save()

    InstrumentLookup = apps.get_model("wbfdm", "InstrumentLookup")
    for rel in InstrumentLookup.objects.filter(
        backend_path="wbfdm.contrib.dsws.backends.market_data.DSWSMarketDataBackend"
    ):
        try:
            instrument = Instrument.objects.get(id=rel.pms_instrument_id)
            instrument.dl_parameters = {
                "market_data": {
                    "path": "wbfdm.contrib.dsws.dataloaders.market_data.DSWSMarketDataDataloader",
                    "parameters": {
                        "identifier": rel.identifier,
                        "price_symbol": rel.parameters.get("market_data", "P"),
                    },
                },
            }
            instrument.source = "dsws"
            instrument.source_id = rel.identifier
            instrument.save()
        except Exception:
            pass


class Migration(migrations.Migration):
    dependencies = [
        ("geography", "0001_initial"),
        ("wbfdm", "0011_delete_instrumentlookup_instrument_corporate_actions_and_more"),
    ]

    operations = [
        migrations.AddField(
            model_name="instrument",
            name="dl_parameters",
            field=models.JSONField(blank=True, default=dict),
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="adjustments",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="corporate_actions",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="dividends",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="esg",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="esg_controversies",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="financials",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="market_data",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="officers",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="statements",
        ),
        migrations.CreateModel(
            name="InstrumentType",
            fields=[
                ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
                ("name", models.CharField(max_length=128, verbose_name="Name")),
                ("short_name", models.CharField(max_length=128, verbose_name="Short Name")),
                ("key", models.CharField(max_length=32, verbose_name="Key", unique=True)),
                ("description", models.TextField(verbose_name="Description")),
            ],
            options={
                "abstract": False,
            },
        ),
        migrations.AlterField(
            model_name="exchange",
            name="city",
            field=models.ForeignKey(
                blank=True,
                help_text="The city where this Exchange is located at.",
                limit_choices_to={"level": 3},
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="exchanges",
                to="geography.geography",
                verbose_name="City",
            ),
        ),
        migrations.RenameField(
            model_name="instrument",
            old_name="instrument_type",
            new_name="old_instrument_type",
        ),
        migrations.AddField(
            model_name="instrument",
            name="instrument_type",
            field=models.ForeignKey(
                default=None,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="instruments",
                to="wbfdm.instrumenttype",
                blank=True,
                null=True,
            ),
            preserve_default=False,
        ),
        migrations.RemoveField(
            model_name="instrumentrequest",
            name="instrument_type",
        ),
        migrations.RunPython(migrate_instrument_type),
        migrations.RemoveField(model_name="instrument", name="old_instrument_type"),
        migrations.AlterField(
            model_name="instrument",
            name="instrument_type",
            field=models.ForeignKey(
                default=None,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="instruments",
                to="wbfdm.instrumenttype",
            ),
            preserve_default=False,
        ),
        migrations.CreateModel(
            name="Equity",
            fields=[],
            options={
                "proxy": True,
                "indexes": [],
                "constraints": [],
            },
            bases=("wbfdm.instrument",),
        ),
        migrations.AddField(
            model_name="instrumentprice",
            name="created",
            field=models.DateTimeField(auto_now_add=True, default=timezone.now(), verbose_name="Created"),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name="instrumentprice",
            name="modified",
            field=models.DateTimeField(auto_now=True, verbose_name="Modified"),
        ),
        migrations.RunPython(post_migrate_script),
        migrations.RemoveField(
            model_name="instrumentlookup",
            name="instrument",
        ),
        migrations.DeleteModel(
            name="InstrumentLookup",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="level",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="lft",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="rght",
        ),
        migrations.RemoveField(
            model_name="instrument",
            name="tree_id",
        ),
        migrations.AddField(
            model_name="exchange",
            name="last_updated",
            field=models.DateTimeField(auto_now=True),
        ),
        migrations.AddField(
            model_name="instrument",
            name="employees",
            field=models.IntegerField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="instrument",
            name="is_security",
            field=models.BooleanField(default=False),
        ),
        migrations.AddField(
            model_name="instrument",
            name="last_annual_report",
            field=models.DateField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="instrument",
            name="last_interim_report",
            field=models.DateField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="instrument",
            name="next_annual_report",
            field=models.DateField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="instrument",
            name="next_interim_report",
            field=models.DateField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name="instrumenttype",
            name="is_classifiable",
            field=models.BooleanField(default=True, verbose_name="Classifiable"),
        ),
        migrations.AddField(
            model_name="instrumenttype",
            name="is_security",
            field=models.BooleanField(default=True, verbose_name="Security"),
        ),
        migrations.AlterField(
            model_name="controversy",
            name="instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("instrument_type__is_security", True)),
                on_delete=django.db.models.deletion.CASCADE,
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="deal",
            name="equity",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("instrument_type__key", "equity")),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="deals",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="alternative_names",
            field=django.contrib.postgres.fields.ArrayField(
                base_field=models.CharField(blank=True, max_length=255, null=True), blank=True, default=list, size=None
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="description",
            field=models.TextField(blank=True, default="", null=True),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="exchange",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="instruments",
                to="wbfdm.exchange",
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="instrument_type",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="instruments",
                to="wbfdm.instrumenttype",
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="isin",
            field=models.CharField(
                blank=True, help_text="The ISIN provided by the bank.", max_length=12, null=True, verbose_name="ISIN"
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="parent",
            field=models.ForeignKey(
                blank=True,
                null=True,
                on_delete=django.db.models.deletion.CASCADE,
                related_name="children",
                to="wbfdm.instrument",
                verbose_name="Parent Instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="refinitiv_identifier_code",
            field=models.CharField(
                blank=True, help_text="Refinitiv Identifier Code", max_length=255, null=True, verbose_name="RIC"
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="refinitiv_mnemonic_code",
            field=models.CharField(
                blank=True,
                help_text="Refinitiv Datastream Mnemonic Code",
                max_length=255,
                null=True,
                verbose_name="Refinitiv Datastream Mnemonic Code",
            ),
        ),
        migrations.AlterField(
            model_name="instrument",
            name="refinitiv_ticker",
            field=models.CharField(
                blank=True, help_text="Refinitiv Refinitiv", max_length=255, null=True, verbose_name="Refinitiv Ticker"
            ),
        ),
        migrations.AlterField(
            model_name="instrumentclassificationrelatedinstrument",
            name="classified_instrument",
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                related_name="classification_instrument_relationships",
                to="wbfdm.instrumentclassificationthroughmodel",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentclassificationrelatedinstrument",
            name="related_instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("instrument_type__is_classifiable", True)),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="instrument_classification_related",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentclassificationthroughmodel",
            name="instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("instrument_type__is_classifiable", True)),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="classifications_through",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentclassificationthroughmodel",
            name="related_instruments",
            field=models.ManyToManyField(
                blank=True,
                limit_choices_to=models.Q(("instrument_type__is_classifiable", True)),
                through="wbfdm.InstrumentClassificationRelatedInstrument",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentfavoritegroup",
            name="instruments",
            field=models.ManyToManyField(
                blank=True,
                limit_choices_to=models.Q(("children__isnull", True)),
                related_name="favorite_groups",
                to="wbfdm.instrument",
                verbose_name="Favorite Instruments Group",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentlistthroughmodel",
            name="instrument",
            field=models.ForeignKey(
                blank=True,
                limit_choices_to=models.Q(("instrument_type__is_security", True)),
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentprice",
            name="instrument",
            field=models.ForeignKey(
                blank=True,
                limit_choices_to=models.Q(("children__isnull", True)),
                null=True,
                on_delete=django.db.models.deletion.PROTECT,
                related_name="prices",
                to="wbfdm.instrument",
                verbose_name="Instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumenttype",
            name="description",
            field=models.TextField(blank=True, verbose_name="Description"),
        ),
        migrations.AlterField(
            model_name="relatedinstrumentthroughmodel",
            name="instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("children__isnull", True)),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="related_instruments_through",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="relatedinstrumentthroughmodel",
            name="related_instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("children__isnull", True)),
                on_delete=django.db.models.deletion.CASCADE,
                related_name="dependent_instruments_through",
                to="wbfdm.instrument",
            ),
        ),
        migrations.AddConstraint(
            model_name="exchange",
            constraint=models.UniqueConstraint(fields=("source", "source_id"), name="unique_exchange_source"),
        ),
        migrations.AddField(
            model_name="exchange",
            name="bbg_exchange_codes",
            field=django.contrib.postgres.fields.ArrayField(
                base_field=models.CharField(max_length=4),
                blank=True,
                default=list,
                help_text="Bloomberg Exchange Code.",
                size=None,
                verbose_name="BBG Exchange Code",
            ),
        ),
        migrations.RunPython(migrate_bbg_code),
        migrations.RemoveField(model_name="exchange", name="bbg_exchange"),
        migrations.AddField(
            model_name="instrument",
            name="is_managed",
            field=models.BooleanField(default=False),
        ),
        migrations.AlterField(
            model_name="controversy",
            name="instrument",
            field=models.ForeignKey(
                limit_choices_to=models.Q(("is_security", True)),
                on_delete=django.db.models.deletion.CASCADE,
                to="wbfdm.instrument",
            ),
        ),
        migrations.AlterField(
            model_name="instrumentlistthroughmodel",
            name="instrument",
            field=models.ForeignKey(
                blank=True,
                limit_choices_to=models.Q(("is_security", True)),
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                to="wbfdm.instrument",
            ),
        ),
    ]
