#include "fillBlank.h"
#include "ui_fillBlank.h"

#include <QFile>

#include "fbFillBlankBody.h"
#include "audioPlay.h"
#include "fbBlank.h"
#include "CCommonTools.h"
#include "CSqlite3DBProc.h"
//#include "MsgDlg.h"
#include "CAppInfo.h"
#include "logproc.h"


fillBlank::fillBlank(CSubQuestionStruct &sqs, QWidget *parent) :
    CQuestionBaseWidget(parent),
    ui(new Ui::fillBlank), m_sqs(sqs)
{
    ui->setupUi(this);

    setAttribute(Qt::WA_DeleteOnClose);

    b_isPressed = false;
    m_bAnswerChange = false;
    m_sAnswer = "";
    m_nTimeStap = 0;

    setStyleSheet(g_appInfoPtr->m_sQssStr);

    m_pTimer = new QTimer;
    m_pTimer->setInterval(5*1000);
    connect(m_pTimer, &QTimer::timeout, this, &fillBlank::onTimeout);
    m_pTimer->start();

    this->installEventFilter(this);
}

fillBlank::~fillBlank()
{
	if (m_bAnswerChange)
	{		
		updateAnswer();
		m_bAnswerChange = false;
	}

    m_pTimer->stop();
    RELEASE_PTR(m_pTimer);

    delete ui;
}

int fillBlank::setUI(const int nWidth)
{
    setGeometry(0, 0, nWidth, g_appInfoPtr->m_fRate*300);
    ui->btn_mark->setGeometry(0, g_appInfoPtr->m_fRate*24, g_appInfoPtr->m_fRate*20, g_appInfoPtr->m_fRate*20);
    ui->list_choiceQuestion->setGeometry(ui->btn_mark->x() + ui->btn_mark->width() + g_appInfoPtr->m_fRate*20,
                                         g_appInfoPtr->m_fRate*20, width() - g_appInfoPtr->m_fRate*80, g_appInfoPtr->m_fRate*280);

    m_nListHeight = 0;
    QString sBodyStr = m_sqs.sBody;
    QString sAnswer = m_sqs.sStudentAnswer;

    Json::Reader reader;
    Json::Value jBody = Json::Value::null;
    if(!reader.parse(m_sqs.sBody.toStdString(), jBody))
    {
//            ShowMsg(QString::fromLocal8Bit("解析题干出错！"), g_appInfoPtr->m_answerWidget);
        myDebug()<<QString::fromLocal8Bit("解析题干出错！");
    }
    initBody(jBody, m_sqs.nShowNumber);


    Json::Value jAnswer = Json::Value::null;
    if(!sAnswer.isEmpty())
    {
        Json::Reader reader;
        if(!reader.parse(sAnswer.toStdString(), jAnswer))
        {
//            ShowMsg(QString::fromLocal8Bit("解析答案出错！"), g_appInfoPtr->m_answerWidget);
            myDebug()<<QString::fromLocal8Bit("解析答案出错！");
        }
    }
    QStringList sAnswerList;
    if(m_sqs.sSubjectiveTempAns.isEmpty())
    {
        QString sAnswerStrList;
        int nSize = jAnswer["sections"].size();
        for (int i = 0; i < nSize; i++)
        {
            Json::Value blocks = jAnswer["sections"][i];
            for (int j = 0; j < (int)blocks["blocks"].size(); j++)
            {
                if (blocks["blocks"][j]["type"].asString() == "text")
                {
                    sAnswerStrList += blocks["blocks"][j]["value"].asString().c_str();
                }
            }
        }
        sAnswerList = sAnswerStrList.split("##");
    }
    else
    {
        sAnswerList = m_sqs.sSubjectiveTempAns.split("##");
    }

    int nCount = sBodyStr.count("______");
    for(int i = 0; i < nCount; i++)
    {                
        fbBlank *wBlank = new fbBlank(i+1);

        if(sAnswerList.count() > i)
        {
            wBlank->setAnswer(sAnswerList[i]);
        }

        connect(wBlank, &fbBlank::answerChanged, this, &fillBlank::onAnswerChanged);
        QListWidgetItem *listItem = new QListWidgetItem;
        int nBlankHeight = wBlank->setUI(ui->list_choiceQuestion->width());
        m_nListHeight += nBlankHeight;
        listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nBlankHeight));
        ui->list_choiceQuestion->addItem(listItem);
        ui->list_choiceQuestion->setItemWidget(listItem, wBlank);
    }

    ui->list_choiceQuestion->setGeometry(ui->btn_mark->x() + ui->btn_mark->width() + g_appInfoPtr->m_fRate*20,
                                         g_appInfoPtr->m_fRate*20, width() - g_appInfoPtr->m_fRate*80, m_nListHeight + g_appInfoPtr->m_fRate*10);
    setGeometry(0, 0, nWidth, ui->list_choiceQuestion->y() + m_nListHeight + g_appInfoPtr->m_fRate*30);

    setMarkStyle();
    return height();
}

void fillBlank::setMarkStyle()
{
    QString sMaredStyle = QString(R"(QPushButton#btn_mark
        {
            outline:none;
            border-image:url(:/images/btn-mark-hover.png);
        })");

    QString sUnmaredStyle = QString(R"(QPushButton#btn_mark
        {
            outline:none;
            border-image:url(:/images/btn-mark.png);
        })");
    if(m_sqs.bMarked)
    {
        ui->btn_mark->setStyleSheet(sMaredStyle);
    }
    else
    {
        ui->btn_mark->setStyleSheet(sUnmaredStyle);
    }
}

void fillBlank::initBody(Json::Value jBody, int nOrderIndex)
{
    int nIndex = 1;
    bool isSetItemNo = false;
    int nSectionSize = jBody["sections"].size();
    Json::Value jSections = Json::Value::null;
    for(int i = 0; i < nSectionSize; i++)
    {
        Json::Value jblocks = Json::Value::null;
        int nBlockSize = jBody["sections"][i]["blocks"].size();
        for(int j = 0; j < nBlockSize; j++)
        {
            if(jBody["sections"][i]["blocks"][j]["type"].asString() == "audio")
            {
                if(jblocks != Json::Value::null ||
                        jSections != Json::Value::null)
                {
                    if(jblocks != Json::Value::null)
                    {
                        Json::Value jBlockItem = Json::Value::null;
                        jBlockItem["blocks"] = jblocks;
                        jblocks = Json::Value::null;
                        jSections.append(jBlockItem);
                    }
                    Json::Value jQuestionBody = Json::Value::null;
                    jQuestionBody["sections"] = jSections;
                    jSections = Json::Value::null;
                    jblocks = Json::Value::null;
                    fbFillBlankBody *wFB = new fbFillBlankBody(jQuestionBody);
                    if(!isSetItemNo)
                    {
                        wFB->setQuesionNo(QString::fromLocal8Bit("%1．").arg(QString::number(nOrderIndex)));
                        isSetItemNo = true;
                    }
                    QListWidgetItem *listItem = new QListWidgetItem;
                    int nQBHeight = wFB->setUI(ui->list_choiceQuestion->width());
                    m_nListHeight += nQBHeight;
                    listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nQBHeight));
                    ui->list_choiceQuestion->addItem(listItem);
                    ui->list_choiceQuestion->setItemWidget(listItem, wFB);
                }

                nIndex++;

                QString sAudioName = jBody["sections"][i]["blocks"][j]["ext2"].asString().c_str();
                QString sAudioUrl = jBody["sections"][i]["blocks"][j]["value"].asString().c_str();
                audioPlay *wAP = new audioPlay(sAudioName, sAudioUrl, m_sqs.nLimitedPlayTimes);
                connect(wAP, &audioPlay::playedCountChange, this, [&](){audioPlayCountChange();});

                QListWidgetItem *listItem = new QListWidgetItem;
                int nAPHeight = wAP->setUI(ui->list_choiceQuestion->width());
                m_nListHeight += nAPHeight;
                listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nAPHeight));
                ui->list_choiceQuestion->addItem(listItem);
                ui->list_choiceQuestion->setItemWidget(listItem, wAP);
            }
            else
            {
                jblocks.append(jBody["sections"][i]["blocks"][j]);
            }
        }
        if(jblocks != Json::Value::null)
        {
            Json::Value jBlockItem = Json::Value::null;
            jBlockItem["blocks"] = jblocks;
            jblocks = Json::Value::null;
            jSections.append(jBlockItem);
        }
    }

    if(jSections != Json::Value::null)
    {
        Json::Value jQuestionBody = Json::Value::null;
        jQuestionBody["sections"] = jSections;
        jSections = Json::Value::null;
        fbFillBlankBody *wFB = new fbFillBlankBody(jQuestionBody);
        if(!isSetItemNo)
        {
            wFB->setQuesionNo(QString::fromLocal8Bit("%1．").arg(QString::number(nOrderIndex)));
            isSetItemNo = true;
        }
        QListWidgetItem *listItem = new QListWidgetItem;
        int nQBHeight = wFB->setUI(ui->list_choiceQuestion->width());
        m_nListHeight += nQBHeight;
        listItem->setSizeHint(QSize(ui->list_choiceQuestion->width(), nQBHeight));
        ui->list_choiceQuestion->addItem(listItem);
        ui->list_choiceQuestion->setItemWidget(listItem, wFB);
    }
}

void fillBlank::on_btn_mark_clicked()
{
    if(!b_isPressed)
    {
        b_isPressed = true;
        ui->btn_mark->setStyleSheet("QPushButton{border-image:url(:/images/icon-marked.png);}");
    }
    else
    {
        b_isPressed = false;
        ui->btn_mark->setStyleSheet("QPushButton{border-image:url(:/images/icon-unmark.png);}");
    }

    m_sqs.bMarked = b_isPressed;
    setMarkStyle();
    emit markedItem(b_isPressed, m_sqs.nOrder);
}

void fillBlank::onTimeout()
{
    if(m_bAnswerChange)
    {
        updateAnswer();
        m_bAnswerChange = false;
    }
}

void fillBlank::onAnswerChanged()
{
    myDebug()<<"onAnswerChanged";
    bool answered = false;
    QString sAnsStr = generateAnswer(answered);

    m_nTimeStap = g_appInfoPtr->serverMTime();
    m_sAnswer = sAnsStr;
    m_bAnswerChange = true;
    m_sqs.bAnswered = answered;
    emit questionAnswered(answered, m_sqs.nOrder);
}

QString fillBlank::generateAnswer(bool &answered)
{
    Json::Value jAnswer = Json::Value::null;
    answered = false;
    QString sAnsStr = "";
    int nNumber = 1;
    for(int i = 0; i < ui->list_choiceQuestion->count(); i++)
    {
        CBaseWidget *baseWidget = dynamic_cast<CBaseWidget*>(ui->list_choiceQuestion->itemWidget(ui->list_choiceQuestion->item(i)));
        if(baseWidget->widgetType() == wt_blank)
        {
            fbBlank *wBlank = dynamic_cast<fbBlank*>(baseWidget);
            QString sAnswerStr = wBlank->getAnswer();
            if(!sAnswerStr.isEmpty())
            {
               answered = true;
            }

            if(nNumber == 1)
            {
                sAnsStr = sAnswerStr;
            }
            else
            {
                sAnsStr = sAnsStr + "##" + sAnswerStr;
            }
            nNumber++;
        }
    }

    return sAnsStr;
}

void fillBlank::updateAnswer()
{  
    Json::Value jAudioPlayedInfo = Json::Value::null;

    for(int i = 0; i < ui->list_choiceQuestion->count(); i++)
    {
        CBaseWidget *baseWidget = dynamic_cast<CBaseWidget*>(ui->list_choiceQuestion->itemWidget(ui->list_choiceQuestion->item(i)));
        if(baseWidget->widgetType() == wt_aduioPlay)
        {
            audioPlay *wAp = dynamic_cast<audioPlay*>(baseWidget);
            QString sAudioName = "";
            int nCount = 0;
            wAp->getPalyedCount(sAudioName, nCount);
            Json::Value jPlayedInfo = Json::Value::null;
            jPlayedInfo["name"] = sAudioName.toStdString();
            jPlayedInfo["times"] = nCount;
            jAudioPlayedInfo.append(jPlayedInfo);
        }
    }

    QString sAudioPalyedInfo = "";
    if(jAudioPlayedInfo != Json::Value::null)
    {
        sAudioPalyedInfo = jAudioPlayedInfo.toStyledString().c_str();
    }


    Json::Value jAnswer = Json::Value::null;
    Json::Value jAnswerItem = Json::Value::null;
    if (!m_sqs.sAnswerType.isEmpty())
    {
        jAnswerItem["answerType"] = m_sqs.sAnswerType.toStdString();
    }
    jAnswerItem["audioPlayTimes"] = sAudioPalyedInfo.toStdString();
    jAnswerItem["isSign"] = m_sqs.bMarked;
    jAnswerItem["order"] = m_sqs.nOrder;
    jAnswerItem["studentAnswer"] = m_sAnswer.toStdString();
    jAnswer.append(jAnswerItem);
    QString sUploadAnswer = jAnswer.toStyledString().c_str();
    qDebug()<<sUploadAnswer;
    m_sqs.nVersion++;
    m_sqs.bUpload = false;
    m_sqs.sSubjectiveTempAns = m_sAnswer;
    m_sqs.sUploadAnswer = sUploadAnswer;
    emit uploadAnswer(m_sqs.nOrder, m_nTimeStap, sUploadAnswer);
}

bool fillBlank::eventFilter(QObject *obj, QEvent *ev)
{

    if(obj == this)
    {
      //判断事件
        if(ev->type() == QEvent::Hide)
        {
            if(m_bAnswerChange)
            {
                myDebug()<<"fillBlank::QEvent::Hide";
                updateAnswer();
                m_bAnswerChange = false;
            }
        }
    }
    return QWidget::eventFilter(obj, ev);
}

void fillBlank::handinPaper()
{
    myDebug()<<"fillBlank::handinPaper";
    m_pTimer->stop();

    if(m_bAnswerChange)
    {
        updateAnswer();
        m_bAnswerChange = false;
    }
}

void fillBlank::audioPlayCountChange()
{
    m_bAnswerChange = true;
}

int fillBlank::widgetType()
{
    return wt_question;
}
