#include "backend.h"

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QFile>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>


Backend::Backend() {}


QString Backend::getStateFilePath() {
#ifdef Q_OS_WIN
    QString stateDir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
#else
    QString stateDir = QStandardPaths::writableLocation(QStandardPaths::StateLocation);
#endif
    QDir().mkpath(stateDir);
    return stateDir + "/session.json";
}


void Backend::saveToJson(const QString &uuid, const QString &access_token) {
    QString filePath = getStateFilePath();
    QJsonObject json;
    json["uuid"] = uuid;
    json["access_token"] = access_token;

    QFile file(filePath);
    if (file.open(QIODevice::WriteOnly)) {
        file.write(QJsonDocument(json).toJson());
        file.close();
        qDebug() << "Данные сохранены в" << filePath;
    } else {
        qWarning() << "Не удалось открыть файл для записи:" << filePath;
    }
}


QJsonObject Backend::loadFromJson() {
    QString filePath = getStateFilePath();
    QFile file(filePath);
    if (file.open(QIODevice::ReadOnly)) {
        QByteArray data = file.readAll();
        file.close();
        QJsonDocument doc = QJsonDocument::fromJson(data);
        if (doc.isObject()) {
            return doc.object();
        }
    }
    qWarning() << "Не удалось загрузить данные из файла:" << filePath;
    return QJsonObject();
}


void Backend::sendPostRequest(const QString &url, const QJsonObject &payload, std::function<void(QJsonObject)> callback) {
    QNetworkAccessManager* manager = new QNetworkAccessManager();
    QNetworkRequest request{QUrl(url)};
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply* reply = manager->post(request, QJsonDocument(payload).toJson());
    QObject::connect(reply, &QNetworkReply::finished, [reply, callback]() {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray response = reply->readAll();
            QJsonDocument jsonResponse = QJsonDocument::fromJson(response);
            if (jsonResponse.isObject()) {
                callback(jsonResponse.object());
            } else {
                qWarning() << "Некорректный JSON-ответ.";
                callback(QJsonObject());
            }
        } else {
            qWarning() << "Ошибка запроса:" << reply->errorString();
            callback(QJsonObject());
        }
        reply->deleteLater();
    });
}


void Backend::authWithPassword(
		QString &username,
		QString &password,
		std::function<void(QString, QString, QString)> callback) 
{
    QString url = "https://root-kit.ru:3002/punkcraft/session/auth";
    QJsonObject payload;
    payload["username"] = username;
    payload["password"] = password;

    sendPostRequest(url, payload, [this, callback](QJsonObject response) {
        if (response.isEmpty()) {
            qWarning() << "Ошибка авторизации: пустой ответ.";
            if (callback) {
                callback("", "", "");
            }
            return;
        }

		// Сохраняем пользователя в json и отправляет callback функцию
        QString username = response["username"].toString();
        QString uuid = response["uuid"].toString();
        QString access_token = response["access_token"].toString();
		saveToJson(uuid, access_token);
        

        if (callback) {
            callback(username, uuid, access_token);
        }
    });
}


void Backend::authWithToken(std::function<void(QString, QString, QString)> callback) {
    QJsonObject savedData = loadFromJson();
    if (savedData.isEmpty()) {
        qWarning() << "Нет сохранённых данных для авторизации.";
        if (callback) {
            callback("", "", "");
        }
        return;
    }

    QString uuid = savedData["uuid"].toString();
    QString access_token = savedData["access_token"].toString();

    QString url = "https://root-kit.ru:3002/punkcraft/session/auth/token";
    QJsonObject payload;
    payload["uuid"] = uuid;
    payload["access_token"] = access_token;

    sendPostRequest(url, payload, [this, callback](QJsonObject response) {
        if (response.isEmpty()) {
            qWarning() << "Ошибка авторизации по токену: пустой ответ.";
            if (callback) {
                callback("", "", "");
            }
            return;
        }

        QString username = response["username"].toString();
        QString uuid = response["uuid"].toString();
        QString access_token = response["access_token"].toString();

        qDebug() << "Авторизация по токену успешна. Пользователь:" << username;
        saveToJson(uuid, access_token);

        if (callback) {
            callback(username, uuid, access_token);
        }
    });
}
