#include <curveeditor.h>
#include <QPainter>
#include <QMouseEvent>
#include <QPen>
#include <QBrush>
#include <QLinearGradient>
#include <QStyleOption>
#include <algorithm>

CurveEditor::CurveEditor(QWidget *parent)
    : QWidget(parent)
{
    setMinimumSize(400, 260);
    m_contentRect = rect().adjusted(60, 20, -20, -60);
}

void CurveEditor::setSize(int width, int height) 
{
    setFixedSize(width, height);
    m_contentRect = rect().adjusted(60, 20, -20, -60);
    update();
}

void CurveEditor::setPoints(const QVector<CurvePoint> &points)
{
    m_points = points;
    m_originalPoints = points;
    validateCurve();
    update();
}

QVector<CurvePoint> CurveEditor::getCurrentPoints() const
{
    return m_points;
}

void CurveEditor::setGridWidth(int width) 
{
    gridWidth = width;
    update();
}

void CurveEditor::setGridHeight(int height) 
{
    gridHeight = height;
    update();
}

void CurveEditor::setXTickTag(std::string tag) 
{
    xTickTag = tag;
    update();
}

void CurveEditor::setYTickTag(std::string tag)
{
    yTickTag = tag;
    update();
}

void CurveEditor::setYTickStep(int step) 
{
    yTickStep = step;
    update();
}

void CurveEditor::setXTickStep(int step) 
{
    xTickStep = step;
    update();
}

void CurveEditor::setYTickRange(int min, int max) 
{
    yTickMin = min;
    yTickMax = max;
    update();
}

void CurveEditor::setXTickRange(int min, int max) 
{
    xTickMin = min;
    xTickMax = max;
    update();
}

void CurveEditor::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // 绘制背景
    QStyleOption opt;
    opt.initFrom(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);

    // 绘制网格
    painter.save();
    painter.setPen(Qt::lightGray);

    // 横向网格线
    for (int i = 0; i <= gridWidth; ++i)
    {
        qreal y = m_contentRect.top() + (m_contentRect.height() * (qreal)i / gridWidth);
        painter.drawLine(m_contentRect.left(), y, m_contentRect.right(), y);
    }

    // 纵向网格线
    for (int i = 0; i <= gridHeight; ++i)
    {
        qreal x = m_contentRect.left() + (m_contentRect.width() * (qreal)i / gridHeight);
        painter.drawLine(x, m_contentRect.top(), x, m_contentRect.bottom());
    }
    painter.restore();

    // 绘制坐标轴
    painter.save();
    painter.setPen(Qt::black);
    painter.drawLine(m_contentRect.left(), m_contentRect.bottom(),
                     m_contentRect.right(), m_contentRect.bottom()); // X轴
    painter.drawLine(m_contentRect.left(), m_contentRect.top(),
                     m_contentRect.left(), m_contentRect.bottom()); // Y轴
    painter.restore();

    // 在paintEvent中修改网格和刻度绘制代码

    // 绘制网格
    painter.save();
    painter.setPen(QPen(Qt::lightGray, 1, Qt::DotLine));

    // 横向网格线（水平线）
    for (int i = 0; i <= gridHeight; ++i)
    {
        qreal y = m_contentRect.top() + (m_contentRect.height() * (qreal)i / gridHeight);
        painter.drawLine(m_contentRect.left(), y, m_contentRect.right(), y);
    }

    // 纵向网格线（垂直线）
    for (int i = 0; i <= gridWidth; ++i)
    {
        qreal x = m_contentRect.left() + (m_contentRect.width() * (qreal)i / gridWidth);
        painter.drawLine(x, m_contentRect.top(), x, m_contentRect.bottom());
    }
    painter.restore();

    // 绘制坐标轴刻度
    painter.save();
    painter.setPen(Qt::black);

    // X轴刻度
    for (int i = xTickMin; i <= xTickMax; i += xTickStep)
    {
        // 计算刻度位置 (基于百分比)
        qreal xPos = m_contentRect.left() + (m_contentRect.width() * i / ((qreal)gridWidth * 10));
        QString label = QString::number(i);

        // 绘制刻度线
        painter.drawLine(xPos, m_contentRect.bottom(),
                         xPos, m_contentRect.bottom() + 5);

        // 绘制刻度文本
        QRect textRect(xPos - 15, m_contentRect.bottom() + 10, 30, 15);
        painter.drawText(textRect, Qt::AlignCenter, label);
    }

    // Y轴刻度
    for (int i = yTickMin; i <= yTickMax; i += yTickStep)
    {
        // 计算刻度位置
        qreal yPos = m_contentRect.bottom() - (m_contentRect.height() * i / ((qreal)gridHeight * 10));
        QString label = QString::number(i);

        // 绘制刻度线
        painter.drawLine(m_contentRect.left(), yPos,
                         m_contentRect.left() - 5, yPos);

        // 绘制刻度文本
        QRect textRect(m_contentRect.left() - 40, yPos - 8, 35, 15);
        painter.drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, label);
    }

    // 添加坐标轴标签
    painter.setPen(Qt::black);
    QRect xLabelRect(m_contentRect.right() - 60, m_contentRect.bottom() + 30, 80, 20);
    painter.drawText(xLabelRect, Qt::AlignCenter, xTickTag.c_str());

    painter.save();
    painter.rotate(-90);
    QRect yLabelRect(-m_contentRect.bottom() - 10, m_contentRect.left() - 50, 110, 20);
    painter.drawText(yLabelRect, Qt::AlignCenter, yTickTag.c_str());
    painter.restore();

    painter.restore();
    // 绘制曲线
    painter.save();
    painter.setPen(QPen(Qt::gray, 2));

    for (int i = 1; i < m_points.size(); ++i)
    {
        QPointF p1 = mapToContent(m_points[i - 1].x, m_points[i - 1].y);
        QPointF p2 = mapToContent(m_points[i].x, m_points[i].y);
        painter.drawLine(p1, p2);
    }

    // 绘制节点
    for (int i = 0; i < m_points.size(); ++i)
    {
        QPointF pos = mapToContent(m_points[i].x, m_points[i].y);
        painter.save();
        if (isDragging() && m_dragIndex == i)
            painter.setBrush(Qt::red);
        else
            painter.setBrush(Qt::blue);

        painter.drawEllipse(pos, POINT_RADIUS, POINT_RADIUS);
        painter.restore();
    }
    painter.restore();
}

QPointF CurveEditor::mapToContent(qreal xPercent, qreal yPercent)
{
    qreal x = m_contentRect.left() + (m_contentRect.width() * xPercent / 100.0);
    qreal y = m_contentRect.bottom() - (m_contentRect.height() * yPercent / 100.0);
    return QPointF(x, y);
}

int CurveEditor::findPointAt(const QPointF &pos)
{
    for (int i = 0; i < m_points.size(); ++i)
    {
        QPointF pt = mapToContent(m_points[i].x, m_points[i].y);
        if (QLineF(pt, pos).length() < POINT_RADIUS)
        {
            return i;
        }
    }
    return -1;
}

void CurveEditor::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        m_dragIndex = findPointAt(event->pos());
        if (m_dragIndex >= 0)
        {
            m_dragStartPos = event->pos();
            setCursor(Qt::ClosedHandCursor);
        }
    }
}

void CurveEditor::mouseMoveEvent(QMouseEvent *event)
{
    if (isDragging())
    {
        QPointF delta = event->pos() - m_dragStartPos;

        // 计算新的坐标
        QPointF newPos = mapToContent(m_points[m_dragIndex].x, m_points[m_dragIndex].y) + delta;
        m_points[m_dragIndex].x = qBound(0.0, (newPos.x() - m_contentRect.left()) * 100.0 / m_contentRect.width(), 100.0);
        m_points[m_dragIndex].y = qBound(0.0, (m_contentRect.bottom() - newPos.y()) * 100.0 / m_contentRect.height(), 100.0);

        adjustPointPosition(m_dragIndex);
        validateCurve();
        update();
        m_dragStartPos = event->pos();
        emit curveChanged(m_points);
    }
}

void CurveEditor::mouseReleaseEvent(QMouseEvent *event)
{
    if (isDragging())
    {
        unsetCursor();
        m_dragIndex = -1;
    }
    emit curveReleased();
}

void CurveEditor::adjustPointPosition(int index)
{
    const qreal minGap = 0.1; // 最小间距阈值

    // 处理与前一个点的关系
    if (index > 0)
    {
        // 确保当前点X坐标大于前一个点，并保持最小间距
        if (m_points[index].x <= m_points[index - 1].x + minGap)
        {
            m_points[index].x = m_points[index - 1].x + minGap;
        }
        
        // 确保当前点Y坐标大于前一个点，并保持最小间距
        if (m_points[index].y <= m_points[index - 1].y + minGap)
        {
            m_points[index].y = m_points[index - 1].y + minGap;
        }
    }

    // 处理与后一个点的关系
    if (index < m_points.size() - 1)
    {
        // 确保当前点X坐标小于后一个点，并保持最小间距
        if (m_points[index].x >= m_points[index + 1].x - minGap)
        {
            m_points[index].x = m_points[index + 1].x - minGap;
        }
        
        // 确保当前点Y坐标小于后一个点，并保持最小间距
        if (m_points[index].y >= m_points[index + 1].y - minGap)
        {
            m_points[index].y = m_points[index + 1].y - minGap;
        }
    }
}

void CurveEditor::validateCurve()
{
    // 按X坐标排序
    std::sort(m_points.begin(), m_points.end(), 
        [](const CurvePoint& a, const CurvePoint& b) { return a.x < b.x; });
    
    // 应用间距规则
    for (int i = 0; i < m_points.size(); ++i) {
        adjustPointPosition(i);
    }
}