import difflib
import subprocess
import sys

def main():
    # 1. Generate diff for server/world/hideout_engine.py
    with open("server/world/hideout_engine.py", "r", encoding="utf-8") as f:
        orig_engine = f.readlines()

    # Locate enter_map_portal
    start_idx = None
    for i, line in enumerate(orig_engine):
        if "def enter_map_portal(" in line:
            start_idx = i
            break
    assert start_idx is not None, "Could not find enter_map_portal"

    # Find the end of enter_map_portal (line before configure_world_gate)
    end_idx = None
    for i in range(start_idx, len(orig_engine)):
        if "def configure_world_gate(" in orig_engine[i]:
            end_idx = i
            break
    assert end_idx is not None, "Could not find configure_world_gate"

    # Target new enter_map_portal content
    new_method = """    def enter_map_portal(
        self,
        player_id: str,
        portal_index: Optional[int] = None,
        zone_engine: Optional[Any] = None,
    ) -> Tuple[bool, str, Optional[Dict[str, Any]]]:
        \"\"\"
        Enters an active Map Device portal.
        Consumes exactly 1 portal from the remaining 6 charges.
        When 0 portals remain, the map instance is sealed permanently.
        \"\"\"
        if portal_index is not None and not isinstance(portal_index, int) and zone_engine is None:
            zone_engine = portal_index
            portal_index = None

        hideout = self.get_or_create_hideout(player_id)
        dev = hideout.map_device

        if not dev.active_map or dev.portals_remaining <= 0 or not dev.active_instance_id:
            return False, "Thiên Đạo Tinh Đồ Nghi hiện không có Cổng nào mở hoặc đã hết lượt vào (0/6)!", None

        # Choose portal index to close
        target_idx = -1
        if portal_index is not None and 0 <= portal_index < 6 and dev.portal_states[portal_index]:
            target_idx = portal_index
        else:
            # Pick first available open portal
            for i, is_open in enumerate(dev.portal_states):
                if is_open:
                    target_idx = i
                    break

        if target_idx == -1:
            return False, "Không tìm thấy Cổng khả dụng trên Tinh Đồ Nghi!", None

        # Consume 1 portal charge
        dev.portal_states[target_idx] = False
        dev.portals_remaining -= 1

        result = {
            "instance_id": dev.active_instance_id,
            "map_name": dev.active_map.name,
            "tier": dev.active_map.tier,
            "target_zone_template": dev.active_map.zone_template_id,
            "spawn_x": 0.0,
            "spawn_y": 0.0,
            "portals_remaining": dev.portals_remaining,
            "consumed_portal_index": target_idx,
            "portal_index": target_idx,
        }

        # If exhausted all 6 portals, close device and purge instance session from ZoneEngine
        if dev.portals_remaining == 0:
            if zone_engine is not None and hasattr(zone_engine, "active_instances"):
                if dev.active_instance_id and dev.active_instance_id in zone_engine.active_instances:
                    zone_engine.active_instances.pop(dev.active_instance_id, None)
            dev.active_map = None
            dev.active_instance_id = None
            msg = f"Đã bước qua cổng #{target_idx + 1}. Đây là CỔNG CUỐI CÙNG (0/6)! Tinh Đồ Nghi đã khép lại."
        else:
            msg = f"Đã bước qua cổng #{target_idx + 1}. Còn lại {dev.portals_remaining}/6 Cổng Tinh Đồ."

        return True, msg, result

"""
    new_engine = orig_engine[:start_idx] + [l + "\n" for l in new_method.splitlines()] + orig_engine[end_idx:]

    diff_engine = list(difflib.unified_diff(
        orig_engine,
        new_engine,
        fromfile="a/server/world/hideout_engine.py",
        tofile="b/server/world/hideout_engine.py",
        lineterm="\n"
    ))

    # 2. Generate diff for tests/unit/test_hideout_engine.py
    with open("tests/unit/test_hideout_engine.py", "r", encoding="utf-8") as f:
        orig_test = f.readlines()

    # Modify test_map_portal_consumption_lifecycle to assert dev.active_instance_id is None
    mod_test = []
    for line in orig_test:
        if '    assert "CỔNG CUỐI CÙNG" in msg_last' in line:
            mod_test.append(line)
            mod_test.append("    hideout = engine.get_or_create_hideout(player_id)\n")
            mod_test.append("    assert hideout.map_device.active_map is None\n")
            mod_test.append("    assert hideout.map_device.active_instance_id is None\n")
            mod_test.append("    assert hideout.map_device.portals_remaining == 0\n")
        elif '    assert zone_engine.can_spawn_hostile_monsters("zone_blood_scale_ruins") is True' in line:
            mod_test.append(line)
            mod_test.append("\n")
            mod_test.append("    # Enter first 5 portals with zone_engine\n")
            mod_test.append("    for _ in range(5):\n")
            mod_test.append("        ok_enter, _, _ = engine.enter_map_portal(player_id, zone_engine=zone_engine)\n")
            mod_test.append("        assert ok_enter is True\n")
            mod_test.append("        assert inst_id in zone_engine.active_instances\n")
            mod_test.append("\n")
            mod_test.append("    # Enter 6th and final portal\n")
            mod_test.append("    ok_final, msg_final, res_final = engine.enter_map_portal(player_id, zone_engine=zone_engine)\n")
            mod_test.append("    assert ok_final is True\n")
            mod_test.append("    assert res_final['portals_remaining'] == 0\n")
            mod_test.append('    assert "CỔNG CUỐI CÙNG" in msg_final\n')
            mod_test.append("\n")
            mod_test.append("    # Assert instance unregistered from ZoneEngine and active_instance_id cleared\n")
            mod_test.append("    assert inst_id not in zone_engine.active_instances\n")
            mod_test.append("    dev = engine.get_or_create_hideout(player_id).map_device\n")
            mod_test.append("    assert dev.active_instance_id is None\n")
            mod_test.append("    assert dev.active_map is None\n")
            mod_test.append("    assert dev.portals_remaining == 0\n")
        else:
            mod_test.append(line)

    diff_test = list(difflib.unified_diff(
        orig_test,
        mod_test,
        fromfile="a/tests/unit/test_hideout_engine.py",
        tofile="b/tests/unit/test_hideout_engine.py",
        lineterm="\n"
    ))

    patch_content = "".join(diff_engine) + "".join(diff_test)
    with open(".agents/teamwork/explorer_m3_r2_3/proposed_hideout_cleanup.patch", "w", encoding="utf-8", newline="\n") as f:
        f.write(patch_content)
    print("Wrote patch file successfully.")

if __name__ == "__main__":
    main()
