"""
Integration tests for BaoLife character lifecycle.

Tests the full lifecycle from birth through childhood, adulthood, and death.
"""
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))

import pytest
from cli_runner import HeadlessGame
from tests.fixtures.player_fixtures import create_newborn_player, create_adult_player
from tests.fixtures.scenario_fixtures import (
    scenario_first_day_of_school, scenario_birthday_celebration
)


class TestBirthAndEarlyLife:
    """Tests for birth and early life stages."""

    def test_newborn_starts_alive(self):
        """Test that newborn starts with alive status."""
        player = create_newborn_player()

        assert player.c.status == "alive"
        assert player.c.ageYears == 0
        assert player.c.ageDays == 0

    def test_first_day_message(self):
        """Test that first day of life triggers message."""
        player = create_newborn_player()
        player.c.ageDays = 0
        player.c.firstname = "TestBaby"

        with HeadlessGame(player=player) as game:
            # Advance to first day
            game.advance_hours(24)

            # Check for first day event
            assert game.player.c.ageDays == 1

    def test_age_progression_first_year(self):
        """Test age progression through first year."""
        player = create_newborn_player()
        player.c.ageDays = 0

        with HeadlessGame(player=player) as game:
            # Advance 30 days
            game.advance_days(30)

            assert game.player.c.ageDays == 30
            assert game.player.c.ageYears == 0  # Still less than 1 year


class TestChildhood:
    """Tests for childhood stage."""

    def test_school_age_child(self):
        """Test child at school age."""
        from tests.fixtures.player_fixtures import create_child_player

        player = create_child_player(age_years=8)

        assert player.c.ageYears == 8
        assert player.c.occupation == 'elementary school'

    def test_first_day_of_school_scenario(self):
        """Test first day of school scenario."""
        player = scenario_first_day_of_school()

        with HeadlessGame(player=player) as game:
            # Should be at school
            assert game.player.c.location == 'elementary_school_1'

            # Advance through school day
            game.advance_hours(6)

            # Should still be alive and functioning
            assert game.player.c.status == "alive"


class TestAdulthood:
    """Tests for adulthood stage."""

    def test_adult_has_job(self):
        """Test that adult has job-related attributes."""
        player = create_adult_player(occupation='Engineer')

        assert player.c.ageYears >= 18
        assert player.c.occupation == 'Engineer'

    def test_adult_daily_routine(self):
        """Test adult daily routine."""
        player = create_adult_player()

        with HeadlessGame(player=player) as game:
            # Run for one day
            game.advance_days(1)

            # Should have completed daily activities
            assert game.player.c.status == "alive"


class TestBirthdays:
    """Tests for birthday events."""

    def test_birthday_increments_age(self):
        """Test that birthdays increment age years."""
        player = create_newborn_player()
        player.c.ageDays = 364  # One day before birthday
        player.c.ageYears = 0

        with HeadlessGame(player=player) as game:
            # Advance past birthday
            game.advance_days(2)

            assert game.player.c.ageYears == 1

    def test_birthday_celebration_scenario(self):
        """Test birthday celebration scenario."""
        player = scenario_birthday_celebration(age_years=25)

        with HeadlessGame(player=player) as game:
            # Should be happy on birthday
            assert game.player.c.happiness >= 90


class TestDeath:
    """Tests for death mechanics."""

    def test_death_chance_increases_with_age(self):
        """Test that death chance increases with age."""
        from functions import updateDeathChance

        young_player = create_adult_player(age_years=25)
        old_player = create_adult_player(age_years=90)

        young_chance = updateDeathChance(young_player.c)
        old_chance = updateDeathChance(old_player.c)

        assert old_chance > young_chance

    def test_death_at_extreme_age(self):
        """Test that characters die at extreme age."""
        player = create_adult_player(age_years=121)

        with HeadlessGame(player=player) as game:
            # Advance one day (should trigger death check)
            game.advance_days(1)

            # Character over 120 should die
            assert game.player.c.status == "dead"

    def test_dead_character_stops_aging(self):
        """Test that dead characters don't continue aging."""
        player = create_adult_player()
        player.c.status = "dead"
        player.c.ageDays = 100

        with HeadlessGame(player=player) as game:
            # Try to advance time
            game.advance_days(1)

            # Dead character shouldn't age further
            # (game loop should handle death)
            assert game.player.c.status == "dead"


class TestLifeProgression:
    """Tests for full life progression."""

    def test_rapid_aging_simulation(self):
        """Test rapidly aging a character through life stages."""
        player = create_newborn_player()
        player.c.firstname = "FastAger"

        with HeadlessGame(player=player) as game:
            # Age through childhood (simulate 10 years)
            # Note: This might be slow, so we'll do a shorter test
            game.advance_days(365)  # 1 year

            assert game.player.c.ageYears >= 1
            assert game.player.c.status == "alive"

    def test_multiple_birthdays(self):
        """Test multiple birthday transitions."""
        player = create_newborn_player()
        player.c.ageDays = 360

        with HeadlessGame(player=player) as game:
            # Age through 3 birthdays
            game.advance_days(365 * 3)

            assert game.player.c.ageYears >= 3
