#pragma once

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  Command Handling of incoming JSON commands.
//	Both MQTT and Websocket
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

void replyOnWebSocket(AsyncWebSocketClient *client, String list);
void updateRelayTimings(JsonVariant doc);
void updateBellOutputs(JsonVariant doc);

// Handles the incoming payload. Returns it into a "JsonDocument" format.
JsonDocument payload2json(char * payload) {
	JsonDocument doc;
	DeserializationError error = deserializeJson(doc, payload);
	if (error) {
		Serial.print("deserializeJson() failed: ");
		Serial.println(error.c_str());
	}
	return doc;
}

// Handles the JSON Commands
void handleCommand(JsonDocument command, AsyncWebSocketClient *client = nullptr){

		String cmd = command["cmd"];
		JsonVariant contents = command["contents"];

		if (cmd == "playback") {
			player.command(contents, client);
		} else if (cmd == "list_melodies") {
			String list = listFilesAsJson("/melodies");
			PublishMqtt(list.c_str());
			if (client) {
        replyOnWebSocket(client, list);  // Only reply via WS if client exists
				Serial.println("Replying on WebSocket");
			}
		} else if (cmd == "set_relay_timers") {
			updateRelayTimings(contents);
		} else if (cmd == "set_relay_outputs") {
			updateBellOutputs(contents);
		} else if (cmd == "download_melody") {
			addMelody(contents);
			// Prepare JSON response
		 	StaticJsonDocument<128> response;
		 	response["status"] = "OK";
		 	response["type"] = "Download";
		 	response["payload"] = nullptr;    		// Use null in JSON
 			char jsonOut[256];										// Create Char Buffer
 			serializeJson(response, jsonOut);			// Serialize to Buffer
			replyOnWebSocket(client, jsonOut);		// Reply on WebSocket
		}	/* else if (cmd == "sync_time") {
			StaticJsonDocument<256> response;
			if (manualTimeSync(contents)){
				response["status"] = "OK";
        response["type"] = "time_set_response";
        response["payload"] = "Time updated successfully";
			}
			response["status"] = "ERROR";
			response["type"] = "time_set_response";
			response["payload"] = "Missing timestamp parameter";
			char jsonOut[256];
    	serializeJson(response, jsonOut);
    	replyOnWebSocket(client, jsonOut);
		}	 else if (cmd == "report_time") {
			StaticJsonDocument<256> response;
	    DateTime now = rtc.now();
	    response["status"] = "OK";
	    response["type"] = "time_response";
	    response["timestamp"] = now.unixtime();  // Unix timestamp (seconds since 1970)
	    // Also include human-readable format for debugging
	    response["datetime"] = String(now.year()) + "-" +
	                          String(now.month()) + "-" +
	                          String(now.day()) + "T" +
	                          String(now.hour()) + ":" +
	                          String(now.minute()) + ":" +
	                          String(now.second());

	    char jsonOut[256];
	    serializeJson(response, jsonOut);
	    replyOnWebSocket(client, jsonOut);
		} else if (cmd == "set_time") {
			StaticJsonDocument<256> response;
			if (contents.containsKey("timestamp")) {
			    uint32_t timestamp = contents["timestamp"];
			    DateTime newTime = DateTime(timestamp);
			    rtc.adjust(newTime);
			    response["status"] = "OK";
			    response["type"] = "time_set";
			    LOG_DEBUG("Time updated from app.");
			} else {
			    response["status"] = "ERROR";
			    response["type"] = "time_set";
			    response["message"] = "Missing or Wrong timestamp parameter";
			    LOG_ERROR("Set time command missing timestamp parameter");
			}
			char jsonOut[256];
			serializeJson(response, jsonOut);
			replyOnWebSocket(client, jsonOut);
		} */ else if (cmd == "ping") {
			StaticJsonDocument<128> response;
			response["status"] = "OK";
			response["type"] = "pong";
			char jsonOut[128];										// Create Char Buffer
			serializeJson(response, jsonOut);			// Serialize to Buffer
			replyOnWebSocket(client, jsonOut);		// Reply on WebSocket
			return;
		} else if (cmd == "report_status") {
			StaticJsonDocument<256> response;
			response["status"] = "OK";
			response["type"] = "current_status";
			response["is_playing"] = player.isPlaying;
			response["time_elapsed"] = millis() - player.startTime;
			char jsonOut[256];										// Create Char Buffer
			serializeJson(response, jsonOut);			// Serialize to Buffer
			replyOnWebSocket(client, jsonOut);		// Reply on WebSocket
		} else {
			LOG_WARNING("Unknown Command Received");
		}
}
