#include "deviceitem.h"
#include "tools.h"
#include "passwordindlg.h"
#include "base/x_uimsgboxok.h"
#include <QMessageBox>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <globaldefine.h>
#include <QSettings>
#include <cfg.h>
#include <QHttpMultiPart>
#include <QUuid>
#include <QBuffer>
#include "base/pixbmpshowdialog.h"
#include <QThread>
#include <QTcpSocket>
#include <QHostAddress>
#include <QInputDialog>

DeviceItem::DeviceItem(LedCard *pLedCard, LoQTreeWidget *parent,QWidget *pWnd) : QObject(parent), QTreeWidgetItem(UserType), m_parent(parent){
    m_pWnd=pWnd;
    mCard=pLedCard;
    pHpptClient = new HpptClient(this);
    setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
    setCheckState(0, Qt::Unchecked);
    m_parent->addTopLevelItem(this);
    m_bnLock = new QPushButton();
    m_bnCardDetailInfo = new QPushButton();
    m_bnCardDetailInfo->setToolTip(tr("GetScreenDetailInfo"));
    m_bnCardDetailInfo->setCursor(QCursor(Qt::PointingHandCursor));
    m_bnCardDetailInfo->setStyleSheet(R"rrr(
QPushButton {
    border-radius: 4px;
    image: url(:/res/device/bnDetail.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
    connect(m_bnCardDetailInfo, &QPushButton::clicked, this, [this]{
        QString strTip="";
        strTip.append(tr("cur brightness:")).append(QString::number(mCard->bright)).append("\r\n");
        //strTip.append("cardsystem apk version:"+QString::number(m_LedCard.iCardSystemVersion)+"\r\n");
        //strTip.append("device apk:"+m_LedCard.starterversionName+"\r\n");
        strTip.append(tr("android version:")).append(mCard->androidVersion).append("\r\n");
        //strTip.append(tr("android width:")+QString::number(m_LedCard.androidWidth)+"\r\n");
        //strTip.append(tr("android height:")+QString::number(m_LedCard.androidHeight)+"\r\n");
        strTip.append(tr("IMEI:")).append(mCard->strIMEI).append("\r\n");
        strTip.append(tr("HardWard Version:")).append(mCard->HardVersion).append("\r\n");
        strTip.append(tr("MAX Brightness level:")).append(QString::number(mCard->BrightnessLevel)).append("\r\n");
        strTip.append(tr("Android OS Resolution:")).append(mCard->ScreenResolution).append("\r\n");
        strTip.append(tr("Firmware Version:")).append(mCard->FirmwareVersion).append("\r\n");
        strTip.append(tr("Player Version:")).append(mCard->strXixunplayerVersion).append("\r\n");
        QMessageBox::information(gMainWin, tr("Detail Info"), strTip);
    });

    m_bnReadbackPic = new QPushButton();
    m_bnReadbackPic->setToolTip(tr("ReadbackPic"));
    m_bnReadbackPic->setCursor(QCursor(Qt::PointingHandCursor));
    m_bnReadbackPic->setStyleSheet(R"rrr(
QPushButton {
    border-radius: 4px;
    image: url(:/res/device/deviceReadbackPic.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
    connect(m_bnReadbackPic, SIGNAL(clicked()), this, SLOT(onReadbackPic()));

    m_ImageOnline = new QLabel();
    mCard->m_bOnLine=true;
    m_ImageOnline->setPixmap(QPixmap(":/res/device/O_Online.png"));
    setData(DeviceTable_ID, 0, mCard->m_strCardId);
    setData(DeviceTable_IP, 0, mCard->m_strCardIp);
    setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(mCard->m_iWidth).arg(mCard->m_iHeight));
    m_parent->setItemWidget(this, DeviceTable_Info, m_bnCardDetailInfo);
    m_parent->setItemWidget(this, DeviceTable_Screenshot, m_bnReadbackPic);
    m_parent->setItemWidget(this, DeviceTable_Online, m_ImageOnline);
    m_ImageOnline->setAlignment(Qt::AlignCenter);

    SetPasswordItem(mCard);
    for(int i=1; i<DeviceTable_Screenshot; i++) setTextAlignment(i, Qt::AlignCenter);

    //启动心跳，监测设备在线和下线，3次超时表示下线
    DeviceItemHttpPost();

    connect(&mHeartbeatTimer, &QTimer::timeout, this, [this] {
        m_HeartbeatCount++;
        QJsonObject json4;
        json4.insert("_id", getRandomString(10));
        json4.insert("_type", "GetCardName");
        HttpPostByTypeJsonObject(json4);
        if(m_HeartbeatCount>10) {
            //下线
            mCard->m_bOnLine=false;
            m_ImageOnline->setPixmap(QPixmap(":/res/device/O_Offline.png"));
        } else {
           //在线
            mCard->m_bOnLine=true;
            m_ImageOnline->setPixmap(QPixmap(":/res/device/O_Online.png"));
        }
    });
    mHeartbeatTimer.start(60000);
    connect(m_bnLock, SIGNAL(clicked()), this, SLOT(onVerifyLockPassword()));
    m_pGetAskTimer=new QTimer(this);
    connect(pHpptClient,SIGNAL(httpPostRspReady(QString , QString , QByteArray)),this,SLOT(OnProHttpResponse(QString , QString , QByteArray)));
    //连接item的响应信号到信息输出框的显示槽函数
    connect(this,SIGNAL(sigOutputInfo(QString)),parent->parent(),SLOT(OnOutputInfo(QString)));

}
DeviceItem::~DeviceItem() {
    mHeartbeatTimer.stop();
    if(pHpptClient) {
        delete pHpptClient;
        pHpptClient=nullptr;
    }
}

void DeviceItem::SetMainTabWidgetIndex(int index){
   m_intIndexFlagOfInfoOrControl=index;
   DeviceItemHttpPost();
}
//针对这个ITEM通过POST获取控制卡的信息，两种情况下会调用，一，创建该Item初始化后，二、手动刷新
void DeviceItem::DeviceItemHttpPost() {
    if(m_intIndexFlagOfInfoOrControl!=MainPage_DeviceManager) return;
    QJsonObject json;
    json.insert("_id", getRandomString(10));
    json.insert("_type", "GetScreenSize");
    HttpPostByTypeJsonObject(json);
    QJsonObject json1;
    json1.insert("_id", getRandomString(10));
    json1.insert("_type", "GetBrightness");
    HttpPostByTypeJsonObject(json1);
    QJsonObject json2;
    json2.insert("_id", getRandomString(10));
    json2.insert("_type", "IsScreenOn");
    HttpPostByTypeJsonObject(json2);

    QJsonObject json4;
    json4.insert("_id", getRandomString(10));
    json4.insert("_type", "GetBuildInformation");
    HttpPostByTypeJsonObject(json4);
    QJsonObject json5;
    json5.insert("_id", getRandomString(10));
    json5.insert("_type", "CheckSoftVersions");
    HttpPostByTypeJsonObject(json5);
    QJsonObject json3;
    json3.insert("_id", getRandomString(10));
    json3.insert("_type", "HasControllerPassword");
    HttpPostByTypeJsonObject(json3);
    QJsonObject json8;
    json8.insert("_id", getRandomString(10));
    json8.insert("_type", "GetCardAlias");
    HttpPostByTypeJsonObject(json8);

}
void DeviceItem::OnControlTcpSend(int iProgramIndex) {
    QTcpSocket *send = new QTcpSocket();
    connect(send, SIGNAL(connected()), this, SLOT(connect_sucessful()));
    connect(send, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError)));
    send->connectToHost(QHostAddress(mCard->m_strCardIp),31299);

    ST_ANSY_PROGRAM_PACKET tempStreadPakcet;
    tempStreadPakcet.SyncHead[0]=0x7e;
    tempStreadPakcet.SyncHead[1]=0x7e;
    tempStreadPakcet.SyncHead[2]=0x55;
    tempStreadPakcet.ucCommType=0x97;
    tempStreadPakcet.iBaoLiu=0;
    tempStreadPakcet.iLength=4;
    unsigned char uctemp[4]={0};
    uctemp[0]=iProgramIndex;

    memcpy(tempStreadPakcet.pDataBuffer,uctemp,4);
    tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength]=GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength));
    int iLenPacket=3*sizeof(unsigned char)+sizeof(char)+sizeof(int)+sizeof(int)+tempStreadPakcet.iLength+sizeof(char);/////除正文外的协议结构大小；
    QByteArray databuf = QByteArray(reinterpret_cast<char*>(&tempStreadPakcet), iLenPacket);
    if(!send->waitForConnected(10000))              //等待连接返回
    {
        qDebug()<<mCard->m_strCardIp<<"Connect timeout ";
        emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("Connect")+":"+tr("timeout"));
        send->close();
        delete send;
        return ;
    }
    send->write(databuf);
    if(send->waitForBytesWritten(3000))
    {
        send->read(send->bytesAvailable());
        qDebug()<<"recv anycast success ack";
        emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("Anycast")+":"+tr("success"));
    }
    send->close();
    delete send;
}

void DeviceItem::HttpPostByTypeJsonObject(QJsonObject json)
{
    QJsonDocument doc;
    doc.setObject(json);
    QByteArray post_loginArray = doc.toJson(QJsonDocument::Compact);
    m_strUrl="http://"+mCard->m_strCardIp+":2016/settings";
    if(mCard->m_strCardId.left(2)!="M8" && mCard->m_strCardId.left(2)!="m8")
    {
        if(json["_type"]!="GetAllScreenSizeM80") pHpptClient->httpPost(m_strUrl,post_loginArray);
    }
    else pHpptClient->httpPost(m_strUrl,post_loginArray);
}
void DeviceItem::HttpGetLedCardWidthHeight()
{
    QJsonObject json;
    json.insert("_id", getRandomString(10));
    json.insert("_type", "GetScreenSize");
    HttpPostByTypeJsonObject(json);
}
void DeviceItem::HttpGetLedCardRemarkName(){
    QJsonObject json;
    json.insert("_id", getRandomString(10));
    json.insert("_type", "GetCardAlias");
    HttpPostByTypeJsonObject(json);
}

void DeviceItem::refreshLable(){
    if(mCard->m_bPowerStatus){
        this->setForeground(DeviceTable_Power, Qt::green);
        setData(DeviceTable_Power, 0, tr("on"));
    } else {
        this->setForeground(DeviceTable_Power, Qt::red);
        setData(DeviceTable_Power, 0, tr("off"));
    }
}

void DeviceItem::onVerifyLockPassword() {
    bool ok;
    auto pwd = QInputDialog::getText(gMainWin, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok);
    if(ok) {
        QJsonObject json;
        json.insert("_id", getRandomString(10));
        json.insert("_type", "VerifyPassword");
        json.insert("pwd", pwd);
        HttpPostByTypeJsonObject(json);
    }
}
void DeviceItem::onReadbackPic() {
    QJsonObject json;
    json.insert("_id", getRandomString(10));
    json.insert("_type", "GetScreenshotFull");
    HttpPostByTypeJsonObject(json);
    if(m_PostingDlg==nullptr)
    {
        m_PostingDlg = new LoEmptyDialog(m_pWnd);
        connect(m_PostingDlg,SIGNAL(sigClose()),this,SLOT(DeletePostingDlg()));
        connect(m_pGetAskTimer,SIGNAL(timeout()),m_PostingDlg,SLOT(TimerOutUnlock()));
        m_PostingDlg->lock(tr("GetScreenshotFull"),tr("Success"),tr("GetScreenshotFull")+tr("failed"));
        m_pGetAskTimer->start(20000);
        m_PostingDlg->exec();
    }
}
void DeviceItem::SetPasswordItem(LedCard *p){
    if(p->bPassword) {//加过密
        if(p->m_bLockStatus) m_bnLock->setIcon(QIcon(":/res/device/Lock.png")); //如果已经验证通过密码显示绿色图标
        else m_bnLock->setIcon(QIcon(":/res/device/UnLock.png")); //如果没有验证显示蓝色锁图标
        m_parent->setItemWidget(this, DeviceTable_Password, m_bnLock);
    } else m_bnLock->setIcon(QIcon()); //显示空白
}
//获取到httpPost的应答，如果参数变化需要出发修改控件item的内容
void DeviceItem::OnProHttpResponse(QString url, QString postMD5, QByteArray data) {
    Q_UNUSED(postMD5)
    //qDebug()<< url + "\r\n"+m_strUrl;
    if(url == m_strUrl)
    {
//        qDebug()<<"POST";
        //qDebug()<<postMD5;
        //qDebug()<<data;
        QJsonParseError parseJsonErr;
        QJsonDocument document = QJsonDocument::fromJson(data,&parseJsonErr);
        if(!(parseJsonErr.error == QJsonParseError::NoError))
        {
            if(data.size()==0)
                qDebug()<<"json is empty";
            else
                qDebug()<<"DeviceItem OnProHttpResponse 解析json文件错误！";
            return;
        }
        QJsonObject jsonObject = document.object();
        QString strType=jsonObject["_type"].toString();
        if(jsonObject["success"].toBool()==true)
        {
            if(strType=="GetScreenSize"  )
            {

                if(mCard->m_iWidth!=jsonObject["width"].toInt()||mCard->m_iHeight!=jsonObject["height"].toInt())
                {
                    mCard->m_iWidth=jsonObject["width"].toInt();
                    mCard->m_iHeight=jsonObject["height"].toInt();
                }
                setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(mCard->m_iWidth).arg(mCard->m_iHeight));

            }
            else if(strType=="GetCardAlias"  )
            {
                mCard->m_strCardRemarkName = QString::fromUtf8(QByteArray::fromBase64(jsonObject["alias"].toString().toLatin1()));
                setData(DeviceTable_Remark,0,mCard->m_strCardRemarkName);
            }
            else if(strType=="GetCardName")
            {
                m_HeartbeatCount=0;
                mCard->m_bOnLine=true;
                m_ImageOnline->setPixmap(QPixmap(":/res/device/O_Online.png"));
            }
            else if(strType=="GetBuildInformation"  )
            {
                mCard->strIMEI=jsonObject["IMEI"].toString();
                mCard->HardVersion=jsonObject["HardVersion"].toString();
                mCard->BrightnessLevel=jsonObject["BrightnessLevel"].toInt();
                mCard->ScreenResolution=jsonObject["ScreenResolution"].toString();
                mCard->FirmwareVersion=jsonObject["FirmwareVersion"].toString();
            }
            else if(strType=="CheckSoftVersions"  )
            {

                foreach(QJsonValue value, jsonObject["apps"].toArray()) {
                    QJsonObject oApp = value.toObject();
                    if(oApp["packageName"].toString().contains("xixunplayer"))
                    {
                        mCard->strXixunplayerVersion=oApp["versionName"].toString();
                        mCard->strXixunplayerVersionCode=oApp["versionCode"].toInt();
                    }
                }

            }
            else if(strType == "HasControllerPassword")
            {
                {
                    mCard->bPassword=jsonObject["result"].toBool();
                    SetPasswordItem(mCard);
                }
            }
            else if(strType == "AliIotSetting")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("AliIotSetting")+":"+tr("success"));

            }
            else if(strType == "IsScreenOn")
            {
                {
                    mCard->m_bPowerStatus=jsonObject["on"].toBool();
                    if(mCard->m_bPowerStatus) {
                        this->setForeground(DeviceTable_Power, Qt::green);
                        setData(DeviceTable_Power, 0, tr("on"));
                        emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("GetScreenStatus")+tr("success")+","+tr("Status")+":"+tr("on"));
                    } else {
                        this->setForeground(DeviceTable_Power, Qt::red);
                        setData(DeviceTable_Power, 0, tr("off"));
                        emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("GetScreenStatus")+tr("success")+","+tr("Status")+":"+tr("off"));
                    }
                }
            }
            else if(strType == "VerifyPassword")
            {
                bool bStatus=jsonObject["result"].toBool();
                if(bStatus)//解密成功
                {
                    qDebug()<<"解密成功";
                    mCard->m_bLockStatus=false;
                }
                else
                {
                    qDebug()<<"解密失败";
                    X_UIMsgBoxOk *mb = new X_UIMsgBoxOk(tr("Tip Info"),tr("password is wrong"), m_pWnd,0);
                    mb->exec();
                    mCard->m_bLockStatus=true;
                }
                SetPasswordItem(mCard);
            } else if(strType == "GetBrightness") {
                mCard->bright = jsonObject["brightnessPercentage"].toInt(-1);
                if(mCard->bright==-1) mCard->bright = qRound(jsonObject["brightness"].toInt() * 100.0 / mCard->BrightnessLevel);
                QString bright = QString::number(mCard->bright);
                setData(DeviceTable_Brightness, 0, QString::number(mCard->bright)+"%");
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("GetBrightness")+tr("success")+","+tr("brightness")+"="+bright+"%");
            }
            else if(strType == "SetAutoBrightnessTask")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetAutoBrightnessTask")+":"+tr("success"));
            }
            else if(strType == "SetAutoVolumeTask")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetAutoVolumeTask")+":"+tr("success"));
            }
            else if(strType == "SetVolume")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetVolume")+":"+tr("success"));
            }
            else if(strType == "GetVolume")
            {
                int itempVolume=jsonObject["volume"].toInt();
                QString strCurVolume=QString::number(itempVolume);
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("GetVolume")+":"+tr("success")+","+tr("volume")+"="+strCurVolume);
            }
            else if(strType == "SetTimingScreenTask")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetTimingScreenTask")+":"+tr("success"));
            }
            else if(strType == "TestScreen")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("TestScreen")+":"+tr("success"));
            }
            else if(strType == "SetOnlineAddr")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetOnlineAddr")+":"+tr("success"));
            }
            else if(strType == "SetRealtimeServer")
            {
                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("SetRealtimeServer")+":"+tr("success"));
            }
            else if(strType == "GetCurrentSensorBrightness")
            {
                bool b485=jsonObject["is485"].toBool();
                QString strSensorType="RL1";
                if(b485)
                {
                    strSensorType="R60";
                }
                else {
                  strSensorType=  "RL1";
                }
                int iTempValue=jsonObject["value"].toInt();
                QString strSensorValue=QString::number(iTempValue);

                emit sigOutputInfo(mCard->m_strCardId+":"+tr("receive")+"<-"+tr("GetCurrentSensorBrightness")+":"+strSensorType+","+tr("Cur brightness")+":"+strSensorValue);
            } else if(strType == "GetScreenshotFull") {
                MACRO_ASKTIME_STOP
                MACRO_POSTING_DLG_UNLOCK

                qDebug()<<"GetScreenshotFull";
                QString iTemp=jsonObject["data"].toString();
                QByteArray byte_array =iTemp.toLatin1();
                QByteArray Ret_bytearray = QByteArray::fromBase64(byte_array);
                //QBuffer buffer(&Ret_bytearray);
                //buffer.open(QIODevice::WriteOnly);
                //QPixmap imageresult;
                //imageresult.loadFromData(Ret_bytearray);
                PixbmpShowDialog *dlg=new PixbmpShowDialog(m_pWnd);
                dlg->m_PixMap.loadFromData(Ret_bytearray);
                dlg->ResizeByPixmap(mCard->m_iWidth,mCard->m_iHeight);
                dlg->exec();
            }
        }
    }
}
QPixmap DeviceItem::Base64_To_Image(QByteArray bytearray,QString SavePath)
{
    QByteArray Ret_bytearray;
    Ret_bytearray = QByteArray::fromBase64(bytearray);
    QBuffer buffer(&Ret_bytearray);
    buffer.open(QIODevice::WriteOnly);
    QPixmap imageresult;
    imageresult.loadFromData(Ret_bytearray);
    if(SavePath != "")
    {
        qDebug() <<"save" ;
        imageresult.save(SavePath);
    }
    return imageresult;
}

void DeviceItem::DeletePostingDlg()
{
    if(m_PostingDlg!=nullptr)
    {
        delete m_PostingDlg;
        m_PostingDlg=nullptr;
    }
}
