package DataLayer;

import FunctionLayer.Datahandler;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;

public class ThreadClientStoat {

    private String lastProcessedMessageId = null;

    public ThreadClientStoat(Datahandler datahandler, StanfordCoreNLP stanfordCoreNLP, StanfordCoreNLP stanfordCoreNLPSentiment) {
        Properties prop = new Properties();
        String fileName = "app.config";
        try (FileInputStream fis = new FileInputStream(fileName)) {
            prop.load(fis);
        } catch (FileNotFoundException ex) {
        } catch (IOException ex) {
        }


        String botToken = prop.getProperty("app.stoat_bot_token");
        String channelId_general_autism = prop.getProperty("app.stoat_channel_id");
        String API_URL = prop.getProperty("app.stoat_api_url");


        while (true) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //we dont need to constantly request new messages so adding some artifical delay to see if anything new is here.
            JsonObject JsonObjmessages = GetLastMessagesFromStoad(botToken, channelId_general_autism, API_URL);
            if (JsonObjmessages == null || JsonObjmessages.isEmpty())
            {
                continue;
            }
            String sentence = GetMessageToProcess(JsonObjmessages);
            if (!sentence.isEmpty())
            {
                String ResponseMsg = datahandler.getResponseMsg(sentence, "", stanfordCoreNLP, stanfordCoreNLPSentiment,
                    false);
                System.out.println(" ResponseMsg stoat: " + ResponseMsg);

                sendMessage(botToken, channelId_general_autism, API_URL, ResponseMsg);
            }
        }
    }

    private String GetMessageToProcess(JsonObject JsonObjmessages) {
        JsonArray messages = JsonObjmessages.getAsJsonArray("messages");
        JsonArray users = JsonObjmessages.getAsJsonArray("users");

        for (int index = 0; index < messages.size(); index++) {
            JsonObject message = messages.get(index).getAsJsonObject();
            lastProcessedMessageId = message.get("_id").getAsString();
            String authorId = message.get("author").getAsString();

            JsonObject author = findUserById(users, authorId);
            if (author != null) {
                // Check if bot field exists and is true
                if (author.has("bot")) {
                    continue; // Skip bot messages
                }
            }
           return message.get("content").getAsString();

        }
        return "";
    }

    private JsonObject findUserById(JsonArray users, String userId) {
        for (int i = 0; i < users.size(); i++) {
            JsonObject user = users.get(i).getAsJsonObject();
            if (user.get("_id").getAsString().equals(userId)) {
                return user;
            }
        }
        return null;
    }

    public JsonObject GetLastMessagesFromStoad(String botToken, String channelId_general_autism, String API_URL) {
        try {
            String urlString = API_URL + "/channels/" + channelId_general_autism + "/messages?limit=1&include_users=true";
            if (lastProcessedMessageId != null)
            {
                urlString = API_URL + "/channels/" + channelId_general_autism + "/messages?limit=5&include_users=true&sort=Oldest&after=" + lastProcessedMessageId;
            }
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Set up the request
            conn.setRequestMethod("GET");
            conn.setRequestProperty("x-bot-token", botToken);
            conn.setRequestProperty("Content-Type", "application/json");

            // Get the response
            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                if (response.toString().isEmpty())
                {
                    return null;
                }
                Gson gson = new Gson();
                return gson.fromJson(response.toString(), JsonObject.class);
            } else {
                System.err.println("GET request failed. Response Code: " + responseCode);
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void sendMessage(String botToken, String channelId_general_autism, String API_URL, String responseMessage) {
        try {
            String urlString = API_URL + "/channels/" + channelId_general_autism + "/messages";
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            // Set up POST request
            conn.setRequestMethod("POST");
            conn.setRequestProperty("x-bot-token", botToken);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            // Create JSON body
            JsonObject jsonBody = new JsonObject();
            jsonBody.addProperty("content", responseMessage);
            Gson gson = new Gson();
            String jsonString = gson.toJson(jsonBody);

            // Send the request
            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = jsonString.getBytes("utf-8");
                os.write(input, 0, input.length);
            }

            // Get response
            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 201) {
                //System.out.println("Message sent successfully to Stoat");
            } else {
                System.err.println("Failed to send message. Response Code: " + responseCode);

                // Read error response
                BufferedReader errorReader = new BufferedReader(
                        new InputStreamReader(conn.getErrorStream())
                );
                String errorLine;
                StringBuilder errorResponse = new StringBuilder();
                while ((errorLine = errorReader.readLine()) != null) {
                    errorResponse.append(errorLine);
                }
                errorReader.close();
                System.err.println("Error response: " + errorResponse.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
