#pragma once

#include <string>
#include <functional>
#include <iostream>

#include <QPushButton>
#include <QLabel>
#include <QtCharts/QChart>
#include <QChartView>
#include <QBarSeries>
#include <QBarSet>
#include <QBarCategoryAxis>
#include <QValueAxis>
#include <QDateTimeAxis>
#include <QDateTime>
#include <QLineSeries>
#include <QSplineSeries>

#include <QTableWidget>
#include <QTableWidgetItem>
#include <QHeaderView>
#include <QComboBox>
#include <QLineEdit>
#include <QTextEdit>

//using namespace QtCharts;

using MapLabelPair = std::map<std::string, std::pair<std::shared_ptr<QLabel>, std::shared_ptr<QLabel>>>;

class LabelPairH;
class LabelPairV;

class UiStyle
{
public:
    static std::string BTN;
};

class QUI
{
public:
    static std::shared_ptr<QLabel> label(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty="");

    static void label(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");

    static void labelImage(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string img);

    static std::shared_ptr<LabelPairH> labelPair(QWidget* parent, int x, int y, int w, int h, int w1, std::string k, std::string v="");
    static std::shared_ptr<LabelPairV> labelPairV(QWidget* parent, int x, int y, int w, int h, int h1, std::string k, std::string v = "");

    static void button(QPushButton& btn, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");
    static QPushButton* button(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");

    //static std::shared_ptr<QComboBox> combox(QWidget* parent, int x, int y, int w, int h, std::vector<std::string>& items);

    static void combox(QComboBox& comb, QWidget* parent, int x, int y, int w, int h, std::vector<std::string> items, std::string v="");
    
    static void lineedit(QLineEdit& edit, QWidget* parent, int x, int y, int w, int h);

    static void setBackground(QWidget* w, std::string name, QColor color=QColor(29, 54, 102), std::string border="border-radius:5px;");
};

class Panel : public QWidget
{
public:
    Panel(QWidget* parent, QRect rt, std::string title="");
    void setBackground(QColor color, std::string border="border-radius:1px;border:1px solid gray;");
    QLabel labBkg_;
    QLabel labIcon_;
    QLabel labTitle_;
};


class ChartBarView : public QChartView
{
public:
    ChartBarView(QWidget* parent, QRect rt, int xfrag=5);

    void setStatus(std::string title);

    std::shared_ptr<QChart> chart();

    QBarSet& addItem(std::string name);
    void updateItem(int index, std::vector<double>& vd);
    QBarSet* getBar(int index);

    void setBackground(QColor& color);

    void setAxisXTick(std::vector<std::string>& vecTick);

public:
    std::shared_ptr<QChart> chart_;
    std::shared_ptr<QBarSeries> series_;

    // X轴
    std::shared_ptr<QBarCategoryAxis> axisX_;
    // Y轴左侧
    std::shared_ptr<QValueAxis> axisYLeft_;

    int xfrag_;

    QLabel labTitle_;
};

class ChartLineView : QChartView
{
public:
    ChartLineView(QWidget* parent, QRect rt);
    void setAxisX(double min, double max, int tickCount, std::string fmt = "hh:mm");
    void setAxisYLeft(double min, double max, double tickCount, std::string fmt = "%0.1f");
    void addItem(std::string name);
    void updateItem(int index, std::vector<std::pair<double, double>>& vd);
private:
    std::shared_ptr<QChart> chart_;
    std::shared_ptr<QDateTimeAxis> axisX;
    std::shared_ptr<QValueAxis> axisY;
    std::vector<std::shared_ptr<QLineSeries>> vecSeries_;
};

class ProgressView : public QWidget
{
public:
    ProgressView(QWidget* parent, int x, int y, int h, int w=3, int d=1, int n=50);
    void setVal(int v);

    int num_;
    QLabel labVal_;
    QLabel labBarBkg_;
    std::vector<std::shared_ptr<QLabel>> vecBar_;
};

class LabelPairV
{
public:
    LabelPairV(QWidget* parent, QRect rt, int w, std::string k, std::string v);
    void setVal(std::string v, std::string sty = "");
    void setValStyle(std::string sty);
    void setKeyStyle(std::string sty);
    void setStyle(std::string styK, std::string styV = "");
    QLabel labK_;
    QLabel labV_;
};

class LabelPairH
{
public:
    LabelPairH(QWidget* parent, QRect rt, int w, std::string k, std::string v);
    void setVal(std::string v, std::string sty="");
    void setValStyle(std::string sty);
    void setKeyStyle(std::string sty);
    void setStyle(std::string styK, std::string styV="");
    QLabel labK_;
    QLabel labV_;
};

class TableBase : public QObject
{
    Q_OBJECT
public:
    TableBase(QWidget* parent, int rowMax, int colMax);

    ~TableBase();

    void setGeometry(int x, int y, int w, int h);

    void setHeaderH(std::vector<std::string> vecHeader);

    void setHeaderWidth(std::vector<int> vecWidth);
    
    void setOperate(std::vector<std::string> vecOperate, std::function<void(int, std::string)> cb);

    void setRow(int row, std::vector<std::string> vd);

    void clear();

    std::shared_ptr<QTableWidget> widget();

public:
    void onOperate(int row, std::string oper);

private:
    std::vector<std::string> vecOperate_;
    std::vector<std::shared_ptr<QWidget>> vecWidgetOper_;
    std::function<void(int, std::string)> cbOper_ = nullptr;
    std::shared_ptr<QTableWidget> widget_;
};

class PageCtrl : public QWidget
{
    Q_OBJECT
public:
    PageCtrl(QWidget* parent, QRect rt, int pageSize=10);
    void setPage(int pageId, int total);

    int pageSize_ = 0;
    int curPage_ = 0;

    QLabel labTotal_;
    QLabel labPage_;

    QPushButton btnPrev_;
    QPushButton btnNext_;
    QPushButton btnFirst_;
    QPushButton btnLast_;
};