#!/usr/bin/env python

"""
Tutorial Events System for BaoLife
Provides gentle guided events for first-time players during their first 24 in-game hours
"""

from datetime import datetime, timedelta
import logging
import random

# Import existing event helpers
from events import messageFunction, questionFunction, answerOption


def is_tutorial_mode(player, game_hours=None):
    """
    Check if player is still in tutorial mode (first 24 in-game hours)

    Args:
        player: Player object
        game_hours: Optional override for testing

    Returns:
        bool: True if player is in tutorial mode
    """
    if game_hours is not None:
        return game_hours < 24

    # Calculate hours played based on character age
    if not hasattr(player.c, 'ageHours'):
        return True  # Brand new player

    hours_played = player.c.ageHours
    return hours_played < 24


def get_welcome_message(player):
    """
    Generate welcome message for new player

    Args:
        player: Player object

    Returns:
        dict: Tutorial message event
    """
    firstname = getattr(player.c, 'firstname', None)
    if not firstname:
        firstname = 'friend'

    return {
        'type': 'tutorial_message',
        'message': f"Welcome to BaoLife, {firstname}! Your journey begins now. Make choices, build relationships, and live your best life!",
        'character': 'system',
        'character_image': None,
        'dismissible': True
    }


def generate_tutorial_event(player, event_type):
    """
    Generate special gentle events for tutorial mode

    Event types:
    - first_friend: Guaranteed positive interaction with NPC
    - first_activity: Simplified activity choices
    - first_purchase: Small diamond reward for first store visit
    - first_class: Guaranteed good grade

    Args:
        player: Player object
        event_type: String indicating which tutorial event to generate

    Returns:
        dict: Tutorial event data or None
    """

    if event_type == 'first_friend':
        # Find a friendly classmate/person
        friendly_people = [p for p in player.r if getattr(p, 'affinity', 0) >= 0 and p.status == 'alive']

        if not friendly_people:
            return None

        npc = random.choice(friendly_people)

        return {
            'type': 'tutorial_interaction',
            'event_id': 'first_friend',
            'npc_id': npc.id,
            'npc_name': npc.firstname,
            'message': f"Your classmate {npc.firstname} smiles at you. They seem friendly!",
            'guaranteed_success': True,  # Always positive outcome
            'affinity_bonus': 20,  # Extra affinity gain
            'reward_diamonds': 5,
            'tutorial_hint': "Making friends increases happiness and opens new activities!"
        }

    elif event_type == 'first_activity':
        # Simplified activity selection
        basic_activities = [
            {'name': 'Study', 'energy': 5, 'benefit': 'Increases intelligence'},
            {'name': 'Play', 'energy': 5, 'benefit': 'Increases happiness'},
            {'name': 'Exercise', 'energy': 5, 'benefit': 'Increases health'}
        ]

        return {
            'type': 'tutorial_activity_selection',
            'event_id': 'first_activity',
            'simplified_choices': True,
            'choices': basic_activities,
            'tutorial_hint': "Activities cost energy but help you grow. Choose wisely!"
        }

    elif event_type == 'first_purchase':
        return {
            'type': 'tutorial_store_visit',
            'event_id': 'first_purchase',
            'reward_diamonds': 10,
            'message': "Welcome to the store! Here's 10 diamonds to get you started.",
            'tutorial_hint': "Buy items to increase your prestige and impress others!"
        }

    elif event_type == 'first_class':
        return {
            'type': 'tutorial_class_result',
            'event_id': 'first_class',
            'guaranteed_good_grade': True,
            'grade': 'A',
            'message': "Great job in class! You're a natural learner.",
            'reward_diamonds': 5,
            'tutorial_hint': "Good grades lead to better college and career opportunities!"
        }

    return None


def apply_tutorial_modifiers(player, event_data):
    """
    Apply tutorial mode modifiers to regular events
    - Reduce difficulty
    - Increase rewards
    - Add helpful hints

    Args:
        player: Player object
        event_data: Dictionary of event data

    Returns:
        dict: Modified event data
    """
    if not is_tutorial_mode(player):
        return event_data

    # Make events easier
    if 'difficulty' in event_data:
        event_data['difficulty'] = max(1, event_data['difficulty'] - 2)

    # Boost rewards
    if 'money_reward' in event_data:
        event_data['money_reward'] = int(event_data['money_reward'] * 1.5)

    if 'diamonds_reward' in event_data:
        event_data['diamonds_reward'] = int(event_data['diamonds_reward'] * 1.5)

    # Reduce costs
    if 'energyCost' in event_data:
        event_data['energyCost'] = max(1, int(event_data['energyCost'] * 0.75))

    # Add tutorial hints
    event_data['tutorial_mode'] = True
    event_data['tutorial_hint'] = get_contextual_hint(event_data.get('type', 'general'))

    return event_data


def get_contextual_hint(event_type):
    """
    Get helpful hint based on event type

    Args:
        event_type: String indicating event type

    Returns:
        str: Helpful hint text
    """
    hints = {
        'work': "Working earns money. Save up for big purchases!",
        'school': "Education opens better career opportunities.",
        'social': "Building relationships makes life more fulfilling.",
        'health': "Keep your health high to live longer.",
        'money': "Money buys items that increase your prestige.",
        'questionEvent': "Take your time making decisions - they shape your future!",
        'messageEvent': "Pay attention to life events - they tell your story!"
    }

    return hints.get(event_type, "Make choices that align with your goals!")


def modify_event_for_tutorial(player, event):
    """
    Modify any generated event if player is in tutorial mode
    Called by main event generator

    Args:
        player: Player object
        event: Event object (messageEvent, questionEvent, etc.)

    Returns:
        Event object (potentially modified)
    """
    if not is_tutorial_mode(player):
        return event

    # If it's a dictionary, apply modifiers
    if isinstance(event, dict):
        return apply_tutorial_modifiers(player, event)

    # If it's an event object, try to modify its attributes
    if hasattr(event, '__dict__'):
        event_dict = event.__dict__
        modified_dict = apply_tutorial_modifiers(player, event_dict)

        # Apply modifications back to object
        for key, value in modified_dict.items():
            setattr(event, key, value)

    return event


# Tutorial-specific events that can be called from the event system

def firstConversation(player, type='message', message=False, response=False):
    """
    Tutorial event: First conversation with an NPC
    Guaranteed positive outcome to encourage social interaction
    """
    fname = 'firstConversation'
    check = fname not in player.events and is_tutorial_mode(player) and len(player.r) > 0

    if type != 'answer' and check:
        # Find a friendly person
        friendly_people = [p for p in player.r if getattr(p, 'affinity', 0) >= 0 and p.status == 'alive']

        if friendly_people:
            npc = random.choice(friendly_people)
            message = f"{npc.firstname} approaches you with a warm smile. This seems like a great opportunity to make a friend!"

            answerOptions = [
                answerOption("Say hello!", energyCost=3),
                answerOption("Start a conversation", energyCost=3),
                answerOption("Wave and smile", energyCost=1)
            ]

            return questionFunction(fname, message, player, check, answerOptions)

    elif type == 'answer':
        # Always positive outcome in tutorial mode
        player.messageQueue.append("Great! You've taken your first steps in building relationships. Keep talking to people to grow your friendships!")
        player.c.happiness += 5

        # Give small diamond reward
        if hasattr(player.c, 'diamonds'):
            player.c.diamonds += 5
            player.messageQueue.append("You earned 5 diamonds for making your first connection!")


def firstActivityChoice(player, type='message', message=False, response=False):
    """
    Tutorial event: First activity selection
    Simplified choices with clear benefits
    """
    fname = 'firstActivityChoice'
    check = fname not in player.events and is_tutorial_mode(player) and player.c.ageYears >= 5

    if type != 'answer' and check:
        message = "You have some free time! What would you like to do?"

        answerOptions = [
            answerOption("Study (Gain Intelligence)", energyCost=5),
            answerOption("Play (Gain Happiness)", energyCost=5),
            answerOption("Exercise (Gain Health)", energyCost=5)
        ]

        return questionFunction(fname, message, player, check, answerOptions)

    elif type == 'answer':
        # Apply benefits based on choice
        choice = response.get('option', '')

        if 'Study' in choice:
            player.c.intelligence = getattr(player.c, 'intelligence', 50) + 10
            player.messageQueue.append("You studied hard and feel smarter! Intelligence increased.")
        elif 'Play' in choice:
            player.c.happiness = getattr(player.c, 'happiness', 50) + 10
            player.messageQueue.append("You had fun playing! Happiness increased.")
        elif 'Exercise' in choice:
            player.c.health = getattr(player.c, 'health', 50) + 10
            player.messageQueue.append("You exercised and feel healthier! Health increased.")

        # Tutorial reward
        if hasattr(player.c, 'diamonds'):
            player.c.diamonds += 3
            player.messageQueue.append("You earned 3 diamonds for completing your first activity!")


def tutorialComplete(player, type='message'):
    """
    Event triggered when player completes tutorial (24 hours)
    Awards completion bonus
    """
    fname = 'tutorialComplete'
    check = fname not in player.events and player.c.ageHours >= 24 and player.c.ageHours < 25

    if check:
        message = "You've completed your first day! You're getting the hang of life. Keep going!"

        # Award completion bonus
        if hasattr(player.c, 'diamonds'):
            player.c.diamonds += 25
            message += " You earned 25 diamonds for completing the tutorial!"

        return messageFunction(fname, message, player, check)


# ===== NEW TUTORIAL EVENTS FROM EVENT_IDEAS_QUICK_WINS.md SECTION 11 =====

def tutorialEnergyExplained(player, type='message'):
    """
    Tutorial event: Explaining energy system when low
    Trigger: First time energy < 20
    """
    fname = 'tutorialEnergyExplained'
    check = fname not in player.events and player.c.energy < 20
    message = "Your energy is running low! When you're tired, activities cost more effort and you'll feel worse. Make sure to rest!"

    return messageFunction(fname, message, player, check)


def tutorialMoneyExplained(player, type='message'):
    """
    Tutorial event: Explaining money system on first expense
    Trigger: First question with moneyCost
    Note: This is triggered externally when a choice with moneyCost appears
    """
    fname = 'tutorialMoneyExplained'
    check = fname not in player.events
    message = "This choice costs money! You earn money through jobs and can spend it on activities and items. Choose wisely!"

    return messageFunction(fname, message, player, check)


def tutorialRelationshipExplained(player, type='message'):
    """
    Tutorial event: Explaining relationship affinity
    Trigger: First NPC interaction
    """
    fname = 'tutorialRelationshipExplained'
    check = fname not in player.events and len(player.r) > 0 and any(hasattr(p, 'affinity') for p in player.r)
    message = "Each person has an affinity toward you that changes based on your interactions. Higher affinity means better relationships!"

    return messageFunction(fname, message, player, check)


def tutorialStatsExplained(player, type='message'):
    """
    Tutorial event: Explaining stat tracking
    Trigger: First stat change notification
    Note: This should trigger after any significant stat change
    """
    fname = 'tutorialStatsExplained'
    check = fname not in player.events and player.c.ageHours >= 2
    message = "Your choices affect your stats! Keep an eye on happiness, health, intelligence, and social skills."

    return messageFunction(fname, message, player, check)


def tutorialDiamondsEarned(player, type='message'):
    """
    Tutorial event: Explaining premium currency
    Trigger: First time earning diamonds
    Note: This should trigger right after diamonds are awarded
    """
    fname = 'tutorialDiamondsEarned'
    check = (fname not in player.events and
             hasattr(player.c, 'diamonds') and
             player.c.diamonds > 0)
    message = "You earned diamonds! These are special currency for premium choices that unlock better outcomes."

    return messageFunction(fname, message, player, check)


def tutorialGameSpeedExplained(player, type='message'):
    """
    Tutorial event: Explaining game speed controls
    Trigger: After 1 hour of game time
    """
    fname = 'tutorialGameSpeedExplained'
    check = fname not in player.events and player.c.ageHours >= 1
    message = "You can control how fast time passes! Use the speed controls to slow down during important moments or speed up during routine times."

    return messageFunction(fname, message, player, check)


def tutorialSchedulesIntro(player, type='message'):
    """
    Tutorial event: Explaining schedule system
    Trigger: First schedule added (bike lessons, swimming, etc)
    """
    fname = 'tutorialSchedulesIntro'
    check = (fname not in player.events and
             hasattr(player.c, 'schedules') and
             len(player.c.schedules) > 0)
    message = "You've started a recurring activity! This will happen automatically on scheduled days. Check your schedules to see what's coming up."

    return messageFunction(fname, message, player, check)


def tutorialEventsIntro(player, type='message'):
    """
    Tutorial event: Explaining event system
    Trigger: After 3rd event
    """
    fname = 'tutorialEventsIntro'
    check = fname not in player.events and len(player.events) >= 3
    message = "Events are how life unfolds! Some happen automatically, others require your choices. Every decision shapes your story."

    return messageFunction(fname, message, player, check)


def tutorialOneTimeEvents(player, type='message'):
    """
    Tutorial event: Explaining delayed events
    Trigger: First oneTimeEvent scheduled
    """
    fname = 'tutorialOneTimeEvents'
    check = (fname not in player.events and
             hasattr(player, 'oneTimeEvents') and
             len(player.oneTimeEvents) > 0)
    message = "Some events are scheduled for the future! Keep an eye on your calendar for upcoming moments."

    return messageFunction(fname, message, player, check)


def tutorialFirstMilestone(player, type='message'):
    """
    Tutorial event: Celebrating first major milestone
    Trigger: First major event (learned to walk, first day school, etc)
    Awards 5 diamonds
    """
    fname = 'tutorialFirstMilestone'
    # Check if player has completed any major milestone events
    major_milestones = ['learnedWalk', 'learnedBike', 'learnedSwim', 'firstDayOfSchool',
                       'lostFirstTooth', 'likeSchool', 'firstCrush', 'firstKiss']
    has_milestone = any(milestone in player.events for milestone in major_milestones)
    check = fname not in player.events and has_milestone

    if check:
        message = "Congratulations on your first major milestone! These special moments mark important progress in your life journey."
        # Award 5 diamonds
        if hasattr(player.c, 'diamonds'):
            player.c.diamonds += 5
            message += " You earned 5 diamonds!"
        return messageFunction(fname, message, player, check)


# Helper function to check if tutorial events should be triggered
def check_tutorial_triggers(player):
    """
    Check which tutorial events should be triggered based on player state

    Args:
        player: Player object

    Returns:
        list: List of event functions to call
    """
    if not is_tutorial_mode(player):
        return []

    events_to_check = []

    # Original tutorial events
    if 'firstConversation' not in player.events and len(player.r) > 0:
        events_to_check.append(firstConversation)

    if 'firstActivityChoice' not in player.events and player.c.ageYears >= 5:
        events_to_check.append(firstActivityChoice)

    if 'tutorialComplete' not in player.events and player.c.ageHours >= 24:
        events_to_check.append(tutorialComplete)

    # New tutorial events from EVENT_IDEAS_QUICK_WINS.md Section 11
    if 'tutorialGameSpeedExplained' not in player.events and player.c.ageHours >= 1:
        events_to_check.append(tutorialGameSpeedExplained)

    if 'tutorialStatsExplained' not in player.events and player.c.ageHours >= 2:
        events_to_check.append(tutorialStatsExplained)

    if 'tutorialEventsIntro' not in player.events and len(player.events) >= 3:
        events_to_check.append(tutorialEventsIntro)

    if 'tutorialEnergyExplained' not in player.events and player.c.energy < 20:
        events_to_check.append(tutorialEnergyExplained)

    if 'tutorialRelationshipExplained' not in player.events and len(player.r) > 0:
        events_to_check.append(tutorialRelationshipExplained)

    if 'tutorialDiamondsEarned' not in player.events and hasattr(player.c, 'diamonds') and player.c.diamonds > 0:
        events_to_check.append(tutorialDiamondsEarned)

    if 'tutorialSchedulesIntro' not in player.events and hasattr(player.c, 'schedules') and len(player.c.schedules) > 0:
        events_to_check.append(tutorialSchedulesIntro)

    if 'tutorialOneTimeEvents' not in player.events and hasattr(player, 'oneTimeEvents') and len(player.oneTimeEvents) > 0:
        events_to_check.append(tutorialOneTimeEvents)

    # tutorialFirstMilestone has its own complex check
    events_to_check.append(tutorialFirstMilestone)

    # tutorialMoneyExplained is triggered externally when a choice with moneyCost appears
    # but we can also check it here
    events_to_check.append(tutorialMoneyExplained)

    return events_to_check
