"""
Tier 3 E2E Tests: Cross-Feature State Interleaving & Pairwise Combinations.
Tests interactions between Party, Teleport, Town Portal, Quarantine, and Loot systems.
"""

from __future__ import annotations
import math
import pytest
from tests.e2e_social_party.test_harness import (
    GroundLootDrop,
    GuildMemberPresenceDTO,
    GuildRosterService,
    LootAllocationMode,
    PartyScalingCalculator,
    PartyService,
    SocialService,
    TargetType,
    TeleportService,
    TownPortalEngine,
)


@pytest.fixture
def cross_env():
    party_svc = PartyService()
    social_svc = SocialService()
    guild_svc = GuildRosterService()
    teleport_svc = TeleportService(party_svc, social_svc, guild_svc)
    portal_engine = TownPortalEngine()
    return party_svc, social_svc, guild_svc, teleport_svc, portal_engine


class TestTier3CrossFeatureCombinations:
    """Tier 3: Cross-Feature State Interleaving & System Interactions."""

    def test_cross_01_party_leader_opens_portal_in_boss_fight(self, cross_env) -> None:
        """Party leader attempts to open town portal while boss encounter is in progress -> BLOCKED."""
        party_svc, _, _, _, portal_engine = cross_env
        p = party_svc.create_party("leader", "Leader", 40, "zone_boss_chamber", "inst_boss_1")
        party_svc.invite_player(p.party_id, "leader", "member1")
        party_svc.accept_invite(p.party_id, "member1", "M1", 40, "zone_boss_chamber", "inst_boss_1")

        # Engage boss
        portal_engine.set_encounter_state("inst_boss_1", boss_active=True)

        # Leader attempts portal
        ok, err, p_id = portal_engine.request_town_portal("leader", "zone_boss_chamber", "inst_boss_1", 0.0, 0.0)
        assert ok is False and p_id is None
        assert "QUARANTINE_BOSS" in err

    def test_cross_02_teleport_to_friend_in_secret_chamber_blocked(self, cross_env) -> None:
        """Party member attempts to teleport to friend who is inside a quarantined secret chamber -> BLOCKED."""
        _, social_svc, _, teleport_svc, _ = cross_env
        social_svc.send_friend_request("hero", "explorer")
        social_svc.accept_friend_request("explorer", "hero")
        social_svc.update_presence("explorer", "Explorer", 50, True, "zone_puzzle_tomb", "Mật Thất Cổ Quan")

        # Mark secret chamber active
        teleport_svc.set_zone_state("zone_puzzle_tomb", is_secret_active=True)

        ok, reason = teleport_svc.validate_destination_5_gates("hero", "explorer", TargetType.FRIEND, "zone_puzzle_tomb")
        assert ok is False
        assert "GATE_5_QUARANTINE_SECRET" in reason

    def test_cross_03_short_allocation_when_allocated_player_leaves_party(self, cross_env) -> None:
        """Item dropped for member who leaves party remains locked until 5.0s expires, then converts to FFA."""
        party_svc, _, _, _, _ = cross_env
        p = party_svc.create_party("leader", "Leader", 50)
        party_svc.invite_player(p.party_id, "leader", "leaver")
        party_svc.accept_invite(p.party_id, "leaver", "Leaver", 50)

        drop = GroundLootDrop("d_drop", "sword_unique", "leaver", drop_timestamp=100.0, allocation_mode=LootAllocationMode.SHORT)

        # Leaver leaves party
        party_svc.leave_party("leaver")

        # At t=102s (still under 5.0s): leader cannot pick up
        assert drop.can_player_pickup("leader", current_time=102.0) is False

        # At t=105.1s (timer expired): converts to FFA, leader can pick up
        assert drop.can_player_pickup("leader", current_time=105.1) is True

    def test_cross_04_map_death_reentry_restores_six_player_scaling(self, cross_env) -> None:
        """Member dies in 6-player map, consumes charge on death, returns via portal, restoring full EXP & Loot bonuses."""
        party_svc, _, _, _, portal_engine = cross_env
        p = party_svc.create_party("p1", "Leader", 60, "zone_map_t16", "inst_t16")
        for i in range(2, 7):
            party_svc.invite_player(p.party_id, "p1", f"p{i}")
            party_svc.accept_invite(p.party_id, f"p{i}", f"M{i}", 60, "zone_map_t16", "inst_t16")

        portal_engine.register_astral_map_device("inst_t16", initial_charges=6)

        # Player 6 dies in map
        portal_engine.on_player_death("p6", "zone_map_t16", "inst_t16", is_map_instance=True)
        assert portal_engine.map_charges["inst_t16"] == 5

        # While dead/in hideout, nearby party in map drops to 5 members
        p.members["p6"].zone_id = "zone_player_hideout"
        nearby_5 = party_svc.get_nearby_members("p1", radius=15.0)
        assert len(nearby_5) == 5
        i_qty5, _, _ = PartyScalingCalculator.calculate_loot_multipliers(len(nearby_5))
        assert math.isclose(i_qty5, 3.0)  # 1.0 + 0.50 * 4 = 3.0

        # Player 6 enters portal from hideout -> consumes charge (5 -> 4)
        ok, _, rem = portal_engine.enter_map_portal("inst_t16")
        assert ok is True and rem == 4

        # Returns to 15m radius
        p.members["p6"].zone_id = "zone_map_t16"
        p.members["p6"].x, p.members["p6"].y = 0.0, 0.0
        nearby_6 = party_svc.get_nearby_members("p1", radius=15.0)
        assert len(nearby_6) == 6
        i_qty6, _, _ = PartyScalingCalculator.calculate_loot_multipliers(len(nearby_6))
        assert math.isclose(i_qty6, 3.5)  # Restored to 3.5x (+250%)

    def test_cross_05_concurrent_guild_teleport_and_town_portal_channel(self, cross_env) -> None:
        """Simultaneous channeling of guild teleport and town portal creation operates cleanly without cross-talk."""
        party_svc, social_svc, guild_svc, teleport_svc, portal_engine = cross_env
        p = party_svc.create_party("alice", "Alice", 40, "zone_wild", "inst_w")
        party_svc.invite_player(p.party_id, "alice", "bob")
        party_svc.accept_invite(p.party_id, "bob", "Bob", 40, "zone_wild", "inst_w")

        # Register guildmate for Bob
        guild_mate = GuildMemberPresenceDTO("charlie", "Charlie", 42, "Huynh Đệ", True, "zone_sanctuary")
        guild_svc.register_member("outcasts", guild_mate)

        # Alice starts town portal request
        ok_portal, _, p_id = portal_engine.request_town_portal("alice", "zone_wild", "inst_w", 10.0, 10.0)
        assert ok_portal is True and p_id is not None

        # Bob starts teleport channel to guildmate Charlie
        ok_tp, chan_id = teleport_svc.start_teleport_channel("bob", TargetType.GUILDMATE, "charlie", "zone_sanctuary")
        assert ok_tp is True and chan_id.startswith("chan_bob_")

        # Complete Bob's channel after 3.5s
        ok_comp, target_zone = teleport_svc.complete_channel("bob", elapsed_time=3.5)
        assert ok_comp is True and target_zone == "zone_sanctuary"

        # Alice's portal remains intact
        assert portal_engine.portals[p_id]["is_active"] is True
