#include "AccountUpdate.hpp"
#include <string>
#include <cstdlib>
#include "PrintFile.hpp"
#include "common.hpp"
#include "ExecCommand.hpp"
#include "json.hpp"
#include "base64.h"
#include <fstream>
#include "cleanHtml.h"
#include <sstream>
#include <iostream>
using namespace std;

int AccountUpdate::Help()
{
	if (this->isRussian)

	{
		std::cout <<
			R"(
Использование: dm-cli account update [параметры] <биткоин адрес>

    Изменить учётные данные пользователя.

    Для изменения учётных данных вы должны подписать текущую дату и новые данные пользователя
    вашим приватным биткоин ключом. Например, текущая дата, новый битмессадж, подпись:
    2020-01-01
    BM-2cUuxYUFWLCrtpKRMdHCpU1QKEuFtHh7vu
    IEF1ysyhu8ps0m5xSJaZZg/5hBylmcWQQggkGO7yNN8iMf/EA2O287kxi58xCDDtxvdsC0TWqylVE5MT5CouamU=

    -d|--date <yyyy-mm-dd>    Текущая дата.
    -s|--signature <sig>      Биткоин подпись.
    -p|--pgp <pgp>            Установить armored RSA pgp ключ.
    -u|--url [+/-]<url>       Добавить/удалить url в trusted список. Разделенные запятыми
    -b|--bitmessage           Изменить битмессадж адрес.

   
)"
				  << std::endl;
	}

	else
	{
		std::cout <<
			R"(
Usage: dm-cli account update [options] <bitcoin_address>

    Update user account data.

    To change the account data you should sign the current date and new user data
    with your bitcoin private key. For example, current date, new bitmessage, signature:
    2020-01-01
    BM-2cUuxYUFWLCrtpKRMdHCpU1QKEuFtHh7vu
    IEF1ysyhu8ps0m5xSJaZZg/5hBylmcWQQggkGO7yNN8iMf/EA2O287kxi58xCDDtxvdsC0TWqylVE5MT5CouamU=

    -d|--date <yyyy-mm-dd>    Current date.
    -s|--signature <sig>      Bitcoin signature.
    -p|--pgp <pgp>            Set up an armored RSA pgp key.
    -u|--url [+/-]<url>       Add/remove an url to trusted list.
    -b|--bitmessage           Change bitmessage address.   
)"
				  << std::endl;
	}
	return 0;
}

AccountUpdate::AccountUpdate(const InputParser &parser, const bool isRussian)
{
	this->parser = parser;
	this->isRussian = isRussian;
	address = (DEFAULTADDRESS);
	const string &addressarg = parser.getCmdOption("--address");
	if (!addressarg.empty())
	{
		address = addressarg;
	}
	isDebug = false;
	if (parser.cmdOptionExists("--debug"))
	{
		isDebug = true;
	}
}

int AccountUpdate::Process()
{
	if (this->parser.cmdOptionExists("--help"))
		return this->Help();
	return Update();
}
string AccountUpdateUrl()
{
	return
		R"(
 -X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json" -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"url\":[{{URLS}}],	\"sign\":\"{{SIGN}}\"}"   
)";
}
int AccountUpdate::ProcessUrl(std::string date, std::string signature, std::string urls)
{
	/*
	curl -X POST "https://testnet-dm2.bitdeals.org/api/v1/client/update" \
	-H "Content-Type: application/json" \
	-d '{"address":"mnumHs9HQMrw2Q1iKLNnx9NzExS7nMLmyp","date":"2025-10-21","url":["https://testnet-dm2.bitdeals.org"],
	"sign":"IAGHICUSCxUrcWTMSL9j94vRufb9l5nBckahT+RznlHMPx9LTPpDHsozxVyxkpjtgrhC8eCyJKNaOw8U/v56pL0="}'
	*/
	/*
		[{{URLS}}],
		*/
	std::stringstream test(urls);
	std::string segment;
	std::vector<std::string> seglist;
	string urlout("");
	while (std::getline(test, segment, ','))
	{
		urlout.append("\\\"");
		urlout.append(segment);
		urlout.append("\\\",");
		seglist.push_back(segment);
	}
	urlout = urlout.substr(0, urlout.length() - 1);
	string data("curl -s ");
	data += AccountUpdateUrl();
	string bt("");
	bt = parser.getLast();
	data = Replace(data, string("{{ADDRESS}}"), address);
	data = Replace(data, string("{{BT}}"), bt);
	data = Replace(data, string("{{DATE}}"), date);
	data = Replace(data, string("{{SIGN}}"), signature);
	data = Replace(data, string("{{URLS}}"), urlout);

	string result = ExecCommand(data.c_str());
	if (result.length() == 0)
		return NoResponse("");
	nlohmann::json jsonData = nlohmann::json::parse(result);

	std::ostringstream stream;
	stream << "success: " << jsonData["result"]["success"] << endl;
	stream << "message: " << jsonData["result"]["message"] << endl;
	string decoded = stream.str();
	cout << decoded << endl;
	string payload = cleanup_html(base64_decode(jsonData["payload"]));
	if (isDebug)
		ShowDebug(data, decoded, 1, payload);

	return 0;
}
string AccountUpdatePgp()
{
	return R"(
 -X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json"  -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"pgp\":\"{{PGP}}\",\"sign\":\"{{SIGN}}\"}"
)";
}
int AccountUpdate::ProcessPgp(std::string date, std::string signature, std::string pgp)
{

	string data("curl -s ");
	data += AccountUpdatePgp();
	string bt("");
	bt = parser.getLast();
	string pgpencoded = ReplaceAll(pgp, "\n", "\\n");
	data = Replace(data, string("{{ADDRESS}}"), address);
	data = Replace(data, string("{{BT}}"), bt);
	data = Replace(data, string("{{DATE}}"), date);
	data = Replace(data, string("{{SIGN}}"), signature);
	data = Replace(data, string("{{PGP}}"), pgpencoded);
	string result = ExecCommand(data.c_str());
	if (result.length() == 0)
		return NoResponse("");
	nlohmann::json jsonData = nlohmann::json::parse(result);

	std::ostringstream stream;
	stream << "success: " << jsonData["result"]["success"] << endl;
	stream << "message: " << jsonData["result"]["message"] << endl;
	string decoded = stream.str();
	cout << decoded << endl;
	string payload = cleanup_html(base64_decode(jsonData["payload"]));
	if (isDebug)
		ShowDebug(data, decoded, 1, payload);

	return 0;
}
string AccountUpdateBtm()
{
	return R"(
 -X POST "{{ADDRESS}}/api/v1/client/update" -H "Content-Type: application/json" -d "{\"address\":\"{{BT}}\",\"date\":\"{{DATE}}\",\"bitmessage\":[\"{{BTM}}\"],\"sign\":\"{{SIGN}}\"}"   
)";
}
int AccountUpdate::ProcessBitmessage(std::string date, std::string signature, std::string btmsg)
{

	string data("curl -s ");
	data += AccountUpdateBtm();
	string bt("");
	bt = parser.getLast();
	data = Replace(data, string("{{ADDRESS}}"), address);
	data = Replace(data, string("{{BT}}"), bt);
	data = Replace(data, string("{{DATE}}"), date);
	data = Replace(data, string("{{SIGN}}"), signature);
	data = Replace(data, string("{{BTM}}"), btmsg);

	string result = ExecCommand(data.c_str());
	if (result.length() == 0)
		return NoResponse("");
	nlohmann::json jsonData = nlohmann::json::parse(result);

	std::ostringstream stream;
	stream << "success: " << jsonData["result"]["success"] << endl;
	stream << "message: " << jsonData["result"]["message"] << endl;
	string decoded = stream.str();
	cout << decoded << endl;
	string payload = cleanup_html(base64_decode(jsonData["payload"]));
	if (isDebug)
		ShowDebug(data, decoded, 1, payload);

	return 0;
}
int AccountUpdate::Update()
{
	if (!this->parser.cmdOptionExists("-d") && !this->parser.cmdOptionExists("--date"))
	{
		cout << "option -d | --date required" << endl;
		return 1;
	}
	if (!this->parser.cmdOptionExists("-s") && !this->parser.cmdOptionExists("--signature"))
	{
		cout << "option -s | --signature required" << endl;
		return 1;
	}

	if (!this->parser.cmdOptionExists("-p") && !this->parser.cmdOptionExists("--pgp") && !this->parser.cmdOptionExists("-u") && !this->parser.cmdOptionExists("--url") && !this->parser.cmdOptionExists("-b") && !this->parser.cmdOptionExists("--bitmessage"))
	{
		cout << "one of this parameter required: -p | --pgp, -u| --url, -b| --bitmessage" << endl;
		return 1;
	}

	string datavalue("");
	if (this->parser.cmdOptionExists("-d"))
	{
		string vl = this->parser.getCmdOption("-d");
		if (vl.length() > 0)
		{
			datavalue = vl;
		}
	}
	if (this->parser.cmdOptionExists("--data"))
	{
		string vl = this->parser.getCmdOption("--data");
		if (vl.length() > 0)
		{
			datavalue = vl;
		}
	}
	if (datavalue.length() == 0)
	{
		cout << "data cold't be empty" << endl;
		return 1;
	}

	string signvalue("");
	if (this->parser.cmdOptionExists("-s"))
	{
		string vl = this->parser.getCmdOption("-s");
		if (vl.length() > 0)
		{
			signvalue = vl;
		}
	}
	if (this->parser.cmdOptionExists("--signature"))
	{
		string vl = this->parser.getCmdOption("--signature");
		if (vl.length() > 0)
		{
			signvalue = vl;
		}
	}
	if (signvalue.length() == 0)
	{
		cout << "signature cold't be empty" << endl;
		return 1;
	}

	// делаем обновление url
	if (this->parser.cmdOptionExists("-u") || this->parser.cmdOptionExists("--url"))
	{
		string urlvalue("");
		if (this->parser.cmdOptionExists("-u"))
		{
			string vl = this->parser.getCmdOption("-u");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (this->parser.cmdOptionExists("--url"))
		{
			string vl = this->parser.getCmdOption("--url");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (urlvalue.length() == 0)
		{
			cout << "url cold't be empty" << endl;
			return 1;
		}
		return ProcessUrl(datavalue, signvalue, urlvalue);
	}
	if (this->parser.cmdOptionExists("-b") || this->parser.cmdOptionExists("--bitmessage"))
	{
		string urlvalue("");
		if (this->parser.cmdOptionExists("-b"))
		{
			string vl = this->parser.getCmdOption("-b");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (this->parser.cmdOptionExists("--bitmessage"))
		{
			string vl = this->parser.getCmdOption("--bitmessage");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (urlvalue.length() == 0)
		{
			cout << "bitmessage cold't be empty" << endl;
			return 1;
		}
		return ProcessBitmessage(datavalue, signvalue, urlvalue);
	}

	else if (this->parser.cmdOptionExists("-p") || this->parser.cmdOptionExists("--pgp"))
	{
		string urlvalue("");
		if (this->parser.cmdOptionExists("-p"))
		{
			string vl = this->parser.getCmdOption("-p");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (this->parser.cmdOptionExists("--pgp"))
		{
			string vl = this->parser.getCmdOption("--pgp");
			if (vl.length() > 0)
			{
				urlvalue = vl;
			}
		}
		if (urlvalue.length() == 0)
		{
			cout << "pgp cold't be empty" << endl;
			return 1;
		}
		return ProcessPgp(datavalue, signvalue, urlvalue);
	}
	cout << "no argument" << endl;
	return 1;

	return 0;
}
