#include "path_curve.h"
#include <iostream>
#include <string>

/**
 * @brief 平滑路径生成器类
 * 用于生成各种类型的平滑路径并保存为CSV文件
 */
class SmoothPathGenerator {
public:
    /**
     * @brief 生成圆弧平滑路径
     * @param filename 输出文件名
     * @param center_x 圆心X坐标
     * @param center_y 圆心Y坐标
     * @param radius 半径
     * @param start_angle 起始角度（弧度）
     * @param end_angle 终止角度（弧度）
     * @param num_points 路径点数量
     */
    static bool generateCircleArc(const std::string& filename,
                                  double center_x, double center_y, double radius,
                                  double start_angle, double end_angle,
                                  int num_points = 200) {
        PathCurve path;
        path.generateCircleArc(center_x, center_y, radius,
                              start_angle, end_angle, num_points);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ Circle arc path saved: " << filename << std::endl;
            std::cout << "  Points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 生成S型曲线（三次贝塞尔曲线）
     * @param filename 输出文件名
     * @param start_x 起点X
     * @param start_y 起点Y
     * @param end_x 终点X
     * @param end_y 终点Y
     * @param control_offset 控制点偏移量
     * @param num_points 路径点数量
     */
    static bool generateSCurve(const std::string& filename,
                               double start_x, double start_y,
                               double end_x, double end_y,
                               double control_offset = 3.0,
                               int num_points = 200) {
        PathPoint p0(start_x, start_y);
        PathPoint p1(start_x + control_offset, start_y + control_offset);
        PathPoint p2(end_x - control_offset, end_y + control_offset);
        PathPoint p3(end_x, end_y);

        PathCurve path;
        path.generateCubicBezier(p0, p1, p2, p3, num_points);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ S-curve path saved: " << filename << std::endl;
            std::cout << "  Points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 生成样条曲线路径
     * @param filename 输出文件名
     * @param key_points 关键点数组
     * @param num_points 生成的路径点总数
     * @param tension 张力参数（0-1，越大越紧）
     */
    static bool generateSpline(const std::string& filename,
                               const std::vector<PathPoint>& key_points,
                               int num_points = 200,
                               double tension = 0.5) {
        if (key_points.size() < 2) {
            std::cerr << "✗ Error: At least 2 key points required" << std::endl;
            return false;
        }

        PathCurve path;
        path.generateSpline(key_points, num_points, tension);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ Spline path saved: " << filename << std::endl;
            std::cout << "  Key points: " << key_points.size() << std::endl;
            std::cout << "  Total points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 生成复杂的平滑路径（组合多个关键点）
     * @param filename 输出文件名
     * @param num_points 路径点数量
     */
    static bool generateComplexPath(const std::string& filename,
                                    int num_points = 300) {
        // 定义关键点：模拟AGV在仓库中的复杂路径
        std::vector<PathPoint> key_points = {
            PathPoint(0.0, 0.0),      // 起点
            PathPoint(5.0, 0.5),      // 第一段轻微转弯
            PathPoint(8.0, 3.0),      // 上升
            PathPoint(10.0, 6.0),     // 继续上升
            PathPoint(11.0, 9.0),     // 接近顶部
            PathPoint(10.5, 12.0),    // 转向
            PathPoint(8.0, 13.0),     // 左转
            PathPoint(5.0, 13.5),     // 继续左转
            PathPoint(2.0, 12.0),     // 下降
            PathPoint(0.0, 10.0)      // 终点
        };

        PathCurve path;
        path.generateSpline(key_points, num_points, 0.3);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ Complex smooth path saved: " << filename << std::endl;
            std::cout << "  Key points: " << key_points.size() << std::endl;
            std::cout << "  Total points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 生成环形平滑路径
     * @param filename 输出文件名
     * @param radius 半径
     * @param num_points 路径点数量
     */
    static bool generateLoop(const std::string& filename,
                            double radius = 5.0,
                            int num_points = 300) {
        PathCurve path;
        path.generateCircleArc(0.0, 0.0, radius, 0.0, 2 * M_PI, num_points);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ Loop path saved: " << filename << std::endl;
            std::cout << "  Radius: " << radius << " m" << std::endl;
            std::cout << "  Points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 生成Figure-8路径（8字形）
     * @param filename 输出文件名
     * @param size 8字大小
     * @param num_points 路径点数量
     */
    static bool generateFigure8(const std::string& filename,
                                double size = 5.0,
                                int num_points = 400) {
        std::vector<PathPoint> key_points = {
            PathPoint(0.0, 0.0),
            PathPoint(size, size),
            PathPoint(size * 2, 0.0),
            PathPoint(size, -size),
            PathPoint(0.0, 0.0)
        };

        PathCurve path;
        path.generateSpline(key_points, num_points, 0.4);

        if (path.saveToCSV(filename)) {
            std::cout << "✓ Figure-8 path saved: " << filename << std::endl;
            std::cout << "  Size: " << size << " m" << std::endl;
            std::cout << "  Points: " << num_points << std::endl;
            std::cout << "  Length: " << path.getPathLength() << " m" << std::endl;
            return true;
        }
        return false;
    }

    /**
     * @brief 打印使用说明
     */
    static void printUsage() {
        std::cout << "\n========================================" << std::endl;
        std::cout << "   Smooth Path Generator" << std::endl;
        std::cout << "========================================\n" << std::endl;
        std::cout << "This tool generates various smooth paths for AGV navigation.\n" << std::endl;
        std::cout << "Available path types:" << std::endl;
        std::cout << "  1. Simple smooth path (default)" << std::endl;
        std::cout << "  2. Circle arc" << std::endl;
        std::cout << "  3. S-curve" << std::endl;
        std::cout << "  4. Complex path" << std::endl;
        std::cout << "  5. Loop path" << std::endl;
        std::cout << "  6. Figure-8 path" << std::endl;
        std::cout << "\nAll paths will be saved as CSV files.\n" << std::endl;
    }
};

int main(int argc, char* argv[]) {
    SmoothPathGenerator::printUsage();

    std::cout << "Generating smooth paths...\n" << std::endl;

    // 1. 生成默认的平滑路径 - smooth_path.csv
    std::cout << "[1] Generating default smooth path..." << std::endl;
    std::vector<PathPoint> default_key_points = {
        PathPoint(0.0, 0.0),
        PathPoint(3.0, 1.0),
        PathPoint(6.0, 3.0),
        PathPoint(9.0, 3.5),
        PathPoint(12.0, 3.0)
    };
    SmoothPathGenerator::generateSpline("smooth_path.csv", default_key_points, 200, 0.5);

    // 2. 生成圆弧路径
    std::cout << "\n[2] Generating circle arc path..." << std::endl;
    SmoothPathGenerator::generateCircleArc("smooth_path_arc.csv",
                                           5.0, 0.0, 5.0,
                                           M_PI, M_PI / 2, 150);

    // 3. 生成S型曲线
    std::cout << "\n[3] Generating S-curve path..." << std::endl;
    SmoothPathGenerator::generateSCurve("smooth_path_scurve.csv",
                                        0.0, 0.0, 10.0, 0.0, 2.5, 200);

    // 4. 生成复杂路径
    std::cout << "\n[4] Generating complex path..." << std::endl;
    SmoothPathGenerator::generateComplexPath("smooth_path_complex.csv", 300);

    // 5. 生成环形路径
    std::cout << "\n[5] Generating loop path..." << std::endl;
    SmoothPathGenerator::generateLoop("smooth_path_loop.csv", 5.0, 300);

    // 6. 生成8字形路径
    std::cout << "\n[6] Generating Figure-8 path..." << std::endl;
    SmoothPathGenerator::generateFigure8("smooth_path_figure8.csv", 4.0, 400);

    std::cout << "\n========================================" << std::endl;
    std::cout << "✓ All smooth paths generated successfully!" << std::endl;
    std::cout << "========================================\n" << std::endl;

    std::cout << "Generated files:" << std::endl;
    std::cout << "  • smooth_path.csv        - Default smooth path" << std::endl;
    std::cout << "  • smooth_path_arc.csv    - Circle arc" << std::endl;
    std::cout << "  • smooth_path_scurve.csv - S-curve" << std::endl;
    std::cout << "  • smooth_path_complex.csv - Complex path" << std::endl;
    std::cout << "  • smooth_path_loop.csv   - Loop path" << std::endl;
    std::cout << "  • smooth_path_figure8.csv - Figure-8 path" << std::endl;

    std::cout << "\nYou can load these CSV files in the Qt GUI application:" << std::endl;
    std::cout << "  1. Run: ./build/Debug/agv_qt_gui.exe" << std::endl;
    std::cout << "  2. Select 'Load from CSV' in Path Type" << std::endl;
    std::cout << "  3. Choose one of the generated CSV files" << std::endl;

    return 0;
}
