#!/usr/bin/env python
"""
Health and Habits Management System

This module contains all health and habits-related functionality for the BaoLife game,
including health conditions, weight management, death mechanics, and habit tracking.

Extracted from functions.py for better code organization and maintainability.
"""

import random
from datetime import timedelta, datetime


# ============================================================
# Weight Management
# ============================================================

def getWeightType(weight):
    """
    Determine weight category based on weight value.

    Args:
        weight: Numeric weight value

    Returns:
        str: Weight category ('Underweight', 'Normal', 'Overweight', 'Obese')
    """
    if (weight < 50):
        return 'Underweight'
    elif (weight < 70):
        return 'Normal'
    elif (weight < 90):
        return 'Overweight'
    else:
        return 'Obese'


def handleWeight(person):
    """
    Enforce weight boundaries (0-100).

    Args:
        person: Person object with weight attribute
    """
    if (person.weight < 0):
        person.weight = 0
    if (person.weight > 100):
        person.weight = 100


# ============================================================
# Health Management
# ============================================================

def handleHealth(player, person):
    """
    Update person's health based on weight type and health conditions.
    Handles health condition duration and healing.

    Args:
        player: Player object with date information
        person: Person object with health attributes
    """
    from datetime import timedelta, datetime
    if (person.weightType == 'Underweight' or person.weightType == 'Obese'):
        person.health = person.health - .000001
    # loop through person.healthConditions
    if (person.healthConditions):
        for condition in person.healthConditions:
            condition_date = datetime.strptime(condition.date, '%m-%d')
            healing_date = condition_date + timedelta(weeks=condition.averageDuration)
            # Convert player.date to datetime object assuming it's also in 'mm-dd' format
            player_date = datetime.strptime(player.date, '%m-%d')
            if player_date >= healing_date:
                condition.isCured = True
            else:
                person.health = person.health - (condition.healthModifier/100000)
                condition.isCured = False

    if (person.health <= 0):
        person.deathChance = person.deathChance + 1
    if (person.health >= 2):
        person.health = 2


def handleDeath(player):
    """
    Handle player death event.

    Args:
        player: Player object
    """
    player.messageQueue.append('You have died!')
    player.controller = 'inactive'


def updateDeathChance(person):
    """
    Calculate death chance based on age and health.

    Args:
        person: Person object with age and health attributes

    Returns:
        float: Updated death chance value
    """
    if (person.ageYears > 100):
        person.deathChance = 0.0012
    elif (person.ageYears > 82):
        person.deathChance = 0.0002
    elif (person.ageYears > 70):
        person.deathChance = 0.000006
    elif (person.ageYears > 60):
        person.deathChance = 0.000005
    elif (person.ageYears > 50):
        person.deathChance = 0.000004
    elif (person.ageYears > 40):
        person.deathChance = 0.000003
    elif (person.ageYears > 30):
        person.deathChance = 0.000002
    elif (person.ageYears > 20):
        person.deathChance = 0.000001
    person.deathChance = person.deathChance / person.health
    return person.deathChance


# ============================================================
# Hunger and Thirst Management
# ============================================================

def handleHunger(person):
    """
    Enforce hunger and thirst boundaries (minimum 0).

    Args:
        person: Person object with hunger and thirst attributes

    Returns:
        person: Updated person object
    """
    if (person.hunger < 0):
        person.hunger = 0
    if (person.thirst < 0):
        person.thirst = 0
    return person


def mealEvent(player):
    """
    Process meal event, reducing hunger and thirst.

    Args:
        player: Player object with character (c) attribute

    Returns:
        player: Updated player object
    """
    # random number 50-60
    player.c.hunger = player.c.hunger - random.randint(50, 60)
    player.c.thirst = player.c.thirst - random.randint(50, 60)
    return player


# ============================================================
# Health Conditions System
# ============================================================

class HealthCondition:
    """
    Represents a health condition or disease that can affect a character.

    Attributes:
        id: Unique identifier for the condition
        title: Display name of the condition
        healthModifier: Amount of health impact (higher = worse)
        averageDuration: Expected duration in weeks
        date: Date when condition was acquired
        description: Descriptive text about the condition
        image: Optional image URL
    """
    def __init__(self, id, title, healthModifier, averageDuration, description, image=None):
        self.id = id
        self.title = title
        self.healthModifier = healthModifier
        self.averageDuration = averageDuration
        self.date = None
        self.description = description
        self.image = image


def getHealthConditions():
    """
    Get list of all available health conditions.

    Returns:
        list: List of HealthCondition objects
    """
    # list diseases and conditions
    conditions = [
        HealthCondition("condition1", "COVID-19", 10, 14, "You have contracted COVID-19. You must quarantine for 14 days."),
        HealthCondition("condition2", "Common Cold", 5, 3, "You have a common cold. You must rest for 3 days."),
        HealthCondition("condition3", "Flu", 10, 7, "You have the flu. You must rest for 7 days."),
        HealthCondition("condition4", "Broken Bone", 15, 30, "You have a broken bone. You must rest for 30 days."),
        HealthCondition("condition5", "Sprained Ankle", 5, 7, "You have a sprained ankle. You must rest for 7 days."),
        HealthCondition("condition6", "Food Poisoning", 5, 3, "You have food poisoning. You must rest for 3 days."),
        HealthCondition("condition7", "Diabetes", 5, 99999, "You have been diagnosed with Diabetes. Regular medication and lifestyle changes are required."),
        HealthCondition("condition8", "High Blood Pressure", 5, 99999, "You have high blood pressure. You need to monitor it regularly and possibly take medication."),
        HealthCondition("condition9", "Migraine", 7, 3, "You are suffering from a migraine. You need rest and possibly medication to manage the symptoms."),
        HealthCondition("condition10", "Asthma", 2, 99999, "You have been diagnosed with Asthma. Regular use of inhalers and avoiding triggers is required."),
        HealthCondition("condition11", "Heart Disease", 20, 99999, "You have been diagnosed with heart disease. Lifestyle changes, medication, or surgery may be required."),
        HealthCondition("condition15", "Arthritis", 10, 99999, "You have been diagnosed with Arthritis. Pain management and physical therapy can help."),
        HealthCondition("condition16", "Gastroenteritis", 7, 5, "You have gastroenteritis. Rest, fluid intake, and possibly medication are required.")
    ]
    return conditions


# ============================================================
# Habits System
# ============================================================

class HabitClass:
    """
    Represents a habit (positive or negative) that a character can have.

    Attributes:
        name: Habit identifier
        description: Descriptive text about the habit
        type: Always "habit"
        habitType: "positive" or "negative"
        status: "active" or "quitting"
        quitProgress: Days of progress when quitting (0-30)
    """
    def __init__(self, name, description, habitType="negative"):
        self.name = name
        self.description = description
        self.type = "habit"
        self.habitType = habitType
        self.status = "active"
        self.quitProgress = 0


# Habit definitions
negative_habits = {
    'tardiness': HabitClass("tardiness", "Your lack of punctuality is becoming noticeable."),
    'nail_biting': HabitClass("nail_biting", "You catch yourself biting your nails. It's a nervous habit."),
    'overthinking': HabitClass("overthinking", "You can't help but overanalyze every situation."),
    'procrastination': HabitClass("procrastination", "You tend to put things off until the last minute."),
    'negative_thinking': HabitClass("negative_thinking", "You're struggling to keep negative thoughts at bay."),
    'overeating': HabitClass("overeating", "Your tiredness is making you reach for comfort foods. You're overeating and it's not making you feel any better."),
    'under_exercising': HabitClass("under_exercising", "You haven't been getting much exercise lately."),
    'excessive_screen_time': HabitClass("excessive_screen_time", "You're spending too much time in front of screens."),
    'impulsiveness': HabitClass("impulsiveness", "You have a tendency to act without thinking things through."),
    'indecisiveness': HabitClass("indecisiveness", "You struggle with making decisions, big or small."),
    'neglecting_self_care': HabitClass("neglecting_self_care", "You haven't been taking care of yourself as much as you should."),
    'poor_time_management': HabitClass("poor_time_management", "You're always running behind schedule."),
    'overeating_when_stressed': HabitClass("overeating_when_stressed", "Stress pushes you to eat more than you need."),
    'excessive_caffeine_intake': HabitClass("excessive_caffeine_intake", "You've been consuming too much caffeine."),
    'smoking': HabitClass("smoking", "The habit of smoking is taking a toll on your health."),
    'excessive_alcohol_consumption': HabitClass("excessive_alcohol_consumption", "Exhaustion sets in and you find yourself reaching for a drink more often than usual.")
}

positive_habits = {
    'punctuality': HabitClass("punctuality", "Your punctuality is appreciated by those around you.", "positive"),
    'regular_exercise': HabitClass("regular_exercise", "Your commitment to regular exercise is paying off.", "positive"),
    'healthy_eating': HabitClass("healthy_eating", "You feel better when you eat well.", "positive"),
    'positive_thinking': HabitClass("positive_thinking", "Your positive mindset helps you overcome challenges.", "positive"),
    'planning_ahead': HabitClass("planning_ahead", "Planning ahead makes life smoother.", "positive"),
    'prioritizing_self_care': HabitClass("prioritizing_self_care", "Taking care of yourself improves your mood.", "positive"),
    'effective_time_management': HabitClass("effective_time_management", "Your time management skills keep things under control.", "positive"),
    'practicing_gratitude': HabitClass("practicing_gratitude", "Practicing gratitude makes you feel happier.", "positive"),
    'mindfulness_meditation': HabitClass("mindfulness_meditation", "Meditation helps keep your mind clear.", "positive"),
    'regular_sleeping_schedule': HabitClass("regular_sleeping_schedule", "Maintaining a regular sleep schedule keeps you refreshed.", "positive"),
    'active_listening': HabitClass("active_listening", "You understand others better by actively listening.", "positive"),
    'showing_empathy': HabitClass("showing_empathy", "Showing empathy builds strong relationships.", "positive"),
    'tidy': HabitClass("tidy", "Keeping things tidy helps your peace of mind.", "positive"),
    'hygienic': HabitClass("hygienic", "Your hygiene habits keep you healthy.", "positive"),
    'work_life_balance': HabitClass("work_life_balance", "Balancing work and personal time keeps you satisfied.", "positive"),
}


def setHabits(person):
    """
    Initialize habits for a person based on age.
    Assigns random negative and non-conflicting positive habits.

    Args:
        person: Person object with ageYears and habits attributes

    Returns:
        person: Updated person object with habits assigned
    """
    habit_pairs = {
        'tardiness': 'punctuality',
        'overthinking': 'positive_thinking',
        'procrastination': 'planning_ahead',
        'negative_thinking': 'positive_thinking',
        'overeating': 'healthy_eating',
        'under_exercising': 'regular_exercise',
        'excessive_screen_time': 'work_life_balance',
        'impulsiveness': 'planning_ahead',
        'indecisiveness': 'planning_ahead',
        'neglecting_self_care': 'prioritizing_self_care',
        'poor_time_management': 'effective_time_management',
        'overeating_when_stressed': 'healthy_eating',
        'excessive_caffeine_intake': 'regular_sleeping_schedule',
        'smoking': 'prioritizing_self_care',
        'excessive_alcohol_consumption': 'prioritizing_self_care'
    }

    habitCnt = 6
    if person.ageYears < 18:
        habitCnt = round(person.ageYears / 5)

    person_negative_habits = random.sample(list(negative_habits.values()), random.randint(0, habitCnt))
    habitCnt = habitCnt - len(person_negative_habits)
    non_conflicting_positive_habits = [habit for habit in positive_habits.values() if habit not in [negative_habits.get(habit_pairs.get(negative_habit)) for negative_habit in person_negative_habits]]

    person_positive_habits = random.sample(non_conflicting_positive_habits, min(random.randint(0, habitCnt), len(non_conflicting_positive_habits)))

    # Merge negative and positive habits into a list
    person.habits = person_negative_habits + person_positive_habits

    return person


def quitHabit(player, habit):
    """
    Start the process of quitting a habit.

    Args:
        player: Player object with character (c) and messageQueue
        habit: Name of the habit to quit
    """
    # change habit status to quitting
    for index, item in enumerate(player.c.habits):
        if item.name == habit:
            player.c.habits[index].status = 'quitting'
            # event message
            player.messageQueue.append('You have decided to try quitting "' + habit.replace('_', ' ').title() + '". ')
            from stats.stats_manager import getPeakEnergy
            getPeakEnergy(player.c)


def stopQuitHabit(player, habit):
    """
    Stop trying to quit a habit and reset progress.

    Args:
        player: Player object with character (c) and messageQueue
        habit: Name of the habit to stop quitting
    """
    # change habit status to active
    for index, item in enumerate(player.c.habits):
        if item.name == habit:
            player.c.habits[index].status = 'active'
            player.c.habits[index].quitProgress = 0
            # event message
            player.messageQueue.append('You have decided to stop trying to quit "' + habit.replace('_', ' ').title() + '". ')
            from stats.stats_manager import getPeakEnergy
            getPeakEnergy(player.c)


def handleHabitChanges(player, person):
    """
    Process habit quitting progress. After 30 days, habit is successfully quit.

    Args:
        player: Player object for message queue
        person: Person object with habits
    """
    for habit in person.habits:
        if habit.status == 'quitting':
            habit.quitProgress += 1
            print("Habit: " + str(habit.quitProgress))
            if habit.quitProgress == 30:
                # remove habit from list
                person.habits.remove(habit)
                # event message
                player.messageQueue.append("You have successfully quit your habit!")
                from stats.stats_manager import getPeakEnergy
                getPeakEnergy(person)
