#include "packagepage2.h"
#include "ui_packagepage2.h"

const QString PackagePage2::ZipCacheFile = "jsoncache.zip";
const QString PackagePage2::PackagesCacheUrl = "http://mods.oni2.net/jsoncache/"+ZipCacheFile;
const QString PackagePage2::CacheFile = "nodes.json";

PackagePage2::PackagePage2(QWidget *parent) :
    QWizardPage(parent),
    ui(new Ui::PackagePage2)
{
    ui->setupUi(this);

    this->setTitle("Mandatory Fields");

    //Register fields to be accessible in another pages //Not using mandatory field, it would require empty verification too...
    registerField("leModName", ui->leModName);
    registerField("leAuthors", ui->leAuthors);
    registerField("leVersion", ui->leVersion);
    registerField("ptDescription", ui->ptDescription,"plainText");
    registerField("lePackageNumber", ui->lePackageNumber);
    registerField("rbReplace", ui->rbReplace);

    ui->lbFieldsReadOnly->setText("<html><span style='color:#0000ff;'>* Fields read only  by AEI2 when the package "
            "isn't at the mod depot.</span></html>"); // Don't use rich text in qtdesigner because it generates platform dependent code
    QString htmlAsterisk="<html><span style='color:#0000ff;'>*</span></html>";
    ui->lbAsteriscAuthors->setText(htmlAsterisk);
    ui->lbAsteriscModName->setText(htmlAsterisk);
    ui->lbAsteriscVersion->setText(htmlAsterisk);
    ui->lbAsteriscDescription->setText(htmlAsterisk);
}

bool PackagePage2::validatePage(){
    QString modName=ui->leModName->text();
    QString authors=ui->leAuthors->text();
    QString version=ui->leVersion->text();
    QString description=ui->ptDescription->toPlainText();
    QString number=ui->lePackageNumber->text();

    bool emptyContent=Util::Validation::checkEmptySpaces(QStringList()<<modName<<authors<<version<<description<<number);


    if(emptyContent){
        Util::Dialogs::showError("You need to fill all fields first!");
        return false;
    }

    if(number.size()!=5){
        Util::Dialogs::showError("Invalid number format. It should contain 5 numbers.");
        return false;
    }

    if(!Util::Validation::isStringInteger(number)){
        Util::Dialogs::showError("Number is not numeric.");
        return false;
    }

    return true;
}

PackagePage2::~PackagePage2()
{
    delete ui;
}

void PackagePage2::on_pbCheck_clicked()
{
    QString number = ui->lePackageNumber->text();

    if(Util::Validation::checkEmptySpaces(QStringList(number))){
        Util::Dialogs::showError("Number is empty. Please fill it first.");
        return;
    }

    if(number.size()!=5){
        Util::Dialogs::showError("Invalid number format. It should contain 5 numeric characters.");
        return;
    }

    if(Util::Validation::isStringInteger(number)){

        bool necessaryToRedownload=false;

        QFile file(GlobalVars::VagoTemporaryDir+"/"+this->ZipCacheFile);

        if(!file.exists()){
            necessaryToRedownload=true; //File doesn't exist yet, necessary to download
        }
        else if (QDateTime::currentDateTime().toTime_t()-QFileInfo(file).lastModified().toTime_t() > 150){ //checks between 2 minutes (give more 30 seconds due to zip extraction)
            necessaryToRedownload=true; //File already exists but already expired (+2 mins without update)
        }

        if(necessaryToRedownload){
            //let's start the search in the web, so we make sure it doesn't exists yet
            QNetworkAccessManager *manager = new QNetworkAccessManager(this);
            connect(manager, SIGNAL(finished(QNetworkReply*)),
                    this, SLOT(downloadPackagesCache(QNetworkReply*)));

            //This timestamp is to guarantee that the cache received is fresh even through proxys
            QDateTime currTime = QDateTime::currentDateTime();
            QString t_time =  QString::number(currTime.toTime_t());

            manager->get(QNetworkRequest(QUrl(this->PackagesCacheUrl+"?ts="+t_time)));
        }
        else{ //Not needed to download! :) Let's use our local cache.
            checkForPackagesInCache();
        }
    }
    else{
        Util::Dialogs::showError("Number is not numeric.");
    }
}

void PackagePage2::downloadPackagesCache(QNetworkReply *result){

    if(result->error()==QNetworkReply::NoError){

        QFile file(GlobalVars::VagoTemporaryDir+"/"+this->ZipCacheFile);

        // Create temp folder if it doesn't exist
        if(!QDir(GlobalVars::VagoTemporaryDir).exists()){
            QDir().mkdir(GlobalVars::VagoTemporaryDir);
        }

        if(!file.open(QIODevice::WriteOnly)){
            UtilVago::showAndLogErrorPopUp("Error fetching package data: creating cache file.");
            return;
        }
        file.write(result->readAll());
        file.close();

        //Let's extract the cache data
        if(JlCompress::extractFile(GlobalVars::VagoTemporaryDir+"/"+this->ZipCacheFile, "/"+this->CacheFile ,GlobalVars::VagoTemporaryDir+"/"+this->CacheFile).isEmpty()){
            UtilVago::showAndLogErrorPopUp("An error occurred while unzipping the package data.");
        }

        checkForPackagesInCache();

    }
    else{
        UtilVago::showAndLogErrorPopUpLogButton("An error occurred checking number availability:\n\n"+result->errorString());
    }

    result->deleteLater();
}

void PackagePage2::checkForPackagesInCache(){
    QString packageNumber=ui->lePackageNumber->text();

    QFile file(GlobalVars::VagoTemporaryDir+"/"+this->CacheFile); //let's read the chache unzipped
    if(!file.open(QIODevice::ReadOnly)){
        UtilVago::showAndLogErrorPopUp("Error reading downloaded package cache data.");
        return;
    }
    //Read file cache to ram
    QString data=file.readAll();


    //Let's play with json engine
    QScriptEngine engine;
    QScriptValue sc = engine.evaluate("(" + data + ")");

    QScriptValue currNumber;
    QString existingModName,existingModUrl;

    QScriptValueIterator it(sc);

    while (it.hasNext()) {
        it.next();
        currNumber=it.value().toObject().property("field_package_number").toObject().property("und").toObject().property("0").toObject().property("value");
        if(currNumber.isValid() && currNumber.toString() == packageNumber){
            existingModName = it.value().toObject().property("title").toString();
            existingModUrl = it.value().toObject().property("path").toString();
            break;
        }
    }

    if(!existingModName.isEmpty()){
        Util::Dialogs::showRichError("Package "+packageNumber+" is already being used by the following mod:<br/><br/>"+
                                 existingModName+"<br/><br/>"+
                                 "More information <a href='"+existingModUrl+"'>here</a>.");
    }
    else{
        Util::Dialogs::showInfo("It seems that the package number " + packageNumber + " is not being used yet! :)");
    }
}

void PackagePage2::on_cbType_currentIndexChanged(int index)
{
    ui->lePackageNumber->setText(QString().setNum(index+1)+"XXXX");
}
