from collections import defaultdict
from datetime import datetime
from enum import Enum

from .entity import Entity
from .task import Task


class CompositeStatus(Enum):
    ACTIVE = 1
    COMPLETED = 2
    DELETED = 3


class Composite(Entity):

    def __init__(self,
                 name: str,
                 description: str = None,
                 creation_date: datetime = datetime.now(),
                 project: int = None,
                 assignee: int = None,
                 status: str = "ACTIVE",
                 created_by: int = None,
                 **kwargs) -> None:
        if not name:
            raise ValueError("task name cannot be empty!")
        if not isinstance(creation_date, datetime):
            raise ValueError(
                "creation_date should be of type datetime.datetime!")
        self.name = name
        self.creation_date = creation_date
        self.description = description
        self.project = project
        self.assignee = assignee
        self.created_by = created_by
        self.status = status
        self.is_completed = False

    @property
    def backlog_tasks(self) -> list[Task]:
        tasks = []
        for entity_task in self.tasks:
            task = entity_task.tasks
            if task.status.name == "BACKLOG":
                tasks.append(task)
        return tasks
    @property
    def open_tasks(self) -> list[Task]:
        tasks = []
        for entity_task in self.tasks:
            task = entity_task.tasks
            if task.status.name not in ("DONE", "DELETED"):
                tasks.append(task)
        return tasks

    @property
    def completed_tasks(self) -> list[Task]:
        tasks = []
        for entity_task in self.tasks:
            task = entity_task.tasks
            if task.status.name in ("DONE", "DELETED"):
                tasks.append(task)
        return tasks

    def complete(self, tasks) -> None:
        incompleted_tasks = list()
        for task in tasks:
            if task.tasks.status.name != "DONE":
                incompleted_tasks.append(task)
        if incompleted_tasks:
            logging.warning("[composite %d]: %d tasks haven't been completed",
                            self.id, len(incompleted_tasks))
        self.is_completed = True

    def daily_time_entries_hours(self,
                                 last_n_days: int = 14) -> dict[str, float]:
        entries: dict[str, float] = defaultdict(float)
        for task in self.tasks:
            task_entries = task.tasks.daily_time_entries_hours(
                last_n_days=last_n_days)
            for day, hours in task_entries.items():
                entries[day] += hours
        return entries

    @property
    def total_time_spent(self):
        total_time_spent = 0
        for task in self.tasks:
            total_time_spent += task.tasks.total_time_spent
        return total_time_spent
