#include "Deals.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 Deals::HelpCreate() const {
	if (isRussian)
		PrintFile(DEALS_RU);
	else
		PrintFile(DEALS_EN);
	return 0;
}
int Deals::HelpDealStatus() const
{
	if (isRussian)
		PrintFile(DEAL_STATUS_RU);
	else
		PrintFile(DEAL_STATUS_EN);
	return 0;
}
int Deals::HelpDealComplete() const
{
	if (isRussian)
		PrintFile(DEAL_COMPLETE_RU);
	else
		PrintFile(DEAL_COMPLETE_EN);
	return 0;
}
int Deals::HelpDealCancel() const
{
	if (isRussian)
		PrintFile(DEAL_CANCEL_RU);
	else
		PrintFile(DEAL_CANCEL_EN);
	return 0;
	
}
int Deals::HelpDealNegative() const
{
	if (isRussian)
		PrintFile(DEAL_NEGATIVE_RU);
	else
		PrintFile(DEAL_NEGATIVE_EN);
	return 0;
}
Deals::Deals(const InputParser& parser, const bool isRussian, const string address, bool isDebug)
{
	this->parser = parser;
	this->isRussian = isRussian;
	this->address = address;
	this->isDebug = isDebug;
}

int Deals::Process()
{	

	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("create") && this->parser.cmdOptionExists("--help"))
	     return this->HelpCreate();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("status") && this->parser.cmdOptionExists("--help"))
		return this->HelpDealStatus();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("complete") && this->parser.cmdOptionExists("--help"))
		return this->HelpDealComplete();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("cancel") && this->parser.cmdOptionExists("--help"))
		return this->HelpDealCancel();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("negative") && this->parser.cmdOptionExists("--help"))
		return this->HelpDealNegative();

	
	return Update();
	return 0;
}

int Deals::Update() {
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("create"))
		return Create();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("status"))
		return Status();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("complete"))
		return Complite();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("cancel"))
		return Cancel();
	if (parser.cmdOptionExists("deal") && this->parser.cmdOptionExists("negative"))
		return Negative();
	return 1;
}

int Deals::Create() {
	/*
	Использование: dm-cli deal create [параметры]

    Создать новую сделку

    [smhd] означает секунды, минуты, часы, дни.
    Например: --leave-before 2020-01-01, or --leave-before 10d.

    -a|--at                   Сайт проведения сделки
    -s|--seller               Продавец в сделке
    -c|--customer             Покупатель в сделке
    -t|--type [prepayment|postpayment]
                              Тип сделки
    -s|--sum                  Сумма сделки в BTC
    -l|--leave-before { <гггг-мм-дд> [чч:мм:сс UTC] | <время>[smhd] }
                              Время окончания сделки (длительность сделки), по умолчанию: 14d
    -p|--pay { <гггг-мм-дд> [чч:мм:сс UTC] | <время>[smhd] }
                              Время для оплаты сделки; по умолчанию: 1d
	
	*/

	
	string at;	
	string seller;
	string customer;
	string type;
	string sum;
	string leave_before;
	string pay;
	
    

	at = GetVal("-a", "--at");
	seller = GetVal("-s", "--seller");
	customer = GetVal("-c", "--customer");
	type = GetVal("-t", "--type");
	sum = GetVal("-g", "--sum");
	leave_before = GetVal("-l", "--leave_before");
	pay = GetVal("-p", "--pay");
	
	// start curl
	string data("");
	data += ReadFile(DEAL_CREATE_TPL);
	
	
	data = Replace(data, string("{{ADDRESS}}"), address);
	data = Replace(data, string("{{AT}}"), at);
	data = Replace(data, string("{{TYPE}}"), type);
	data = Replace(data, string("{{SELLER}}"), seller);
	data = Replace(data, string("{{CUSTOMER}}"), customer);
	data = Replace(data, string("{{SUM}}"), sum);


	if (pay.length() == 0) {
		//{{UNTIL}}
		data = Replace(data, string("{{UNTIL}}"), "");
	}
	else {
		string untl(",\"until\": \"");
		untl.append(pay);
		untl.append("\"");
		data = Replace(data, string("{{UNTIL}}"), untl);

	}

	if (leave_before.length() == 0) {
		//{{FEETBACK}}
		data = Replace(data, string("{{FEETBACK}}"), "");
	}
	else {

		string untl(",\"feedback\": {\"leave-before\": \"");
		untl.append(leave_before);
		untl.append("\"}");

		data = Replace(data, string("{{FEETBACK}}"), untl);
	}

	/*
	"payment": {
    "address": "<string>",
    "until": "<datetime>",
    "sum": "<double>"
  },
  "feedback": {
    "leave-before": "<datetime>",
    "status": "<string>",
    "comments": "<string>"
  }
	
	*/
	/*
	curl -X POST "{{ADDRESS}}/api/v1/deal/create" \
    -H "Content-Type: application/json" \
    -d '{"at":"{{AT}}","type":"{{TYPE}}","seller":{"address": "{{SELLER}}"},"customer":{"address":"{{CUSTOMER}}"},"payment":{"sum":"{{SUM}}" {{UNTIL}}  } {{FEETBACK}} }'
	*/
	
	

	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;


	return 0;
}


int Deals::Status() { return 0; }
int Deals::Complite() { return 0; }
int Deals::Cancel() { return 0; }
int Deals::Negative() { return 0; }

string Deals::GetVal(const string first, const string second)
{
	string aval;
	string res("");
	if (parser.cmdOptionExists(first)) {
		aval = parser.getCmdOption(first);
		if (aval.length() > 0) res = aval;
	}
	if (parser.cmdOptionExists(second)) {
		aval = parser.getCmdOption(second);
		if (aval.length() > 0) res = aval;
	}
	return res;
}
