import datetime

# ═════════════════════════════════════════════
# CalorieTracker — OOP version
# ═════════════════════════════════════════════

class CalorieTracker:

    def __init__(self, user):
        self.food_dict = {}
        self.filename  = f"food_log_{user}.txt"

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

    def load(self):
        try:
            with open(self.filename, "r", encoding="utf-8") as f:
                for line in f:
                    row = line.strip().split(";")
                    self.food_dict[row[0]] = [row[1], float(row[2]), row[3], int(row[4])]
        except FileNotFoundError:
            pass

    # ─────────────────────────────────────────
    # Add food item
    # ─────────────────────────────────────────

    def add(self):
        name = ""
        while not name:
            name = input("Food name: ")

        while True:
            try:
                quantity = float(input("Quantity: "))
                if quantity > 0:
                    break
                print("Quantity must be greater than 0.")
            except ValueError:
                print("Invalid quantity. Enter a number.")

        measure = ""
        while not measure:
            measure = input("Measure: ")

        while True:
            try:
                calories = int(input("Calories: "))
                if calories > 0:
                    break
                print("Calories must be greater than 0.")
            except ValueError:
                print("Invalid calories. Enter a whole number.")

        timestamp = datetime.datetime.now().strftime("%Y-%m-%d,%H:%M:%S")
        self.food_dict[timestamp] = [name, quantity, measure, calories]

        with open(self.filename, "a", encoding="utf-8") as f:
            f.write(f"{timestamp};{name};{quantity};{measure};{calories}\n")
        self.load()

    # ─────────────────────────────────────────
    # Last 7 days — detailed
    # ─────────────────────────────────────────

    def last_days_details(self):
        today = datetime.datetime.now()
        last_days_dict = {}

        for n in range(0, 8):
            reference_day = (today - datetime.timedelta(days=n)).strftime("%Y-%m-%d")
            for key in self.food_dict:
                if reference_day == key.split(",")[0]:
                    last_days_dict[key] = self.food_dict[key]

        return last_days_dict

    def print_details(self):
        food_log = self.last_days_details()
        for key in food_log:
            print(f"{key.split(',')[0]} - {food_log[key][0]} - {food_log[key][1]}{food_log[key][2]} - {food_log[key][3]} kcal")

    # ─────────────────────────────────────────
    # Discipline analysis
    # ─────────────────────────────────────────

    def last_days_sum(self):
        today_string = ""
        while not today_string:
            today_string = input("Reference date (YYYY-MM-DD): ")

        while True:
            try:
                calories_target = int(input("Your daily calories target: "))
                if calories_target > 0:
                    break
                print("Target must be greater than 0.")
            except ValueError:
                print("Invalid calories target. Enter a whole number.")

        last_days_dict = {}
        for key in self.food_dict:
            if today_string == key.split(",")[0]:
                if key.split(",")[0] not in last_days_dict:
                    last_days_dict[key.split(",")[0]] = 0
                last_days_dict[key.split(",")[0]] += self.food_dict[key][3]

        for key in last_days_dict:
            if last_days_dict[key] <= calories_target:
                cal_value = last_days_dict[key]
                last_days_dict[key] = [cal_value, "On target! Great job!"]
            else:
                cal_value = last_days_dict[key]
                cal_diff  = cal_value - calories_target
                last_days_dict[key] = [cal_value, "Over target by " + str(cal_diff) + " kcal."]

        return last_days_dict

    def print_target(self):
        food_log = self.last_days_sum()
        for key in sorted(food_log):
            print(f"Date: {key} - {food_log[key][0]} kcal consumed. {food_log[key][1]}")

    # ─────────────────────────────────────────
    # General report
    # ─────────────────────────────────────────

    def general_report(self):
        start_string = ""
        while not start_string:
            start_string = input("Start date (YYYY-MM-DD): ")

        stop_string = ""
        while not stop_string:
            stop_string = input("Stop date (YYYY-MM-DD): ")

        rep_dict = {}
        for key in self.food_dict:
            if start_string <= key.split(",")[0] <= stop_string:
                if key.split(",")[0] not in rep_dict:
                    rep_dict[key.split(",")[0]] = [self.food_dict[key][3], {key.split(",")[1]: [self.food_dict[key][0], self.food_dict[key][1], self.food_dict[key][2], self.food_dict[key][3]]}]
                else:
                    rep_dict[key.split(",")[0]][0] += self.food_dict[key][3]
                    rep_dict[key.split(",")[0]][1][key.split(",")[1]] = [self.food_dict[key][0], self.food_dict[key][1], self.food_dict[key][2], self.food_dict[key][3]]

        return rep_dict

    def export_general(self):
        food_log = self.general_report()

        start_string = min(food_log.keys())
        stop_string  = max(food_log.keys())
        filename = f"report_{start_string}_{stop_string}.txt"

        with open(filename, "w", encoding="utf-8") as f:
            for key in sorted(food_log):
                f.write("=" * 20 + "\n")
                f.write(f"Date: {key} - {food_log[key][0]} kcal consumed.\n")
                f.write("=" * 20 + "\n")
                day_dict = food_log[key][1]
                for subkey in sorted(day_dict):
                    f.write(f"Time: {subkey} - {day_dict[subkey][0]}, {day_dict[subkey][1]}{day_dict[subkey][2]} - {day_dict[subkey][3]} kcal.\n")

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

    # ─────────────────────────────────────────
    # Special methods
    # ─────────────────────────────────────────

    def __str__(self):
        return f"CalorieTracker — {len(self.food_dict)} entries in {self.filename}"

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


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

tracker = CalorieTracker("bull")
tracker.load()

print(tracker)          # CalorieTracker — N entries in food_log_bull.txt
print(len(tracker))     # N

while True:
    option = input("\nChoose option (1-Add, 2-Show food details, 3-Discipline analysis, 4-General report, q-Quit): ")
    if option == "1":
        tracker.add()
        print("Food log added successfully!")
    elif option == "2":
        if len(tracker.last_days_details()):
            tracker.print_details()
        else:
            print("No data available.")
    elif option == "3":
        if len(tracker.last_days_sum()):
            tracker.print_target()
        else:
            print("No data available.")
    elif option == "4":
        if len(tracker.general_report()):
            tracker.export_general()
        else:
            print("No data available.")
    elif option == "q":
        break
    else:
        print("Invalid option!")
