from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
import random
from mygame.backend.event import SpecialOrder
from .worker import Worker
from .order import Order
from .event import Event
from .action import *

# ACTION NOCH IMPORTIEREN?


# company die jeder spieler steuert
class Company(models.Model):
    name = models.CharField(default="A company", max_length=20)
    user = models.CharField(default="default User", max_length=20)
    customersatisfaction = models.IntegerField(
        default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
    )
    workersatisfaction = models.IntegerField(
        default=100, validators=[MinValueValidator(0), MaxValueValidator(100)]
    )
    money = models.IntegerField(default=100000)
    workermarket = models.ManyToManyField(Worker, related_name="workermarket")
    actions = models.ManyToManyField("Action", blank=True)
    workers = models.ManyToManyField(Worker, blank=True, related_name="workers")
    orders = models.ManyToManyField(Order, blank=True)
    events = models.ManyToManyField(Event, blank=True)

    def __str__(self):
        return self.name

    def addProfit(self, profit):
        self.money += profit
        self.save()

    def clearEvents(self):
        for event in self.events.all():
            # wenn specialorder ignoriert wurde -> penalty und removen (nicht löschen)
            if isinstance(event, SpecialOrder):
                for order in self.orders.all():
                    if order.specialorder == event:
                        event.handle(order=order, company=self, handle=False)
                self.events.remove(event)
            else:
                event.delete()

    def addEvent(self, event):
        self.events.add(event)
        self.save()

    def getEvent(self, eventnumber, direction):
        # wenn keine events gib leeres event
        if not self.events.exists():
            event = Event.createEmpty()
            return (event, eventnumber)
        # bei klick auf eventbutton immer erstes event zeigen
        if eventnumber == 0 and direction == "default":
            event = self.events.order_by("id")[eventnumber]
        elif direction == "previous":
            # wenn bei erstem element zurück dann letztes element zeigen
            if eventnumber <= 0:
                eventnumber = self.events.count() - 1
                event = self.events.order_by("id")[eventnumber]
            else:
                eventnumber -= 1
                event = self.events.order_by("id")[eventnumber]
        elif direction == "next":
            # wenn bei letztem element weiter dann erstes anzeigen
            if eventnumber >= (self.events.count() - 1):
                eventnumber = 0
                event = self.events.order_by("id")[eventnumber]
            else:
                eventnumber += 1
                event = self.events.order_by("id")[eventnumber]
        return (event, eventnumber)

    def addAction(self, action):
        for existingaction in self.actions.all():
            if action.name == existingaction.name:
                self.cancelAction(existingaction.id)
        self.actions.add(action)

    def deleteAction(self, action):
        self.actions.delete(action)

    def calculateCustomerSatisfaction(self, number):
        calc = self.customersatisfaction
        calc += number
        if calc < 0:
            calc = 0
        if calc > 100:
            calc = 100
        self.customersatisfaction = calc
        self.save()

    def calculateWorkerSatisfaction(self, number):
        if (self.workersatisfaction + number) > 100:
            self.workersatisfaction = 100
        elif (self.workersatisfaction + number) < 0:
            self.workersatisfaction = 0
        else:
            self.workersatisfaction += number
        self.save()

    def calculateAllWorkersHappyness(self, addhappyness):
        for worker in self.workers.all():
            worker.calculateHappyness(addhappyness)

    def paySalary(self):
        salarysum = 0
        for worker in self.workers.all():
            if self.money < salarysum:
                worker.calculateHappyness(-50)
            else:
                salarysum += worker.salary
        self.money -= salarysum
        self.save()

    def checkWorkerQuit(self):
        threshhold = 55
        for worker in self.workers.all():
            if worker.happyness <= threshhold:
                diff = threshhold - worker.happyness
                randnum = random.randint(1, 100)
                if 2 * diff > randnum:
                    event = Event.createWorkerQuit(
                        threshhold=threshhold,
                        workername=worker.name,
                        workerhappyness=worker.happyness,
                    )
                    self.addEvent(event)
                    worker.quitJob()

    def calculateOrderWorkload(self):
        for order in self.orders.all():
            finished = order.calculateWorkload(self.workersatisfaction)
            if finished:
                order.finishOrder(self)
                event = Event.createOrderFinished(
                    ordername=order.name, profit=str(order.profit)
                )
                self.events.add(event)
                order.delete()
            elif order.maxRounds == 0:
                order.cancelOrder()
                self.calculateCustomerSatisfaction(-30)
                event = Event.createOrderFailed(ordername=order.name)
                self.events.add(event)
                order.delete()

    def addOrder(self, order):
        self.orders.add(order)

    def deleteOrder(self, order):
        self.orders.remove(order)

    def addToWorkermarket(self, worker):
        self.workermarket.add(worker)

    def removeFromWorkermarket(self, worker):
        self.workermarket.remove(worker)

    def generateWorkermarket(self):
        self.clearWorkermarket()
        for x in range(5):
            worker = Worker.createRandom()
            self.addToWorkermarket(worker)

    def clearWorkermarket(self):
        for worker in self.workermarket.all():
            if worker.status == 0:
                worker.delete()
        self.workermarket.clear()

    # actions:
    def cancelAction(self, id):
        action = Action.objects.get(id=id)
        action.cancel()
        if action:
            action.delete()

    def actionEmploy(self, worker):
        act = ActionEmploy.create(worker=worker, actionmaker=self)
        return act

    def actionUnemploy(self, worker):
        act = ActionUnemploy.create(worker=worker, actionmaker=self)
        return act

    def actionOffer(self, order, amount):
        act = ActionOffer.create(order=order, amount=amount, actionmaker=self)
        return act

    def actionCancelOrder(self, order):
        act = ActionCancelOrder.create(order=order, actionmaker=self)
        return act

    def actionTrain(self, worker, trainskill):
        act = ActionTrain.create(worker=worker, trainskill=trainskill, actionmaker=self)
        return act
