from pyscript import display, document # type: ignore
from engine import GameEngine
from models import GameState
from data import GAME_MAP
import random

state = GameState()
engine = GameEngine(GAME_MAP)

def log_message(text, class_name=""):
    terminal = document.getElementById("terminal")
    new_line = document.createElement("div")
    if class_name:
        new_line.classList.add(class_name)
    new_line.innerText = text
    terminal.appendChild(new_line)
    terminal.scrollTop = terminal.scrollHeight

def handle_keydown(event):
    if event.key == "Enter":
        process_input()

def handle_combat(choice):
    """戦闘ロジックの実行"""
    player_moves = {
        "1": {"name": "殴る", "strong_against": "A"},
        "2": {"name": "ナイフで刺す", "strong_against": "B"},
        "3": {"name": "掴む", "strong_against": "C"}
    }
    enemy_moves = {
        "A": {"name": "噛みつき", "strong_against": "3"},
        "B": {"name": "つかみかかり", "strong_against": "1"},
        "C": {"name": "殴りかかり", "strong_against": "2"}
    }

    if choice not in player_moves:
        return "⚠️ 1, 2, 3 のいずれかを入力してください。"

    enemy_choice = random.choice(["A", "B", "C"])
    res = f"\n>> あなた: {player_moves[choice]['name']} / 敵: {enemy_moves[enemy_choice]['name']}\n"

    if player_moves[choice]["strong_against"] == enemy_choice:
        res += "✨ クリーンヒット！ダメージを与えた！"
        state.player_wins += 1
    elif enemy_moves[enemy_choice]["strong_against"] == choice:
        res += "💢 痛恨！ダメージを受けた！"
        state.enemy_wins += 1
    else:
        res += "🛡️ 相殺された！"

    res += f"\n(状況: あなた {state.player_wins}勝 / 敵 {state.enemy_wins}勝)"

    if state.player_wins >= 3:
        res += "\n\n🔥 勝利！怪物を撃破した！書斎の方で地響きと共に大きな音がしました。\n"
        state.in_combat = False
        GAME_MAP["hallway"]["puzzle_state"]["painting_damaged"] = True
        res += state.get_description(GAME_MAP)
    elif state.enemy_wins >= 3:
        res += "\n\n💀 敗北... あなたは力尽き、館の闇に飲み込まれていきました...\n"
        state.lost_battle = True 
        state.current_room = "entrance" 
        
        # 所持していたナイフを玄関ホールに落とす
        if "knife" in state.inventory:
            state.inventory.remove("knife")
            if "knife" not in GAME_MAP["entrance"]["items"]:
                GAME_MAP["entrance"]["items"].append("knife")

        state.in_combat = False # 戦闘状態を解除
        state.player_wins = 0 # 勝敗数をリセット
        state.enemy_wins = 0 # 勝敗数をリセット
        res += state.get_description(GAME_MAP)
    return res

def display_menu():
    """現在可能な行動を選択肢として表示する"""
    if state.game_over or state.in_combat:
        return

    options = []
    room = GAME_MAP[state.current_room]

    # 1. 移動肢
    for direction in room["exits"]:
        options.append({"label": f"移動: {direction}", "cmd": f"go {direction}"})
    # 2. 拾う
    for item in room["items"]:
        options.append({"label": f"拾う: {item}", "cmd": f"take {item}"})
    # 3. 使う（所持品）
    for item in state.inventory:
        options.append({"label": f"使う: {item}", "cmd": f"use {item}"})
    # 4. 見る
    options.append({"label": "周囲を調べる", "cmd": "look"})

    state.current_options = options
    
    menu_msg = "\n【行動を選択してください】\n"
    for i, opt in enumerate(options, 1):
        menu_msg += f"{i}: {opt['label']}\n"
    log_message(menu_msg)

def process_input(event=None):
    input_el = document.getElementById("user-input")
    command = input_el.value.strip()
    if not command:
        return
    
    input_el.value = ""
    log_message(f"\n> {command}", "system-msg")
    
    if state.game_over:
        log_message("ゲームは終了しています。リロードして最初から始めてください。")
        return

    # 戦闘中の処理
    if state.in_combat:
        output = handle_combat(command)
        log_message(output)
        if not state.in_combat and not state.game_over:
            display_menu()
        return

    # 選択肢（数字）の処理
    actual_command = ""
    if command.isdigit():
        idx = int(command) - 1
        if 0 <= idx < len(state.current_options):
            actual_command = state.current_options[idx]["cmd"]
        else:
            log_message("⚠️ 無効な番号です。リストにある数字を入力してください。")
            return
    else:
        # 直接入力も一応許容する場合
        actual_command = command

    verb, args = engine.parse_command(actual_command)
    
    if verb == "help":
        output = "コマンド例: look, go [方向], take [アイテム], use [アイテム], inventory"
    elif verb == "go":
        output = engine.move(state, args[0]) if args else "どこへ移動しますか？"
        # 廊下に入った際の自動戦闘エンカウント
        if not state.game_over and state.current_room == "hallway" and not GAME_MAP["hallway"]["puzzle_state"].get("painting_damaged"):
            state.in_combat = True
            state.player_wins = 0
            state.enemy_wins = 0
            output += "\n\n😱 廊下に足を踏み入れた瞬間、あの影が再び立ちはだかりました！\n戦闘開始！(1:殴る, 2:刺す, 3:掴む)"
    elif verb == "use":
        output, changed = engine.use(state, " ".join(args))
    elif verb in ["look", "examine"]:
        output = state.get_description(GAME_MAP)
    elif verb == "take":
        output = engine.take(state, " ".join(args)) if args else "何を拾いますか？"
    elif verb in ["inventory", "i"]:
        output = engine.get_inventory_text(state)
    else:
        output = "⚠️ 無効なコマンドです。"

    log_message(output)
    
    if state.current_room == "study_room" and engine.world_map["study_room"]["puzzle_state"].get("puzzle_solved"):
        ending_msg = "\n=========================================\n"
        ending_msg += "✨ 終幕：光差す世界へ ✨\n"
        ending_msg += "-----------------------------------------\n\n"
        ending_msg += "隠し扉の先には、長く暗い階段が続いていました。\n"
        ending_msg += "一段ずつ踏みしめるたび、背後で館の呪縛が遠のいていくのを感じます。\n"
        ending_msg += "やがて、重い鉄の扉を力いっぱい押し開けると、そこには眩いばかりの朝日が広がっていました。\n\n"
        ending_msg += "冷たい館の空気とは違う、暖かな風が優しく頬を撫でます。\n"
        ending_msg += "あなたはついに、あの失われた館から真の自由を手に入れたのです。\n\n"
        ending_msg += "背後で館の影が静かに消え去るのを感じます。\n"
        ending_msg += "影が笑っています。あなたの顔であなたの姿で。。。\n\n"
        ending_msg += "「次の犠牲者をお待ちしております」遠くで笑い声を聞いたような気がしました。\n\n"
        ending_msg += "あなたは、もう振り向かず、前へ進むことを決意しました。\n\n"

        ending_msg += "🎉 脱出成功！ Game Clear. プレイありがとうございました！\n"
        log_message(ending_msg)
        state.game_over = True
    else:
        # 次のターンに向けたメニュー表示
        display_menu()

log_message(state.get_description(GAME_MAP))
display_menu() # 初回メニュー表示