import datetime

# ═════════════════════════════════════════════
# Task class
# ═════════════════════════════════════════════

class Task:
    VALID_PRIORITIES = ["low", "medium", "high"]
    VALID_STATUSES   = ["pending", "in progress", "done"]

    def __init__(self, title, priority, deadline):
        self.title    = title
        self.priority = priority
        self.status   = "pending"
        self.deadline = deadline
        self.created  = datetime.datetime.now().strftime("%Y-%m-%d,%H:%M:%S")

    def __str__(self):
        return f"[{self.status.upper()}] {self.title} | priority: {self.priority} | deadline: {self.deadline}"

    def __repr__(self):
        return f"Task('{self.title}', '{self.priority}', '{self.deadline}')"


# ═════════════════════════════════════════════
# TaskList class
# ═════════════════════════════════════════════

class TaskList:
    def __init__(self, name):
        self.name     = name
        self.tasks    = {}
        self.filename = f"{name}.txt"

    def __str__(self):
        total   = len(self.tasks)
        pending = sum(1 for t in self.tasks.values() if t.status == "pending")
        done    = sum(1 for t in self.tasks.values() if t.status == "done")
        return f"{self.name} — {total} tasks | {pending} pending | {done} done"

    def __len__(self):
        return len(self.tasks)

    # ─────────────────────────────────────────
    # Get next ID
    # ─────────────────────────────────────────

    def get_next_id(self):
        if not self.tasks:
            return 1
        return max(self.tasks.keys()) + 1

    # ─────────────────────────────────────────
    # Load from file
    # ─────────────────────────────────────────

    def load(self):
        self.tasks = {}
        try:
            with open(self.filename, "r", encoding="utf-8") as f:
                for line in f:
                    row          = line.strip().split(";")
                    task         = Task(row[1], row[2], row[4])
                    task.status  = row[3]
                    task.created = row[5]
                    self.tasks[int(row[0])] = task
        except FileNotFoundError:
            pass

    # ─────────────────────────────────────────
    # Add task
    # ─────────────────────────────────────────

    def add(self):
        title = ""
        while not title:
            title = input("Task title: ")

        priority = ""
        while priority not in Task.VALID_PRIORITIES:
            priority = input("Priority (low/medium/high): ").lower()

        deadline = ""
        while not deadline:
            deadline = input("Deadline (YYYY-MM-DD): ")

        id   = self.get_next_id()
        task = Task(title, priority, deadline)
        self.tasks[id] = task

        with open(self.filename, "a", encoding="utf-8") as f:
            f.write(f"{id};{task.title};{task.priority};{task.status};{task.deadline};{task.created}\n")
        self.load()

    # ─────────────────────────────────────────
    # Show all tasks
    # ─────────────────────────────────────────

    def show(self):
        if not self.tasks:
            print("No tasks yet.")
            return
        for id, task in self.tasks.items():
            print(f"{id}. {task}")

    # ─────────────────────────────────────────
    # Show tasks sorted by deadline
    # ─────────────────────────────────────────

    def show_by_deadline(self):
        if not self.tasks:
            print("No tasks yet.")
            return

        today = datetime.date.today()

        def days_left(item):
            id, task = item
            try:
                deadline = datetime.datetime.strptime(task.deadline, "%Y-%m-%d").date()
                return (deadline - today).days
            except ValueError:
                return 9999

        sorted_tasks = sorted(self.tasks.items(), key=days_left)

        for id, task in sorted_tasks:
            try:
                deadline = datetime.datetime.strptime(task.deadline, "%Y-%m-%d").date()
                diff     = (deadline - today).days
                if diff < 0:
                    urgency = f"OVERDUE by {abs(diff)} days"
                elif diff == 0:
                    urgency = "DUE TODAY"
                else:
                    urgency = f"{diff} days left"
            except ValueError:
                urgency = "invalid date"
            print(f"{id}. {task} | {urgency}")

    # ─────────────────────────────────────────
    # Update status
    # ─────────────────────────────────────────

    def update_status(self):
        self.show()
        if not self.tasks:
            return

        while True:
            try:
                id = int(input("Task ID to update: "))
                if id in self.tasks:
                    break
                print("ID not found.")
            except ValueError:
                print("Invalid ID. Enter a number.")

        print(f"Current status: {self.tasks[id].status}")
        status = ""
        while status not in Task.VALID_STATUSES:
            status = input("New status (pending/in progress/done): ").lower()

        self.tasks[id].status = status
        print(f"Task updated: {self.tasks[id]}")

        with open(self.filename, "w", encoding="utf-8") as f:
            for tid, task in self.tasks.items():
                f.write(f"{tid};{task.title};{task.priority};{task.status};{task.deadline};{task.created}\n")
        self.load()

    # ─────────────────────────────────────────
    # Filter tasks
    # ─────────────────────────────────────────

    def filter_tasks(self):
        print("Filter by:")
        print("1 - Priority")
        print("2 - Status")
        choice = input("Choose: ")

        if choice == "1":
            priority = ""
            while priority not in Task.VALID_PRIORITIES:
                priority = input("Priority (low/medium/high): ").lower()
            results = {id: t for id, t in self.tasks.items() if t.priority == priority}

        elif choice == "2":
            status = ""
            while status not in Task.VALID_STATUSES:
                status = input("Status (pending/in progress/done): ").lower()
            results = {id: t for id, t in self.tasks.items() if t.status == status}

        else:
            print("Invalid choice.")
            return

        if not results:
            print("No tasks match your filter.")
            return

        for id, task in results.items():
            print(f"{id}. {task}")

    # ─────────────────────────────────────────
    # Delete task
    # ─────────────────────────────────────────

    def delete(self):
        self.show()
        if not self.tasks:
            return

        while True:
            try:
                id = int(input("Task ID to delete: "))
                if id in self.tasks:
                    break
                print("ID not found.")
            except ValueError:
                print("Invalid ID. Enter a number.")

        print(f"Deleting: {self.tasks[id]}")
        confirm = input("Confirm? (yes/no): ").lower()
        if confirm == "yes":
            del self.tasks[id]
            with open(self.filename, "w", encoding="utf-8") as f:
                for tid, task in self.tasks.items():
                    f.write(f"{tid};{task.title};{task.priority};{task.status};{task.deadline};{task.created}\n")
            self.load()
            print("Task deleted.")
        else:
            print("Cancelled.")

    # ─────────────────────────────────────────
    # Export report
    # ─────────────────────────────────────────

    def export_report(self):
        today    = datetime.date.today().strftime("%Y-%m-%d")
        filename = f"{self.name}_report_{today}.txt"

        with open(filename, "w", encoding="utf-8") as f:
            f.write(f"Task Report — {self.name}\n")
            f.write(f"Generated: {today}\n")
            f.write("=" * 30 + "\n")
            f.write(f"Total:       {len(self.tasks)}\n")
            f.write(f"Pending:     {sum(1 for t in self.tasks.values() if t.status == 'pending')}\n")
            f.write(f"In progress: {sum(1 for t in self.tasks.values() if t.status == 'in progress')}\n")
            f.write(f"Done:        {sum(1 for t in self.tasks.values() if t.status == 'done')}\n")
            f.write("=" * 30 + "\n\n")

            for priority in ["high", "medium", "low"]:
                tasks = {id: t for id, t in self.tasks.items() if t.priority == priority}
                if tasks:
                    f.write(f"// {priority.upper()}\n")
                    for id, task in tasks.items():
                        f.write(f"{id}. [{task.status.upper()}] {task.title} | deadline: {task.deadline}\n")
                    f.write("\n")

        print(f"Report saved: {filename}")


# ═════════════════════════════════════════════
# Menu
# ═════════════════════════════════════════════

task_list = TaskList("daily")
task_list.load()

print(task_list)

while True:
    print("\nTask Manager")
    option = input("1-Add\n2-Show all\n3-Show by deadline\n4-Update status\n5-Filter\n6-Delete\n7-Export report\nq-Quit\nChoose: ")
    if option == "1":
        task_list.add()
        print("Task added successfully!")
    elif option == "2":
        task_list.show()
    elif option == "3":
        task_list.show_by_deadline()
    elif option == "4":
        task_list.update_status()
    elif option == "5":
        task_list.filter_tasks()
    elif option == "6":
        task_list.delete()
    elif option == "7":
        task_list.export_report()
    elif option == "q":
        break
    else:
        print("Invalid option.")
