"""
Code example generation for learning.

This module contains functions to generate educational code examples
for common Python concepts that beginners need to learn.
"""

from typing import Dict, Optional


# Database of code examples for different Python concepts
CODE_EXAMPLES: Dict[str, Dict[str, str]] = {
    "variables": {
        "title": "Переменные и типы данных",
        "description": "Основы работы с переменными в Python",
        "code": '''# Основные типы данных в Python

# Строки (str)
name = "Анна"
message = 'Привет, мир!'
multiline = """Это многострочная
строка в Python"""

# Числа
age = 25                    # Целое число (int)
height = 1.75              # Число с плавающей точкой (float)
temperature = -5.5         # Отрицательное число

# Логические значения (bool)
is_student = True
is_working = False

# Вывод информации о переменных
print(f"Имя: {name}, тип: {type(name)}")
print(f"Возраст: {age}, тип: {type(age)}")
print(f"Рост: {height}, тип: {type(height)}")
print(f"Студент: {is_student}, тип: {type(is_student)}")

# Преобразование типов
age_str = str(age)         # Число в строку
height_int = int(height)   # Дробное в целое (обрезает дробную часть)
number_from_str = int("42") # Строка в число

print(f"Возраст как строка: '{age_str}'")
print(f"Рост как целое: {height_int}")
print(f"Число из строки: {number_from_str}")'''
    },
    
    "lists": {
        "title": "Списки и операции с ними",
        "description": "Работа со списками - основной структурой данных Python",
        "code": '''# Создание и работа со списками

# Создание списков
fruits = ["яблоко", "банан", "апельсин"]
numbers = [1, 2, 3, 4, 5]
mixed_list = ["текст", 42, True, 3.14]
empty_list = []

print("Исходный список фруктов:", fruits)

# Доступ к элементам (индексация начинается с 0)
first_fruit = fruits[0]      # Первый элемент
last_fruit = fruits[-1]      # Последний элемент
print(f"Первый фрукт: {first_fruit}")
print(f"Последний фрукт: {last_fruit}")

# Добавление элементов
fruits.append("груша")       # Добавить в конец
fruits.insert(1, "киви")     # Вставить на позицию 1
print("После добавления:", fruits)

# Удаление элементов
fruits.remove("банан")       # Удалить по значению
removed_fruit = fruits.pop() # Удалить и вернуть последний элемент
print(f"Удален фрукт: {removed_fruit}")
print("После удаления:", fruits)

# Полезные операции
print(f"Количество фруктов: {len(fruits)}")
print(f"Есть ли яблоко: {'яблоко' in fruits}")

# Срезы (slicing)
first_two = fruits[:2]       # Первые два элемента
last_two = fruits[-2:]       # Последние два элемента
print(f"Первые два: {first_two}")
print(f"Последние два: {last_two}")

# Итерация по списку
print("Все фрукты:")
for i, fruit in enumerate(fruits):
    print(f"{i + 1}. {fruit}")'''
    },
    
    "dictionaries": {
        "title": "Словари для хранения данных",
        "description": "Словари позволяют хранить данные в формате ключ-значение",
        "code": '''# Создание и работа со словарями

# Создание словаря
student = {
    "name": "Алексей",
    "age": 20,
    "course": 2,
    "subjects": ["математика", "физика", "программирование"]
}

print("Информация о студенте:")
print(student)

# Доступ к значениям
student_name = student["name"]           # Прямой доступ
student_age = student.get("age", 0)      # Безопасный доступ с значением по умолчанию
student_gpa = student.get("gpa")         # Вернет None, если ключа нет

print(f"Имя: {student_name}")
print(f"Возраст: {student_age}")
print(f"Средний балл: {student_gpa or 'не указан'}")

# Добавление и изменение данных
student["gpa"] = 4.5                     # Добавить новый ключ
student["age"] = 21                      # Изменить существующий
student["subjects"].append("английский") # Изменить список внутри словаря

print("\\nОбновленная информация:")
print(student)

# Проверка наличия ключей
if "email" in student:
    print(f"Email: {student['email']}")
else:
    print("Email не указан")

# Итерация по словарю
print("\\nВся информация о студенте:")
for key, value in student.items():
    if key == "subjects":
        print(f"{key}: {', '.join(value)}")
    else:
        print(f"{key}: {value}")

# Получение всех ключей и значений
all_keys = list(student.keys())
all_values = list(student.values())
print(f"\\nВсе ключи: {all_keys}")
print(f"Количество полей: {len(student)}")'''
    },
    
    "functions": {
        "title": "Функции для организации кода",
        "description": "Функции помогают организовать код и избежать повторений",
        "code": '''# Определение и использование функций

def greet(name):
    """Простая функция приветствия."""
    return f"Привет, {name}!"

def calculate_area(length, width):
    """Вычисляет площадь прямоугольника."""
    area = length * width
    return area

def create_user_profile(name, age, city="Не указан"):
    """
    Создает профиль пользователя.
    
    Args:
        name: Имя пользователя
        age: Возраст пользователя  
        city: Город (необязательный параметр)
    
    Returns:
        Словарь с информацией о пользователе
    """
    profile = {
        "name": name,
        "age": age,
        "city": city,
        "is_adult": age >= 18
    }
    return profile

# Использование функций
print(greet("Мария"))

room_area = calculate_area(5, 4)
print(f"Площадь комнаты: {room_area} кв.м")

# Создание профилей пользователей
user1 = create_user_profile("Иван", 25, "Москва")
user2 = create_user_profile("Анна", 17)  # Город не указан

print("\\nПрофиль пользователя 1:")
for key, value in user1.items():
    print(f"  {key}: {value}")

print("\\nПрофиль пользователя 2:")
for key, value in user2.items():
    print(f"  {key}: {value}")

# Функция с несколькими возвращаемыми значениями
def get_name_parts(full_name):
    """Разделяет полное имя на части."""
    parts = full_name.split()
    first_name = parts[0] if len(parts) > 0 else ""
    last_name = parts[-1] if len(parts) > 1 else ""
    return first_name, last_name

first, last = get_name_parts("Петр Иванович Сидоров")
print(f"\\nИмя: {first}, Фамилия: {last}")'''
    },
    
    "loops": {
        "title": "Циклы для повторения действий",
        "description": "Циклы позволяют выполнять код многократно",
        "code": '''# Различные виды циклов в Python

# Цикл for для итерации по последовательности
print("=== Цикл FOR ===")

# Итерация по списку
colors = ["красный", "зеленый", "синий"]
print("Цвета:")
for color in colors:
    print(f"  - {color}")

# Итерация по строке
word = "Python"
print(f"\\nБуквы в слове '{word}':")
for letter in word:
    print(f"  {letter}")

# Использование range() для числовых последовательностей
print("\\nЧисла от 1 до 5:")
for i in range(1, 6):
    print(f"  Число: {i}")

# Enumerate для получения индекса и значения
print("\\nЦвета с номерами:")
for index, color in enumerate(colors, 1):
    print(f"  {index}. {color}")

# Цикл while для повторения пока условие истинно
print("\\n=== Цикл WHILE ===")

count = 0
print("Обратный отсчет:")
while count < 5:
    print(f"  {5 - count}")
    count += 1
print("  Пуск!")

# Практический пример: поиск в списке
numbers = [2, 7, 1, 8, 3, 9, 4]
target = 8
found_index = -1

print(f"\\nПоиск числа {target} в списке {numbers}:")
for i, number in enumerate(numbers):
    if number == target:
        found_index = i
        break  # Прерываем цикл при нахождении

if found_index != -1:
    print(f"  Число {target} найдено на позиции {found_index}")
else:
    print(f"  Число {target} не найдено")

# Вложенные циклы
print("\\n=== Вложенные циклы ===")
print("Таблица умножения 3x3:")
for i in range(1, 4):
    for j in range(1, 4):
        result = i * j
        print(f"  {i} × {j} = {result}")
    print()  # Пустая строка после каждой строки таблицы'''
    },
    
    "conditionals": {
        "title": "Условные конструкции",
        "description": "Условия позволяют выполнять разный код в зависимости от ситуации",
        "code": '''# Условные конструкции в Python

# Простое условие if
age = 18
print("=== Простые условия ===")

if age >= 18:
    print("Вы совершеннолетний")
else:
    print("Вы несовершеннолетний")

# Множественные условия if-elif-else
score = 85
print(f"\\nОценка за тест: {score}")

if score >= 90:
    grade = "Отлично"
elif score >= 80:
    grade = "Хорошо"
elif score >= 70:
    grade = "Удовлетворительно"
else:
    grade = "Неудовлетворительно"

print(f"Результат: {grade}")

# Логические операторы
temperature = 22
is_sunny = True
print(f"\\nТемпература: {temperature}°C, Солнечно: {is_sunny}")

if temperature > 20 and is_sunny:
    print("Отличная погода для прогулки!")
elif temperature > 20 or is_sunny:
    print("Неплохая погода")
else:
    print("Лучше остаться дома")

# Проверка принадлежности
fruits = ["яблоко", "банан", "апельсин"]
user_choice = "банан"

if user_choice in fruits:
    print(f"\\n{user_choice} есть в наличии")
else:
    print(f"\\n{user_choice} нет в наличии")

# Проверка типа данных
value = "123"
print(f"\\nЗначение: '{value}'")

if isinstance(value, str):
    if value.isdigit():
        number = int(value)
        print(f"Это строка с числом: {number}")
    else:
        print("Это обычная строка")
elif isinstance(value, int):
    print("Это целое число")
else:
    print("Это что-то другое")

# Тернарный оператор (краткая форма if-else)
number = 7
result = "четное" if number % 2 == 0 else "нечетное"
print(f"\\nЧисло {number} - {result}")

# Практический пример: валидация пользовательского ввода
username = "user123"
password = "mypassword"

print(f"\\nПроверка данных пользователя:")
print(f"Логин: {username}")

# Проверка логина
if len(username) < 3:
    print("❌ Логин слишком короткий (минимум 3 символа)")
elif len(username) > 20:
    print("❌ Логин слишком длинный (максимум 20 символов)")
elif not username.isalnum():
    print("❌ Логин должен содержать только буквы и цифры")
else:
    print("✅ Логин корректный")

# Проверка пароля
if len(password) < 8:
    print("❌ Пароль слишком короткий (минимум 8 символов)")
elif password.lower() == password:
    print("⚠️  Пароль должен содержать заглавные буквы")
else:
    print("✅ Пароль достаточно сложный")'''
    },
    
    "file_operations": {
        "title": "Работа с файлами",
        "description": "Чтение и запись файлов - важная часть многих программ",
        "code": '''# Работа с файлами в Python

# Запись в файл
print("=== Запись в файл ===")

# Создание и запись текстового файла
filename = "example.txt"
content = """Это пример файла.
Он содержит несколько строк текста.
Python делает работу с файлами простой!"""

# Безопасная запись с автоматическим закрытием файла
with open(filename, 'w', encoding='utf-8') as file:
    file.write(content)
    
print(f"Файл '{filename}' создан и записан")

# Чтение файла
print("\\n=== Чтение файла ===")

try:
    with open(filename, 'r', encoding='utf-8') as file:
        file_content = file.read()
        print("Содержимое файла:")
        print(file_content)
except FileNotFoundError:
    print(f"Файл '{filename}' не найден")

# Чтение файла построчно
print("\\n=== Чтение по строкам ===")

try:
    with open(filename, 'r', encoding='utf-8') as file:
        line_number = 1
        for line in file:
            print(f"Строка {line_number}: {line.strip()}")
            line_number += 1
except FileNotFoundError:
    print(f"Файл '{filename}' не найден")

# Добавление в существующий файл
print("\\n=== Добавление в файл ===")

additional_content = "\\nЭта строка добавлена позже."

with open(filename, 'a', encoding='utf-8') as file:
    file.write(additional_content)
    
print("Содержимое добавлено в файл")

# Чтение обновленного файла
with open(filename, 'r', encoding='utf-8') as file:
    updated_content = file.read()
    print("\\nОбновленное содержимое:")
    print(updated_content)

# Работа с CSV-подобными данными
print("\\n=== Работа с данными ===")

# Создание файла с данными о студентах
students_data = """Имя,Возраст,Курс
Анна,20,2
Борис,19,1
Вера,21,3
Григорий,22,4"""

with open("students.txt", 'w', encoding='utf-8') as file:
    file.write(students_data)

# Чтение и обработка данных
print("Список студентов:")
with open("students.txt", 'r', encoding='utf-8') as file:
    lines = file.readlines()
    
    # Пропускаем заголовок (первую строку)
    for line in lines[1:]:
        name, age, course = line.strip().split(',')
        print(f"  {name}: {age} лет, {course} курс")

# Безопасная работа с файлами
print("\\n=== Безопасная работа ===")

def safe_read_file(filepath):
    """Безопасное чтение файла с обработкой ошибок."""
    try:
        with open(filepath, 'r', encoding='utf-8') as file:
            return file.read()
    except FileNotFoundError:
        return f"Ошибка: файл '{filepath}' не найден"
    except PermissionError:
        return f"Ошибка: нет прав для чтения файла '{filepath}'"
    except Exception as e:
        return f"Неожиданная ошибка: {e}"

# Тестирование безопасной функции
result1 = safe_read_file("example.txt")
result2 = safe_read_file("nonexistent.txt")

print("Результат чтения существующего файла:")
print(result1[:50] + "..." if len(result1) > 50 else result1)
print("\\nРезультат чтения несуществующего файла:")
print(result2)'''
    }
}


def generate_example(concept: str) -> str:
    """
    Generate a code example for a Python concept.
    
    Args:
        concept: The Python concept to generate an example for.
                Available concepts: variables, lists, dictionaries, functions, 
                loops, conditionals, file_operations
    
    Returns:
        A formatted code example as a string, or an error message if concept not found.
    """
    concept_lower = concept.lower().strip()
    
    if concept_lower not in CODE_EXAMPLES:
        available_concepts = ", ".join(CODE_EXAMPLES.keys())
        return f"❌ Концепция '{concept}' не найдена.\n📚 Доступные концепции: {available_concepts}"
    
    example_data = CODE_EXAMPLES[concept_lower]
    
    result = f"""
{'=' * 60}
📖 {example_data['title']}
{'=' * 60}

📝 Описание: {example_data['description']}

💻 Пример кода:

{example_data['code']}

{'=' * 60}
💡 Совет: Попробуйте запустить этот код и поэкспериментировать с ним!
{'=' * 60}
"""
    return result.strip()


def list_available_concepts() -> list:
    """
    Get a list of all available code example concepts.
    
    Returns:
        List of available concept names
    """
    return list(CODE_EXAMPLES.keys())


def get_concept_info(concept: str) -> Optional[Dict[str, str]]:
    """
    Get information about a specific concept.
    
    Args:
        concept: The concept to get information for
        
    Returns:
        Dictionary with concept information or None if not found
    """
    concept_lower = concept.lower().strip()
    
    if concept_lower not in CODE_EXAMPLES:
        return None
    
    return {
        "title": CODE_EXAMPLES[concept_lower]["title"],
        "description": CODE_EXAMPLES[concept_lower]["description"]
    }