from datetime import date
from typing import Dict, List, Tuple

from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.management import BaseCommand, CommandError
from django.db import transaction

from gaehsnitz.models import Drink, Consumption, Donation, Payment

User = get_user_model()


def user(name: str):
    obj, _ = User.objects.get_or_create(username=name)
    return obj


def donation(day, month, amount, note):
    return Donation.objects.create(
        date=date(2024, month, day),
        amount=amount,
        note=note,
    )


def payment(purpose, day, month, amount):
    return Payment.objects.create(
        date=date(2024, month, day),
        amount=amount,
        purpose=purpose,
    )


def consumption(day: int, for_free: bool, drink_dict: Dict[User, List[Tuple[int, Drink]]]):
    for user, drink_list in drink_dict.items():
        for amount, drink in drink_list:
            Consumption.objects.create(user=user, drink=drink, amount=amount, day=day, for_free=for_free)


class Command(BaseCommand):
    @transaction.atomic()
    def handle(self, *args, **options):
        if any(model.objects.exists() for model in [Donation, Payment, Drink, Consumption]):
            raise CommandError("clear all donation, payment, drink and consumption objects before running this command")

        # --------------- PEOPLE ---------------

        anonym = user("anonym")
        alexius = user("alexius")
        andrea = user("andrea")
        annemarie = user("annemarie")
        arthur = user("arthur")
        benni = user("benni")
        casi = user("casi")
        dennis = user("dennis")
        diana = user("diana")
        enni = user("enni")
        flo = user("flo")
        herald = user("herald")
        jona = user("jona")
        josi = user("josi")
        katha = user("katha")
        katz = user("katz")
        lena = user("lena")
        lilly = user("lilly")
        lukas = user("lukas")
        marius = user("marius")
        marten = user("marten")
        marvin = user("marvin")
        matze = user("matze")
        ohli = user("ohli")
        pauline = user("pauline")
        robert = user("robert")
        rockbert = user("rockbert")
        sandra = user("sandra")
        sepp = user("sepp")
        simon = user("simon")
        steven = user("steven")
        thure = user("thure")
        tobi = user("tobi")

        # --------------- DONATIONS ---------------

        donation(10, 6, 871, "Kasse")

        donation(6, 6, 50, "PayPal")
        donation(7, 6, 50, "persönlich")
        donation(9, 6, 62, "PayPal")
        donation(10, 6, 66.66, "PayPal")
        donation(10, 6, 60, "Überweisung")
        donation(11, 6, 45, "PayPal")
        donation(11, 6, 15, "PayPal")
        donation(11, 6, 15, "PayPal")
        donation(11, 6, 75, "PayPal")

        # --------------- PAYMENTS ---------------

        payment("Dixis", 3, 4, 331)
        payment("Holz und Lack", 7, 5, 125)
        payment("Getränke Anzahlung", 29, 5, 300)
        payment("PA", 6, 6, 300)
        payment("Drehstrom-Verteiler", 6, 6, 67)
        payment("Essen, Getränke, Kleinzeug", 7, 6, 104)
        payment("Dankeschön-Bier für Lichttechnik", 10, 6, 20)

        # --------------- DRINKS ---------------

        sterni = Drink.objects.create(
            name="Sterni",
            crates_ordered=16,
            crates_purchased=8,
            crates_returned=6,
            purchase_price_per_crate=8.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=1.50,
        )
        krosti = Drink.objects.create(
            name="Krosti",
            crates_ordered=10,
            crates_purchased=5,
            crates_returned=4,
            purchase_price_per_crate=15.49,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        radler = Drink.objects.create(
            name="Radler",
            crates_ordered=5,
            crates_purchased=2,
            crates_returned=2,
            purchase_price_per_crate=13.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        buddi = Drink.objects.create(
            name="Buddi alkfrei",
            crates_ordered=2,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=19.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        freiberger = Drink.objects.create(
            name="Freiberger alkfrei",
            crates_ordered=3,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=12.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        helles = Drink.objects.create(
            name="Altenburger Hell",
            crates_ordered=4,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=12.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        wasser = Drink.objects.create(
            name="Wasser",
            crates_ordered=10,
            crates_purchased=5,
            crates_returned=4,
            purchase_price_per_crate=4.99,
            deposit_per_crate=3.30,
            bottles_per_crate=12,
            bottle_size=1.0,
            sale_price_per_bottle=1.00,
        )
        mate = Drink.objects.create(
            name="Mate",
            crates_ordered=3,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=16.79,
            deposit_per_crate=4.50,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        cola = Drink.objects.create(
            name="Vita Cola",
            crates_ordered=2,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=10.99,
            deposit_per_crate=3.30,
            bottles_per_crate=12,
            bottle_size=1.0,
            sale_price_per_bottle=2.00,
        )
        spezi = Drink.objects.create(
            name="Spezi",
            crates_ordered=2,
            crates_purchased=1,
            crates_returned=1,
            purchase_price_per_crate=16.99,
            deposit_per_crate=3.10,
            bottles_per_crate=20,
            bottle_size=0.5,
            sale_price_per_bottle=2.00,
        )
        sekt = Drink.objects.create(
            name="Sekt / Mische",
            crates_ordered=5,
            crates_purchased=5,
            crates_returned=0,
            purchase_price_per_crate=4.99,
            deposit_per_crate=0,
            bottles_per_crate=3,
            bottle_size=0.25,
            sale_price_per_bottle=2.00,
        )

        # --------------- THURSDAY ---------------

        consumption(
            day=1,
            for_free=False,
            drink_dict={
                enni: [(2, wasser), (9, sterni)],
                robert: [(2, wasser), (2, freiberger), (1, spezi), (2, mate)],
                josi: [(5, sterni), (1, radler)],
                tobi: [(5, sterni), (1, freiberger), (2, mate)],
                annemarie: [(1, wasser), (4, sterni), (1, radler)],
                sandra: [(1, wasser), (3, sterni), (1, spezi), (1, mate)],
                flo: [(2, wasser), (5, sterni), (1, mate), (1, helles)],
            },
        )

        # --------------- FRIDAY ---------------

        consumption(
            day=2,
            for_free=False,
            drink_dict={
                tobi: [(2, wasser), (9, sterni), (2, freiberger)],
                annemarie: [(1, wasser), (5, sterni), (2, mate), (2, radler), (2, buddi), (3, sekt)],
                sandra: [(1, freiberger), (1, buddi), (1, spezi), (2, mate), (1, radler), (2, sekt)],
                robert: [(2, wasser), (1, freiberger), (1, buddi), (1, spezi)],
                josi: [(2, wasser), (6, sterni), (1, freiberger), (2, radler)],
                enni: [(2, wasser), (10, sterni), (1, spezi)],
                steven: [(1, sterni), (1, krosti), (1, radler), (5, helles)],
                marten: [(9, krosti)],
                thure: [(4, sterni)],
                jona: [(2, freiberger), (10, krosti)],
                benni: [(5, krosti), (1, helles)],
                katha: [(1, krosti), (1, mate)],
                diana: [(5, sterni), (1, radler)],
                katz: [(3, krosti), (1, buddi)],
                alexius: [(8, sterni)],
                pauline: [(5, sterni), (1, radler)],
                herald: [(1, wasser), (2, sterni), (1, freiberger)],
                arthur: [(6, sterni), (1, radler)],
                matze: [(1, sterni), (1, freiberger)],
                dennis: [(1, sterni), (2, krosti)],
                marvin: [(3, sterni), (1, krosti), (1, mate)],
                simon: [(1, sterni)],
            },
        )

        consumption(
            day=2,
            for_free=True,
            drink_dict={
                flo: [(2, wasser), (3, sterni), (1, freiberger), (3, helles)],
                casi: [(6, sterni)],
                sepp: [(6, sterni)],
                ohli: [(4, sterni)],
                marius: [(1, radler)],
                anonym: [(10, sterni), (10, krosti), (2, radler), (4, helles), (1, sekt)],
            },
        )

        # --------------- SATURDAY ---------------

        consumption(
            day=3,
            for_free=False,
            drink_dict={
                herald: [(1, sterni), (2, freiberger), (2, radler), (1, buddi), (5, spezi), (2, wasser)],
                thure: [(6, sterni), (1, krosti), (1, radler), (2, spezi)],
                sandra: [(6, sterni), (1, freiberger), (2, radler), (1, mate), (1, cola), (1, sekt)],
                marvin: [(1, sterni), (1, mate)],
                simon: [(10, sterni), (1, radler), (1, mate)],
                jona: [(6, sterni), (4, krosti)],
                robert: [(1, sterni), (1, freiberger), (1, buddi), (2, mate), (2, spezi), (3, wasser)],
                steven: [(5, helles), (1, sterni), (2, radler), (1, mate)],
                flo: [(4, helles), (1, freiberger), (1, buddi), (2, mate)],
                matze: [(4, sterni), (2, radler), (3, buddi), (7, spezi)],
                alexius: [(2, helles), (3, sterni), (1, radler), (1, cola)],
                josi: [(5, sterni), (1, radler), (2, mate), (2, wasser), (1, sekt)],
                benni: [(1, helles), (2, krosti), (2, radler), (1, wasser)],
                ohli: [(1, helles), (3, sterni), (2, krosti), (1, radler), (1, buddi), (1, mate)],
                arthur: [(3, sterni), (1, krosti), (1, radler), (1, mate), (3, spezi), (2, sekt)],
                pauline: [(2, sterni), (2, radler), (1, mate), (1, cola)],
                enni: [(9, sterni), (1, spezi), (2, wasser), (1, sekt)],
                annemarie: [(5, sterni), (4, radler), (2, buddi), (1, mate), (1, wasser), (2, sekt)],
                tobi: [(3, sterni), (1, radler), (1, mate), (1, wasser)],
                marten: [(4, helles), (1, krosti)],
                lukas: [(4, sterni), (1, spezi)],
                lilly: [(5, sterni), (1, mate)],
                andrea: [(1, buddi)],
                lena: [(1, sterni)],
                anonym: [(2, helles), (3, sterni), (5, krosti), (2, radler), (1, cola), (2, sekt)],
            },
        )

        consumption(
            day=3,
            for_free=True,
            drink_dict={
                rockbert: [(8, krosti), (1, radler), (1, mate)],
                anonym: [(8, sterni), (2, krosti), (2, mate), (1, cola)],
            },
        )

        # --------------- ADMIN STUFF ---------------

        if not settings.PRODUCTION:
            flo.set_password("123")
            flo.is_staff = True
            flo.is_superuser = True
            flo.save()
