#include <iostream>
#include "ANSUtilities.h"
#include "ANSLLM.h"
#include "CkCrypt2.h"
#include <fstream>
#include <sstream>
#include <string>
#include <opencv2/opencv.hpp>

#include <CkHttp.h>
#include <CkJsonObject.h>
#include <CkHttpResponse.h>
#include <CkGlobal.h>

void EncrypyionExample(void)
{
	std::string encryptedString = "";
    //std::string inputKey = "mikael.holmstrom@anscenter.comAA";
    std::string inputKey = "sale@anscenter.com.au";
    std::string inputString = "https://anspushnotification.s3.ap-southeast-2.amazonaws.com/Events/20250113_154146_221140160_643.jpg";
    AESEncryptionCpp(inputString.c_str(), inputKey.c_str(), encryptedString);
	std::cout << "Encrypted String:" << encryptedString << std::endl;
	//std::string NewEncryptionString = "DRqCU8fsgYZcwyjMdMwnEDStSVk13htAIznm1iee8ri0js1RJqN4/q7dMtK5HyQcOWPnQThN8971lFZwRB2baMOxhvyB/xyvP3mzjvPoTH98kvO1UxBltbi0xrlTKIO8xg1i7Iw07zhmSJzxRNz18A==";
	std::string decryptedString = "";
	AESDecryptionCpp(encryptedString.c_str(), inputKey.c_str(), decryptedString);
	std::cout << "Decrypted String:" << decryptedString << std::endl;
}
int Test() {
    ANSCENTER::ANSUtilities* Handle;

    int result = CreateANSUtilityHandle(&Handle, "");

    std::cout << "Intialisation:" << result << std::endl;
    std::string arnTopic = "";
    //CreateAWSSNSTopicCpp(&Handle, "MyTopicFromC",arnTopic);
    //std::cout << "Topic ARN:" << arnTopic << std::endl;


    // delete the topic
    //arnTopic = "arn:aws:sns:ap-southeast-2:654654292871:MyTopicFromC";//arn:aws:sns:ap-southeast-2:654654292871:MyTopicFromC
    //bool deleteResult= DeleteAWSSNSTopic(&Handle, arnTopic.c_str());
    //std::cout << "Delete Topic:" << deleteResult << std::endl;
    //+34623225024
    // Send message
    std::string messageId = "";
    bool SendMessageResult = SendMessageToPhoneNumberCpp(&Handle, "+34623225024", "Hi Mr Mikael Holmstrom, this is the test message from ANS AI Box", messageId);

    std::cout << "Send Message:" << SendMessageResult << std::endl;
    std::cout << "Message ID:" << messageId << std::endl;
}
int uploadFileToGoogleStorage() {
	ANSCENTER::ANSUtilities* Handle;
	int result = CreateANSUtilityHandle(&Handle, "");
	std::cout << "Intialisation:" << result << std::endl;
	std::string googleTokenJsonfile = "C:\\Projects\\ANSVIS\\Documentation\\ImageStorage\\gcs_uploader_key.json";
	std::string bucketName = "ansaibox-image-storage";
	std::string objectName = "public-images/myTest2.jpg";
	cv::Mat image = cv::imread("C:\\Programs\\DemoAssets\\NV\\test.jpg");

    // Read json file to text first
    std::ifstream file(googleTokenJsonfile); // Open the JSON file
    if (!file) {
        std::cerr << "Error: Cannot open file!" << std::endl;
        return 1;
    }

    std::stringstream buffer;
    buffer << file.rdbuf(); // Read file content into buffer
    std::string jsonString = buffer.str(); // Convert buffer to std::string

    std::cout << "JSON Content:\n" << jsonString << std::endl;
	bool authResult = AuthenticateGCS(&Handle, jsonString.c_str());
	std::cout << "Authenticate:" << authResult << std::endl;

	bool uploadResult = UploadImageToGCS(& Handle, bucketName.c_str(), objectName.c_str(), image);
	std::cout << "Upload Image:" << uploadResult << std::endl;
	ReleaseANSUtilityHandle(&Handle);
}
void SendEmailExample(void)
{
    std::string smtpServer = "smtp.office365.com";
	int smtpPort = 587;
    std::string smtpUser =  "noreply@anscenter.com";
    std::string smtpPassword = "PW";//
	std::string subjectContent = "This is the test";
	std::string bodyHTMLContent = "<html> <body><b>Test Email</b> <img src = \"http://www.chilkatsoft.com/images/dude.gif\"></body></html>";
	std::string bodyTextContent = "";
	std::string fromEmailSender = "noreply@anscenter.com";
    std::string toEmails = "nghia.nguyen@anscenter.com;kate.truong@anscenter.com";
    std::string ccEmails = "support@anscenter.com;sale@anscenter.com";
	std::string bccEmails = "admin@anscenter.com";
	int resultSent = SendEmail(smtpServer.c_str(), smtpPort, smtpUser.c_str(), smtpPassword.c_str(),
                               subjectContent.c_str(), bodyHTMLContent.c_str(), bodyTextContent.c_str(), fromEmailSender.c_str(),
                               toEmails.c_str(), ccEmails.c_str(), bccEmails.c_str());

	std::cout << "Send Email Result:" << resultSent << std::endl;
}
int ANSLLMTest() {
    std::cout << "Running ANSLLM Test..." << std::endl;
	ANSCENTER::ANSLLM ansllm;
	std::string licenseKey = "";
    std::string apiKey = "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";
    // Initialize with license key
    ansllm.Initialize(licenseKey);
    ansllm.SetLLMProvider("openai");
    ansllm.SetApiKey(apiKey);
	//std::vector<std::string> modelList = ansllm.GetModelList();
	//std::cout << "Available Models:" << std::endl;
	//for (const auto& model : modelList) {
	//	std::cout << model << std::endl;
	//}

	// Set model
	ansllm.SetModel("gpt-5.2");
	ansllm.CreateConversation("You are a helpful assistant.", "Respond only with markdown.", "TestConversation");
	ansllm.InputAddText("Say Hello.");


	std::string response = ansllm.Ask("text");
    std::cout << "Response from ANSLLM: " << response << std::endl;
    
    // ask others
	std::string prompt2 = "Please tell me a person whose name is Sophie";
	ansllm.InputAddText(prompt2);

    std::string response2 = ansllm.Ask("text");
	std::cout << "Response from ANSLLM: " << response2 << std::endl;

    ansllm.InputAddText("Describe what you see in the following image.");
    ansllm.InputAddImageUrl("https://www.chilkatsoft.com/images/starfish.jpg", "");

    std::string response3 = ansllm.Ask("text");
    std::cout << "Response from ANSLLM: " << response3 << std::endl;


    return 0;
}

int ANSAWSTest() {
    std::cout << "Running ANSAWS Test..." << std::endl;
    ANSCENTER::ANSAWSS3* awsHandle = nullptr;
    // Initialize AWS S3 handle
    if (CreateANSAWSHandle(&awsHandle,"") != 1) {
        std::cerr << "Failed to create AWS S3 handle." << std::endl;
        return 1;
    }
	std::string baseDomain = "amazonaws.com";
	std::string bucketRegion = "ap-southeast-2";
	std::string serviceName = "s3";
	std::string bucketName = "anspushnotification";

	int port = 443;
	bool bTls = true;
	bool autoReconnect = true;
	// Connect to AWS S3
	int awsPath = 0;
    if (ConnectANSAWSHandle(&awsHandle, baseDomain.c_str(), bucketRegion.c_str(), serviceName.c_str(), port, bTls, autoReconnect, &awsPath) == 0) {
        std::cerr << "Failed to connect to AWS S3." << std::endl;
        ReleaseANSAWSHandle(&awsHandle);
        return 1;
	}
	std::cout << "Connected. AWS path style: " << (awsPath ? "true" : "false") << std::endl;

	// Set authentication (test commit)
	std::string accessKey = "AKIAZQ3DPYODSHZCECS4";
	std::string secretKey = "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";
	if (SetAuthenticationANSAWSHandle(&awsHandle, accessKey.c_str(), secretKey.c_str()) != 1) {
		std::cerr << "Failed to set AWS S3 authentication." << std::endl;
		ReleaseANSAWSHandle(&awsHandle);
		return 1;
	}
	// Upload a jpeg image to bucket
	std::string jpegFilePath = "C:\\ProgramData\\ANSCENTER\\Shared\\Test.jpg";
	std::string objectName = "test/test.jpg";

	std::string uploadedUrl;
	while (1) {
		if (UploadBinaryDataANSAWSHandle_CPP(&awsHandle, bucketName.c_str(), jpegFilePath.c_str(), uploadedUrl) != 1) {
			std::cerr << "Failed to upload JPEG image to AWS S3." << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait before retrying
		}
		else {
			std::cout << "Successfully uploaded JPEG image to AWS S3." << std::endl;
			break;
		
		}
	}
	std::cout << "Uploaded to: " << uploadedUrl << std::endl;


	//// List buckets
	//std::string bucketList = "";
	//if (ListBucketANSAWSHandle_CPP(&awsHandle, bucketList) != 1) {
	//	std::cerr << "Failed to list AWS S3 buckets." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//std::cout << "Buckets in AWS S3:" << std::endl;
	//std::cout << bucketList << std::endl;

	//// list objects in a bucket
	//std::string bucketName = "anspushnotification";
	//std::string prefix = "Events/ee2ejdgefcjl7j6ruhvsjlaea/";
	//std::string bucketObjectList = "";

	//if (ListBucketObjectsWithPrefixANSAWSHandle_CPP(&awsHandle, bucketName.c_str(), prefix.c_str(), bucketObjectList) != 1) {
	//	std::cerr << "Failed to list AWS S3 bucket objects." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//std::cout << "Bucket objects in AWS S3:" << std::endl;
	//std::cout << bucketObjectList << std::endl;


	//// Create a new bucket
	//std::string newBucketName = "my-test-bucket-a3f9d2c1w2";
	//std::string bucketPrefix = "test-prefix/";
	//if (CreateBucketANSAWSHandle(&awsHandle, newBucketName.c_str()) != 1) {
	//	std::cerr << "Failed to create AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//if (CreateBucketPrefixANSAWSHandle(&awsHandle, newBucketName.c_str(),bucketPrefix.c_str()) != 1) {
	//	std::cerr << "Failed to create AWS S3 bucket prefix." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}

	//// Delete the bucket prefix
	//std::string deleteBucketName = "my-test-bucket-a3f9d2c1";
	//if (DeleteBucketPrefixANSAWSHandle(&awsHandle, newBucketName.c_str(), bucketPrefix.c_str()) != 1) {
	//	std::cerr << "Failed to delete AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}

	// Delete the bucket
	//if (DeleteBucketANSAWSHandle(&awsHandle, newBucketName.c_str()) != 1) {
	//	std::cerr << "Failed to delete AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}


	// Download an object from bucket
	//std::string objectName = "testevent/test01.jpg";
	//std::string downloadFilePath = "E:\\Programs\\DemoAssets\\Images";
	//if (DownloadFileStreamANSAWSHandle(&awsHandle, bucketName.c_str(), objectName.c_str(), downloadFilePath.c_str()) != 1) {
	//	std::cerr << "Failed to download AWS S3 bucket object." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//
	// Clean up
	ReleaseANSAWSHandle(&awsHandle);
	return 0;
}

int ANSFTechMinIOTest() {
	std::cout << "Running ANSFTechMinIO Test..." << std::endl;
	ANSCENTER::ANSAWSS3* awsHandle = nullptr;
	// Initialize AWS S3 handle
	if (CreateANSAWSHandle(&awsHandle, "") != 1) {
		std::cerr << "Failed to create AWS S3 handle." << std::endl;
		return 1;
	}
	std::string baseDomain = "https://minio.dev.ftech.ai";
	std::string bucketRegion = "vn1";
	std::string serviceName = "s3";
	std::string bucketName = "aicamera";

	int port = 443;
	bool bTls = true;
	bool autoReconnect = true;
	// Connect to AWS S3
	int awsPath = 0;
	if (ConnectANSAWSHandle(&awsHandle, baseDomain.c_str(), bucketRegion.c_str(), serviceName.c_str(), port, bTls, autoReconnect, &awsPath) == 0) {
		std::cerr << "Failed to connect to AWS S3." << std::endl;
		ReleaseANSAWSHandle(&awsHandle);
		return 1;
	}

	// Set authentication
	std::string accessKey = "aicamerapush";
	std::string secretKey = "88fO8Y3EpMFMG1HFCCcfCE4cWh0k5KKZ";
	if (SetAuthenticationANSAWSHandle(&awsHandle, accessKey.c_str(), secretKey.c_str()) != 1) {
		std::cerr << "Failed to set AWS S3 authentication." << std::endl;
		ReleaseANSAWSHandle(&awsHandle);
		return 1;
	}


	// Upload a jpeg image to bucket
	std::string jpegFilePath = "E:\\Programs\\DemoAssets\\NV\\Test.jpg";
	std::string objectName = "test1.jpg";


	std::string uploadedUrl;
	if (UploadBinaryDataANSAWSHandle_CPP(&awsHandle, bucketName.c_str(), jpegFilePath.c_str(), uploadedUrl)!= 1) {
		std::cerr << "Failed to upload JPEG image to AWS S3." << std::endl;
		ReleaseANSAWSHandle(&awsHandle);
		return 1;
	}
	

	// List buckets
	//std::string bucketList = "";
	//if (ListBucketANSAWSHandle_CPP(&awsHandle, bucketList) != 1) {
	//	std::cerr << "Failed to list AWS S3 buckets." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//std::cout << "Buckets in AWS S3:" << std::endl;
	//std::cout << bucketList << std::endl;

	// list objects in a bucket
	//std::string bucketName = "anspushnotification";
	//std::string prefix = "Events/ee2ejdgefcjl7j6ruhvsjlaea/";
	//std::string bucketObjectList = "";

	//if (ListBucketObjectsWithPrefixANSAWSHandle_CPP(&awsHandle, bucketName.c_str(), prefix.c_str(), bucketObjectList) != 1) {
	//	std::cerr << "Failed to list AWS S3 bucket objects." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//std::cout << "Bucket objects in AWS S3:" << std::endl;
	//std::cout << bucketObjectList << std::endl;


	// Create a new bucket
	//std::string newBucketName = "my-test-bucket-a3f9d2c1w2";
	//std::string bucketPrefix = "test-prefix/";
	//if (CreateBucketANSAWSHandle(&awsHandle, newBucketName.c_str()) != 1) {
	//	std::cerr << "Failed to create AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}
	//if (CreateBucketPrefixANSAWSHandle(&awsHandle, newBucketName.c_str(),bucketPrefix.c_str()) != 1) {
	//	std::cerr << "Failed to create AWS S3 bucket prefix." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}

	//// Delete the bucket prefix
	//std::string deleteBucketName = "my-test-bucket-a3f9d2c1";
	//if (DeleteBucketPrefixANSAWSHandle(&awsHandle, newBucketName.c_str(), bucketPrefix.c_str()) != 1) {
	//	std::cerr << "Failed to delete AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}

	// Delete the bucket
	//if (DeleteBucketANSAWSHandle(&awsHandle, newBucketName.c_str()) != 1) {
	//	std::cerr << "Failed to delete AWS S3 bucket." << std::endl;
	//	ReleaseANSAWSHandle(&awsHandle);
	//	return 1;
	//}


	// Clean up
	ReleaseANSAWSHandle(&awsHandle);
	return 0;
}

int ANSLLMOllamaTest() {
	std::cout << "Running ANSLLM Ollama Test..." << std::endl;
	ANSCENTER::ANSLLM ansllm;
	std::string licenseKey = "";

	// Initialize with local Ollama enabled
	ansllm.Initialize(licenseKey, true);

	// Set the Ollama model (must be already pulled via 'ollama pull llama3.2')
	ansllm.SetModel("llama3.2");
	ansllm.CreateConversation("You are a helpful assistant.", "Respond only with markdown.", "TestConversation");
	ansllm.InputAddText("Why is the sky blue?");

	std::string response = ansllm.Ask("text");
	std::cout << "Response from ANSLLM (Ollama): " << response << std::endl;

	// Ask another question
	ansllm.InputAddText("Say Hello.");
	std::string response2 = ansllm.Ask("text");
	std::cout << "Response from ANSLLM (Ollama): " << response2 << std::endl;

	return 0;
}

int main()
{
	//ANSLLMOllamaTest();
	ANSAWSTest();
	//ANSFTechMinIOTest();
	//ANSAWSTest();
    //ANSLLMTest();
    //SendEmailExample();
	//uploadFileToGoogleStorage();
   // EncrypyionExample();
}

