# app/services/it_questions.py

from typing import List, Dict, Any, Optional


def get_it_questions() -> List[Dict[str, Any]]:
    """
    Python レベルテスト 30問 (3レベル × 10問)
    初級(level=1) → 中級(level=2) → 上級(level=3)
    各レベル10問を全問正解で次のレベルへ進む。
    
    NOTE: HTML表示するため、< > は &lt; &gt; にエスケープする。
    コードブロック(```)は使わず、コード部分は太字やインデントで表現する。
    """
    return [
        # =============================================================
        # 初級 (Level 1): Python 基本概念 — 10問
        # print, 変数, データ型, 演算子, 条件文, 繰り返し
        # =============================================================
        {
            "id": 1, "level": 1,
            "question": "Pythonでコンソールに「Hello」と表示するための正しいコードはどれですか？",
            "options": ["echo('Hello')", "print('Hello')", "console.log('Hello')", "printf('Hello')"],
            "answer": "print('Hello')",
            "reason": "Pythonではprint()関数を使ってコンソールに出力します。echoはPHP、console.logはJavaScript、printfはC言語の出力方法です。"
        },
        {
            "id": 2, "level": 1,
            "question": "次のPythonコードの実行結果は？\n\n  x = 5\n  print(type(x))",
            "options": ["&lt;class 'str'&gt;", "&lt;class 'int'&gt;", "&lt;class 'float'&gt;", "&lt;class 'number'&gt;"],
            "answer": "&lt;class 'int'&gt;",
            "reason": "5は整数なので、type()関数はint（integer = 整数）を返します。"
        },
        {
            "id": 3, "level": 1,
            "question": "Pythonで変数名として使えないものはどれですか？",
            "options": ["my_name", "_count", "2nd_value", "total"],
            "answer": "2nd_value",
            "reason": "Pythonの変数名は数字で始められません。アルファベットかアンダースコア(_)で始める必要があります。"
        },
        {
            "id": 4, "level": 1,
            "question": "次のコードの実行結果は？\n\n  x = 10\n  if x &gt; 5:\n      print('大きい')\n  else:\n      print('小さい')",
            "options": ["大きい", "小さい", "エラー", "何も表示されない"],
            "answer": "大きい",
            "reason": "xは10で5より大きいため、if文の条件がTrue（真）となり「大きい」が出力されます。"
        },
        {
            "id": 5, "level": 1,
            "question": "Pythonで「等しい」を比較する演算子はどれですか？",
            "options": ["=", "==", "===", "!="],
            "answer": "==",
            "reason": "= は代入、== は比較（等しい）、!= は比較（等しくない）です。=== はPythonにはありません。"
        },
        {
            "id": 6, "level": 1,
            "question": "次のコードの実行結果は？\n\n  print(10 % 3)",
            "options": ["3", "3.33", "1", "0"],
            "answer": "1",
            "reason": "% は剰余（割り算の余り）演算子です。10 ÷ 3 = 3余り1なので、結果は1です。"
        },
        {
            "id": 7, "level": 1,
            "question": "次のコードの実行結果は？\n\n  for i in range(3):\n      print(i)",
            "options": ["1 2 3", "0 1 2", "0 1 2 3", "1 2"],
            "answer": "0 1 2",
            "reason": "range(3)は0, 1, 2を生成します（0から始まり、3の手前まで）。"
        },
        {
            "id": 8, "level": 1,
            "question": "次のwhile文はいつ終了しますか？\n\n  x = 0\n  while x &lt; 5:\n      x += 1",
            "options": ["xが4のとき", "xが5のとき", "xが6のとき", "永遠に終わらない"],
            "answer": "xが5のとき",
            "reason": "x += 1 でxが1ずつ増え、x < 5 が False（偽）になるx=5で終了します。"
        },
        {
            "id": 9, "level": 1,
            "question": "for文の途中で繰り返しを「中断」するためのキーワードは？",
            "options": ["stop", "exit", "break", "end"],
            "answer": "break",
            "reason": "breakはループを途中で完全に抜けます。continueは現在の回をスキップして次の回へ進みます。"
        },
        {
            "id": 10, "level": 1,
            "question": "次のコードの実行結果は？\n\n  data = [10, 20, 30, 40, 50]\n  print(data[2])",
            "options": ["10", "20", "30", "40"],
            "answer": "30",
            "reason": "インデックスは0から始まるため、data[0]=10, data[1]=20, data[2]=30です。"
        },

        # =============================================================
        # 中級 (Level 2): データ構造 & 関数 — 10問
        # リスト, タプル, 辞書, 集合, 関数, スライス
        # =============================================================
        {
            "id": 11, "level": 2,
            "question": "リスト a = [1, 2, 3] に要素4を追加するメソッドは？",
            "options": ["a.add(4)", "a.append(4)", "a.insert(4)", "a.push(4)"],
            "answer": "a.append(4)",
            "reason": "Pythonのリストでは append() メソッドを使って末尾に要素を追加します。pushはJavaScript、addはsetのメソッドです。"
        },
        {
            "id": 12, "level": 2,
            "question": "次のコードの実行結果は？\n\n  data = [1, 2, 3, 4, 5]\n  print(data[1:4])",
            "options": ["[1, 2, 3]", "[2, 3, 4]", "[2, 3, 4, 5]", "[1, 2, 3, 4]"],
            "answer": "[2, 3, 4]",
            "reason": "スライス[1:4]はインデックス1から3まで（4の手前）を取得します。data[1]=2, data[2]=3, data[3]=4です。"
        },
        {
            "id": 13, "level": 2,
            "question": "次のコードの実行結果は？\n\n  d = {'name': '田中', 'age': 25}\n  print(d['name'])",
            "options": ["name", "田中", "{'name': '田中'}", "エラー"],
            "answer": "田中",
            "reason": "辞書からキー'name'に対応する値を取り出すと、'田中'が返されます。"
        },
        {
            "id": 14, "level": 2,
            "question": "辞書 d = {'a': 1} に新しいキー 'b' と値 2 を追加する正しい方法は？",
            "options": ["d.add('b', 2)", "d.append('b', 2)", "d['b'] = 2", "d.insert('b', 2)"],
            "answer": "d['b'] = 2",
            "reason": "辞書では d[キー] = 値 の構文で新しいキーと値を追加します。appendやaddは使えません。"
        },
        {
            "id": 15, "level": 2,
            "question": "集合(set)の特徴として正しいものは？",
            "options": ["順序がある", "重複を許す", "重複を許さない", "キーと値のペアを持つ"],
            "answer": "重複を許さない",
            "reason": "set（集合）は重複する要素を自動的に排除し、順序も保証しません。キーと値のペアは辞書(dict)の特徴です。"
        },
        {
            "id": 16, "level": 2,
            "question": "次のコードの実行結果は？\n\n  def greet(name):\n      return f'こんにちは、{name}さん'\n\n  print(greet('佐藤'))",
            "options": ["こんにちは、nameさん", "こんにちは、佐藤さん", "エラー", "None"],
            "answer": "こんにちは、佐藤さん",
            "reason": "f文字列(f-string)で{name}に引数'佐藤'が入り、「こんにちは、佐藤さん」が返されます。"
        },
        {
            "id": 17, "level": 2,
            "question": "関数にreturn文がない場合、何が返されますか？",
            "options": ["0", "空文字列", "None", "エラーが発生する"],
            "answer": "None",
            "reason": "Pythonの関数でreturn文を省略すると、自動的にNone（何もない値）が返されます。"
        },
        {
            "id": 18, "level": 2,
            "question": "次のコードの実行結果は？\n\n  def add(a, b=10):\n      return a + b\n\n  print(add(5))",
            "options": ["5", "10", "15", "エラー"],
            "answer": "15",
            "reason": "bにはデフォルト値10が設定されているため、add(5)はa=5, b=10で計算され、5+10=15となります。"
        },
        {
            "id": 19, "level": 2,
            "question": "次のコードの実行結果は？\n\n  text = 'Hello, World'\n  print(text.split(', '))",
            "options": ["['Hello, World']", "['Hello', 'World']", "('Hello', 'World')", "エラー"],
            "answer": "['Hello', 'World']",
            "reason": "split(', ')は文字列を', '（カンマとスペース）で分割してリストを返します。"
        },
        {
            "id": 20, "level": 2,
            "question": "ファイルを読み込むとき、ファイルを自動的に閉じてくれる構文は？",
            "options": ["try/finally", "with open() as f:", "open().auto_close()", "file.read()"],
            "answer": "with open() as f:",
            "reason": "with文（コンテキストマネージャ）を使うと、ブロック終了時に自動的にファイルが閉じられます。"
        },

        # =============================================================
        # 上級 (Level 3): 応用 & OOP — 10問
        # 文字列処理, クラス, 例外処理, モジュール, リスト内包表記, ラムダ, デコレータ
        # =============================================================
        {
            "id": 21, "level": 3,
            "question": "次のコードの実行結果は？\n\n  text = '  Hello  '\n  print(text.strip())",
            "options": ["  Hello  ", "Hello  ", "  Hello", "Hello"],
            "answer": "Hello",
            "reason": "strip()は文字列の両端（前後）にある空白を取り除きます。lstrip()は左側のみ、rstrip()は右側のみです。"
        },
        {
            "id": 22, "level": 3,
            "question": "Pythonのクラスで、インスタンス生成時に自動的に呼ばれるメソッドは？",
            "options": ["__start__", "__init__", "__new__", "__create__"],
            "answer": "__init__",
            "reason": "__init__はコンストラクタ（初期化メソッド）で、インスタンス生成時に自動的に呼ばれます。"
        },
        {
            "id": 23, "level": 3,
            "question": "次のコードで、dog.name の値は？\n\n  class Dog:\n      def __init__(self, name):\n          self.name = name\n\n  dog = Dog('ポチ')",
            "options": ["Dog", "name", "ポチ", "self"],
            "answer": "ポチ",
            "reason": "__init__で self.name = name としているため、dog.name は引数で渡した'ポチ'になります。"
        },
        {
            "id": 24, "level": 3,
            "question": "クラスの「継承」の主な目的は？",
            "options": ["メモリを節約する", "既存クラスの機能を引き継いで拡張する", "変数を隠す", "プログラムを高速化する"],
            "answer": "既存クラスの機能を引き継いで拡張する",
            "reason": "継承により、既存クラス（親クラス）の属性やメソッドを新しいクラス（子クラス）で再利用・拡張できます。"
        },
        {
            "id": 25, "level": 3,
            "question": "次のコードの実行結果は？\n\n  try:\n      x = 1 / 0\n  except ZeroDivisionError:\n      print('ゼロ除算エラー')",
            "options": ["エラーでプログラムが停止", "ゼロ除算エラー", "0", "None"],
            "answer": "ゼロ除算エラー",
            "reason": "1/0はZeroDivisionErrorを発生させますが、exceptで捕捉するため、プログラムは停止せず「ゼロ除算エラー」が出力されます。"
        },
        {
            "id": 26, "level": 3,
            "question": "try/except文で、エラーの有無に関わらず必ず実行されるブロックは？",
            "options": ["else", "finally", "except", "always"],
            "answer": "finally",
            "reason": "finallyブロックは、エラーが発生してもしなくても必ず実行されます。リソースの解放などに使われます。"
        },
        {
            "id": 27, "level": 3,
            "question": "自作モジュール utils.py から関数 helper だけをインポートする正しい構文は？",
            "options": ["import helper from utils", "from utils import helper", "include utils.helper", "require('utils').helper"],
            "answer": "from utils import helper",
            "reason": "Pythonでは from モジュール名 import 関数名 の構文で特定の関数だけをインポートします。"
        },
        {
            "id": 28, "level": 3,
            "question": "次のリスト内包表記の結果は？\n\n  result = [x**2 for x in range(5) if x % 2 == 0]\n  print(result)",
            "options": ["[0, 1, 4, 9, 16]", "[0, 4, 16]", "[1, 9, 25]", "[4, 16]"],
            "answer": "[0, 4, 16]",
            "reason": "range(5)は0~4。偶数(0,2,4)の二乗を計算すると 0²=0, 2²=4, 4²=16 → [0, 4, 16]。"
        },
        {
            "id": 29, "level": 3,
            "question": "次のラムダ関数の実行結果は？\n\n  f = lambda x, y: x * y\n  print(f(3, 4))",
            "options": ["7", "12", "34", "エラー"],
            "answer": "12",
            "reason": "lambda x, y: x * y は2つの引数を掛け算する無名関数です。f(3, 4) = 3 × 4 = 12。"
        },
        {
            "id": 30, "level": 3,
            "question": "Pythonの「デコレータ」の主な役割は？",
            "options": ["変数にデフォルト値を設定する", "関数やクラスに追加の機能を付与する", "ループを高速化する", "型を変換する"],
            "answer": "関数やクラスに追加の機能を付与する",
            "reason": "デコレータ(@構文)は既存の関数を変更せずに、ログ出力や権限チェックなどの追加機能を付与する仕組みです。"
        }
    ]


def get_question_by_id(question_id: int) -> Optional[Dict[str, Any]]:
    """
    問題IDで問題を取得
    """
    questions = get_it_questions()
    for q in questions:
        if q["id"] == question_id:
            return q
    return None


def get_questions_by_level(level: int) -> List[Dict[str, Any]]:
    """
    指定レベルの問題を取得
    """
    questions = get_it_questions()
    return [q for q in questions if q["level"] == level]


def get_level_name(level: int) -> str:
    """
    レベル番号をレベル名に変換
    """
    level_names = {1: "初級", 2: "中級", 3: "上級"}
    return level_names.get(level, f"レベル{level}")
