"""
Core module for kousuan package
Provides various mental arithmetic calculation techniques
"""

import math
from typing import Union, List, Dict, Any
from kousuan.skills import SmartCalculatorEngine

def add_numbers(a: Union[int, float], b: Union[int, float]):
    """
    Add two numbers using mental math techniques

    Args:
        a: First number
        b: Second number

    Returns:
        List of calculation results with values, explanations and steps
    """
    engine = SmartCalculatorEngine()
    return engine.calculate_with_cross_validation(f"{a}+{b}")


def subtract_numbers(a: Union[int, float], b: Union[int, float]):
    """
    Subtract two numbers using mental math techniques

    Args:
        a: First number
        b: Second number

    Returns:
        List of calculation results with values, explanations and steps
    """
    engine = SmartCalculatorEngine()
    return engine.calculate(f"{a}-{b}")


def multiply_numbers(a: Union[int, float], b: Union[int, float]):
    """
    Multiply two numbers using mental math techniques

    Args:
        a: First number
        b: Second number

    Returns:
        List of calculation results with values, explanations and steps
    """
    engine = SmartCalculatorEngine()
    return engine.calculate(f"{a}*{b}")


def divide_numbers(a: Union[int, float], b: Union[int, float]):
    """
    Divide two numbers using mental math techniques

    Args:
        a: Dividend
        b: Divisor

    Returns:
        List of calculation results with values, explanations and steps

    Raises:
        ZeroDivisionError: If b is zero
    """
    if b == 0:
        raise ZeroDivisionError("Cannot divide by zero")
    
    engine = SmartCalculatorEngine()
    return engine.calculate(f"{a}÷{b}")


def calculate_percentage(value: Union[int, float], percentage: Union[int, float]):
    """
    Calculate percentage of a value

    Args:
        value: The base value
        percentage: The percentage to calculate

    Returns:
        List of calculation results with values, explanations and steps
    """
    engine = SmartCalculatorEngine()
    return engine.calculate(f"{value}*{percentage}/100")


def quick_addition(numbers: List[Union[int, float]]):
    """
    Add multiple numbers quickly using mental math techniques

    Args:
        numbers: List of numbers to add

    Returns:
        List of calculation results with values, explanations and steps
    """
    if not numbers:
        return [{"value": 0, "explanation": "Empty list", "steps": []}]
    
    engine = SmartCalculatorEngine()
    # Create addition expression for all numbers
    expression = "+".join(map(str, numbers))
    return engine.calculate(expression)


def quick_multiplication(numbers: List[Union[int, float]]):
    """
    Multiply multiple numbers quickly using mental math techniques

    Args:
        numbers: List of numbers to multiply

    Returns:
        List of calculation results with values, explanations and steps
    """
    if not numbers:
        return [{"value": 1, "explanation": "Empty list", "steps": []}]
    
    engine = SmartCalculatorEngine()
    # Create multiplication expression for all numbers
    expression = "*".join(map(str, numbers))
    return engine.calculate(expression)


def number_decomposition(number: int):
    """
    Decompose a number into its prime factors

    Args:
        number: The number to decompose

    Returns:
        List of calculation results with values, explanations and steps
    """
    if number < 2:
        return [{
            "value": [],
            "explanation": f"Numbers less than 2 have no prime factors",
            "steps": [f"Input: {number}", "No prime factors exist"]
        }]

    factors = []
    divisor = 2
    original_number = number
    steps = [f"Decomposing {original_number} into prime factors:"]

    while divisor * divisor <= number:
        while number % divisor == 0:
            factors.append(divisor)
            steps.append(f"{number} ÷ {divisor} = {number // divisor}")
            number //= divisor
        divisor += 1

    if number > 1:
        factors.append(number)
        steps.append(f"Remaining factor: {number}")

    return [{
        "value": factors,
        "explanation": f"Prime factorization of {original_number}",
        "steps": steps + [f"Prime factors: {factors}"]
    }]


def mental_math_tricks():
    """
    Provide various mental math tricks and techniques

    Returns:
        List of mental math tricks with explanations and examples
    """
    tricks_data = [
        {
            "name": "multiply_by_11",
            "explanation": "To multiply a two-digit number by 11, add the two digits and put the sum in the middle",
            "example": "23 × 11 = 2(2+3)3 = 253"
        },
        {
            "name": "multiply_by_5",
            "explanation": "To multiply by 5, multiply by 10 and divide by 2",
            "example": "36 × 5 = (36 × 10) ÷ 2 = 360 ÷ 2 = 180"
        },
        {
            "name": "multiply_by_9",
            "explanation": "To multiply by 9, multiply by 10 and subtract the number",
            "example": "47 × 9 = (47 × 10) - 47 = 470 - 47 = 423"
        },
        {
            "name": "square_ending_with_5",
            "explanation": "To square a number ending with 5, multiply the first digit by (itself+1) and append 25",
            "example": "35² = 3×4 and append 25 = 1225"
        },
        {
            "name": "percentage_calculation",
            "explanation": "To find 10% of a number, move the decimal point one place to the left",
            "example": "10% of 250 = 25.0"
        },
        {
            "name": "addition_trick",
            "explanation": "Break numbers into parts that are easier to add mentally",
            "example": "47 + 38 = (47 + 40) - 2 = 87 - 2 = 85"
        },
        {
            "name": "subtraction_trick",
            "explanation": "Use complementary numbers to make subtraction easier",
            "example": "83 - 27 = 83 - 30 + 3 = 53 + 3 = 56"
        }
    ]
    
    return [{
        "value": tricks_data,
        "explanation": "Collection of mental math tricks and techniques",
        "steps": ["Mental math techniques for faster calculations"]
    }]


def get_multiplication_table(number: int, limit: int = 10):
    """
    Generate multiplication table for a given number

    Args:
        number: The base number
        limit: The maximum multiplier (default: 10)

    Returns:
        List of calculation results with multiplication table
    """
    table = []
    steps = [f"Generating multiplication table for {number}:"]
    
    for i in range(1, limit + 1):
        expression = f"{number} × {i} = {number * i}"
        table.append(expression)
        steps.append(expression)
    
    return [{
        "value": table,
        "explanation": f"Multiplication table for {number} up to {limit}",
        "steps": steps
    }]