#include "nrj.h"
#include "yaml-cpp/yaml.h"
#include <QDebug>
#include <QColor>
#include <QUrlQuery>

NRJ::NRJ(QObject *parent) : QObject(parent)
{
    mgr = new QNetworkAccessManager(this);
    tries = 0;
}

QList<Radio *> NRJ::getRadios()
{
    return radios;
}

void NRJ::setupPlayer()
{
    tries = 0;
    QNetworkReply* reply = mgr->get(QNetworkRequest(QUrl("http://players.nrjaudio.fm/live-metadata/player/" + radio + "/v1.0/player_setup.yml")));
    connect(reply, SIGNAL(finished()), this, SLOT(onSetupFinished()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onSetupError(QNetworkReply::NetworkError)));
}

void NRJ::getAllCur()
{
    if(apiBase.isEmpty())
        return;
    tries = 0;
    QUrl url = apiBase;
    QUrlQuery query(apiBase.query());
    query.addQueryItem("act", "get_allcur");
    url.setQuery(query);

    QNetworkReply* reply = mgr->get(QNetworkRequest(url));
    connect(reply, SIGNAL(finished()), this, SLOT(onGetAllCurFinished()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onGetAllCurError(QNetworkReply::NetworkError)));
}

void NRJ::setRadio(QString radio)
{
    this->radio = radio;
}

void NRJ::onSetupFinished()
{
    QNetworkReply* reply = (QNetworkReply*)sender();
    YAML::Node root = YAML::Load(reply->readAll().constData());
    apiBase = QUrl(root["player_api"].as<std::string>().c_str());
    QUrlQuery query;
    query.addQueryItem("id_radio", root["id_webradio"].as<std::string>().c_str());
    apiBase.setQuery(query);
    coverBase = QUrl(root["radio_pics"].as<std::string>().c_str());
    YAML::Node webradios = root["webradios"];

    QString logosRootUrl = root["radio_pics"].as<std::string>().c_str();
    logosRootUrl += "80x80/";

    for(unsigned i = 0;i < webradios.size(); ++i)
    {
        YAML::Node node = webradios[i];
        Radio* radio = new Radio(this);
        radios.append(radio);
        radio->setApiBase(apiBase);
        radio->setCoverBase(coverBase);
        radio->setNetworkManager(mgr);

        radio->setId(node["id"].as<int>());
        radio->setName(QString::fromUtf8(node["name"].as<std::string>().c_str()));
        radio->setClaim(QString::fromUtf8(node["claim"].as<std::string>().c_str()));
        radio->setTextColor(QColor("#" + QString(node["color"].as<std::string>().c_str())));
        radio->setLogoUrl(QUrl(logosRootUrl + node["logo"].as<std::string>().c_str()));
        radio->setStreamUrl(QUrl(node["url_128k_mp3"].as<std::string>().c_str()));
    }
    emit setupFinished();
}

void NRJ::onSetupError(QNetworkReply::NetworkError)
{
    if(tries < 3)
    {
        ++tries;
        setupPlayer();
    }
    else
    {
        tries = 0;
        emit setupError();
    }
}

void NRJ::onGetAllCurFinished()
{
    QNetworkReply* reply = (QNetworkReply*)sender();
    QByteArray str = reply->readAll();
    YAML::Node itms = YAML::Load(str.constData())["itms"];

    for(unsigned i = 0;i < itms.size(); ++i)
    {
        YAML::Node itm = itms[i];
        int id = itm["id_plst"].as<int>();
        for(int it = 0;it < radios.size(); ++it)
        {
            Radio* r = radios.at(it);
            if(r->getId() == id)
            {
                it = radios.size();
                Song* song = new Song(r);
                song->setDuration(qMax((int)(itm["t_dur"].as<int>() - (1000 * (QDateTime::currentDateTime().toTime_t() - itm["ts"].as<int>()))), 0));
                song->setArtist(itm["art"].as<std::string>().c_str());
                song->setTitle(itm["tit"].as<std::string>().c_str());
                //qDebug()<<(QDateTime::currentDateTime().toTime_t() - itm["ts"].as<int>());
                //song->setStartTime(itm["ts"].as<int>() * 1000);
                QUrl url = coverBase;
                url.setPath(url.path() + itm["cov"].as<std::string>().c_str());
                song->setCoverUrl(url);
                r->setCurrentSong(song);
            }
        }
    }
}

void NRJ::onGetAllCurError(QNetworkReply::NetworkError)
{
    if(tries < 3)
    {
        ++tries;
        getAllCur();
    }
    else
    {
        tries = 0;
        emit getAllCurError();
    }
}