#include <iostream>
#include <cmath>
#include <vector>
#include <random>
#include <functional>

namespace FunctionRangeSystem {
    
    // 函数范围配置结构体
    struct FunctionRangeConfig {
        float domainStart;           // 定义域起点
        float domainEnd;             // 定义域终点
        float rangeStart;            // 值域起点  
        float rangeEnd;              // 值域终点
        float amplitude;             // 振幅（用于周期函数）
        float frequency;             // 频率
        float phaseShift;            // 相位偏移
        float verticalShift;         // 垂直偏移
        float dampingFactor;         // 阻尼因子
        float growthRate;            // 增长率
        float asymptoteValue;        // 渐近线值
        float precision;             // 计算精度
        int samplePoints;            // 采样点数量
    };

    // 函数类型枚举
    enum class FunctionType {
        LINEAR,         // 线性函数
        QUADRATIC,      // 二次函数
        EXPONENTIAL,    // 指数函数
        LOGARITHMIC,    // 对数函数
        TRIGONOMETRIC,  // 三角函数
        PIECEWISE       // 分段函数
    };

    // 线性函数计算
    float calculateLinearFunction(float x, const FunctionRangeConfig& config) {
        float slope = (config.rangeEnd - config.rangeStart) / (config.domainEnd - config.domainStart);
        return slope * (x - config.domainStart) + config.rangeStart + config.verticalShift;
    }

    // 二次函数计算
    float calculateQuadraticFunction(float x, const FunctionRangeConfig& config) {
        float a = config.amplitude;
        float vertexX = (config.domainStart + config.domainEnd) / 2.0f;
        float vertexY = (config.rangeStart + config.rangeEnd) / 2.0f;
        
        return a * std::pow(x - vertexX, 2) + vertexY + config.verticalShift;
    }

    // 指数函数计算
    float calculateExponentialFunction(float x, const FunctionRangeConfig& config) {
        float base = std::exp(config.growthRate);
        return config.amplitude * std::pow(base, x) + config.verticalShift;
    }

    // 对数函数计算
    float calculateLogarithmicFunction(float x, const FunctionRangeConfig& config) {
        if (x <= 0) return config.rangeStart; // 对数函数定义域保护
        
        return config.amplitude * std::log(x) + config.verticalShift;
    }

    // 三角函数计算（正弦）
    float calculateTrigonometricFunction(float x, const FunctionRangeConfig& config) {
        return config.amplitude * std::sin(config.frequency * x + config.phaseShift) + config.verticalShift;
    }

    // 阻尼振荡函数
    float calculateDampedOscillation(float x, const FunctionRangeConfig& config) {
        return config.amplitude * std::exp(-config.dampingFactor * x) * 
               std::sin(config.frequency * x + config.phaseShift) + config.verticalShift;
    }

    // 逻辑斯蒂函数（S型曲线）
    float calculateLogisticFunction(float x, const FunctionRangeConfig& config) {
        float L = config.rangeEnd; // 最大值
        float k = config.growthRate; // 增长率
        float x0 = (config.domainStart + config.domainEnd) / 2.0f; // 中心点
        
        return L / (1 + std::exp(-k * (x - x0))) + config.verticalShift;
    }

    // 计算函数在指定点的值
    float evaluateFunction(FunctionType type, float x, const FunctionRangeConfig& config) {
        // 检查定义域
        if (x < config.domainStart || x > config.domainEnd) {
            std::cout << "警告: 输入值 " << x << " 超出定义域 [" 
                      << config.domainStart << ", " << config.domainEnd << "]" << std::endl;
            return config.rangeStart; // 返回默认值
        }

        switch (type) {
            case FunctionType::LINEAR:
                return calculateLinearFunction(x, config);
            case FunctionType::QUADRATIC:
                return calculateQuadraticFunction(x, config);
            case FunctionType::EXPONENTIAL:
                return calculateExponentialFunction(x, config);
            case FunctionType::LOGARITHMIC:
                return calculateLogarithmicFunction(x, config);
            case FunctionType::TRIGONOMETRIC:
                return calculateTrigonometricFunction(x, config);
            default:
                return calculateLinearFunction(x, config); // 默认线性函数
        }
    }

    // 生成函数采样点
    std::vector<std::pair<float, float>> generateFunctionSamples(
        FunctionType type, 
        const FunctionRangeConfig& config) {
        
        std::vector<std::pair<float, float>> samples;
        float step = (config.domainEnd - config.domainStart) / config.samplePoints;
        
        for (int i = 0; i <= config.samplePoints; ++i) {
            float x = config.domainStart + i * step;
            float y = evaluateFunction(type, x, config);
            samples.emplace_back(x, y);
        }
        
        return samples;
    }

    // 计算函数极值点
    std::pair<float, float> findFunctionExtremum(
        FunctionType type, 
        const FunctionRangeConfig& config, 
        float searchStep = 0.1f) {
        
        float maxY = config.rangeStart;
        float minY = config.rangeEnd;
        float maxX = config.domainStart;
        float minX = config.domainStart;
        
        for (float x = config.domainStart; x <= config.domainEnd; x += searchStep) {
            float y = evaluateFunction(type, x, config);
            
            if (y > maxY) {
                maxY = y;
                maxX = x;
            }
            if (y < minY) {
                minY = y;
                minX = x;
            }
        }
        
        return std::make_pair(maxX, maxY); // 返回最大值点
    }

    // 计算函数零点（根）
    std::vector<float> findFunctionRoots(
        FunctionType type, 
        const FunctionRangeConfig& config, 
        float tolerance = 0.001f) {
        
        std::vector<float> roots;
        float step = (config.domainEnd - config.domainStart) / 1000.0f;
        float prevY = evaluateFunction(type, config.domainStart, config);
        
        for (float x = config.domainStart + step; x <= config.domainEnd; x += step) {
            float currentY = evaluateFunction(type, x, config);
            
            // 检查符号变化
            if (prevY * currentY <= 0) {
                // 使用二分法精确查找根
                float left = x - step;
                float right = x;
                
                while (right - left > tolerance) {
                    float mid = (left + right) / 2.0f;
                    float midY = evaluateFunction(type, mid, config);
                    
                    if (midY * evaluateFunction(type, left, config) <= 0) {
                        right = mid;
                    } else {
                        left = mid;
                    }
                }
                
                roots.push_back((left + right) / 2.0f);
            }
            
            prevY = currentY;
        }
        
        return roots;
    }

    // 计算函数在区间内的积分（梯形法）
    float calculateFunctionIntegral(
        FunctionType type, 
        const FunctionRangeConfig& config, 
        float integralStart, 
        float integralEnd, 
        int partitions = 1000) {
        
        if (integralStart < config.domainStart) integralStart = config.domainStart;
        if (integralEnd > config.domainEnd) integralEnd = config.domainEnd;
        
        float h = (integralEnd - integralStart) / partitions;
        float sum = 0.0f;
        
        for (int i = 0; i <= partitions; ++i) {
            float x = integralStart + i * h;
            float y = evaluateFunction(type, x, config);
            
            if (i == 0 || i == partitions) {
                sum += y;
            } else {
                sum += 2 * y;
            }
        }
        
        return (h / 2) * sum;
    }

    // 函数范围分析报告
    void analyzeFunctionRange(FunctionType type, const FunctionRangeConfig& config) {
        std::cout << "=== 函数范围分析报告 ===" << std::endl;
        std::cout << "函数类型: ";
        
        switch (type) {
            case FunctionType::LINEAR: std::cout << "线性函数"; break;
            case FunctionType::QUADRATIC: std::cout << "二次函数"; break;
            case FunctionType::EXPONENTIAL: std::cout << "指数函数"; break;
            case FunctionType::LOGARITHMIC: std::cout << "对数函数"; break;
            case FunctionType::TRIGONOMETRIC: std::cout << "三角函数"; break;
            default: std::cout << "未知类型";
        }
        std::cout << std::endl;
        
        std::cout << "定义域: [" << config.domainStart << ", " << config.domainEnd << "]" << std::endl;
        
        // 计算实际值域
        auto samples = generateFunctionSamples(type, config);
        float minVal = config.rangeEnd;
        float maxVal = config.rangeStart;
        
        for (const auto& sample : samples) {
            if (sample.second < minVal) minVal = sample.second;
            if (sample.second > maxVal) maxVal = sample.second;
        }
        
        std::cout << "实际值域: [" << minVal << ", " << maxVal << "]" << std::endl;
        
        // 查找极值点
        auto extremum = findFunctionExtremum(type, config);
        std::cout << "最大值点: (" << extremum.first << ", " << extremum.second << ")" << std::endl;
        
        // 查找零点
        auto roots = findFunctionRoots(type, config);
        std::cout << "零点数量: " << roots.size() << std::endl;
        for (size_t i = 0; i < roots.size(); ++i) {
            std::cout << "零点 " << i + 1 << ": x = " << roots[i] << std::endl;
        }
        
        // 计算积分
        float integral = calculateFunctionIntegral(type, config, config.domainStart, config.domainEnd);
        std::cout << "区间积分: " << integral << std::endl;
        std::cout << "=====================" << std::endl;
    }

} // namespace FunctionRangeSystem

// 测试函数
int main() {
    using namespace FunctionRangeSystem;
    
    std::cout << "函数范围系统测试" << std::endl;
    std::cout << "================" << std::endl;
    
    // 测试1: 线性函数
    FunctionRangeConfig linearConfig = {0.0f, 10.0f, 0.0f, 20.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 100};
    analyzeFunctionRange(FunctionType::LINEAR, linearConfig);
    
    // 测试2: 二次函数
    FunctionRangeConfig quadraticConfig = {-5.0f, 5.0f, -10.0f, 10.0f, -0.5f, 1.0f, 0.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.001f, 100};
    analyzeFunctionRange(FunctionType::QUADRATIC, quadraticConfig);
    
    // 测试3: 三角函数
    FunctionRangeConfig trigConfig = {0.0f, 6.28f, -2.0f, 2.0f, 1.5f, 2.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.001f, 200};
    analyzeFunctionRange(FunctionType::TRIGONOMETRIC, trigConfig);
    
    // 测试单个点计算
    std::cout << "单点计算测试:" << std::endl;
    float x = 3.0f;
    float linearVal = evaluateFunction(FunctionType::LINEAR, x, linearConfig);
    float quadraticVal = evaluateFunction(FunctionType::QUADRATIC, x, quadraticConfig);
    float trigVal = evaluateFunction(FunctionType::TRIGONOMETRIC, x, trigConfig);
    
    std::cout << "x = " << x << " 时:" << std::endl;
    std::cout << "线性函数值: " << linearVal << std::endl;
    std::cout << "二次函数值: " << quadraticVal << std::endl;
    std::cout << "三角函数值: " << trigVal << std::endl;
    
    return 0;
}
