package com.banesco.common.infraestructure.repository;

import com.banesco.common.domain.model.ApiConfig;
import com.banesco.common.domain.dto.bian.device.JsonHelper;
import com.banesco.common.domain.dto.bian.device.LoggerHelper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;

public class RegisterSecurityRepository {

    private static final Logger logger = Logger.getLogger(RegisterSecurityRepository.class.getName());
    private final LoggerHelper loggerHelper;
    private final ApiConfig registerSecurityAPI;
    private final ExecutorService executor = Executors.newCachedThreadPool();

    public RegisterSecurityRepository(LoggerHelper loggerHelper, ApiConfig registerSecurityAPI) {
        this.loggerHelper = loggerHelper;
        this.registerSecurityAPI = registerSecurityAPI;
    }

    public <T> void writeTrice(String requestId, T registerSecurityRq) {
        logger.info(loggerHelper.buildInfoPrivateRequest(requestId, "RegisterSecurityRq", registerSecurityRq));

        CompletableFuture.runAsync(() -> {
            try {
                URL url = new URL(registerSecurityAPI.getUrl());
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setConnectTimeout(registerSecurityAPI.getTimeout().getConnect());
                connection.setReadTimeout(registerSecurityAPI.getTimeout().getResponse());
                connection.setDoOutput(true);

                String jsonInputString = JsonHelper.getJsonFromObject(registerSecurityRq);

                try (OutputStream os = connection.getOutputStream()) {
                    byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
                    os.write(input, 0, input.length);
                }

                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
                        StringBuilder response = new StringBuilder();
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                        logger.info(loggerHelper.buildInfoPrivateResponse(requestId, "RegisterSecurityRs", response.toString()));
                    }
                } else {
                    try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8))) {
                        StringBuilder response = new StringBuilder();
                        String responseLine;
                        while ((responseLine = br.readLine()) != null) {
                            response.append(responseLine.trim());
                        }
                        logger.info(loggerHelper.buildInfoPrivateResponse(requestId, "RegisterSecurityRs", response.toString()));
                    }
                }

                connection.disconnect();

            } catch (IOException e) {
                logger.log(Level.SEVERE, String.format("Error interno writeTrice: %s", e.getMessage()));
                logger.info(loggerHelper.buildInfoPrivateResponse(requestId, "RegisterSecurityRs", e.getMessage()));
            }
        }, executor).exceptionally(ex -> {
            logger.log(Level.SEVERE, String.format("Async Error interno writeTrice: %s", ex.getMessage()));
            logger.info(loggerHelper.buildInfoPrivateResponse(requestId, "RegisterSecurityRs", ex.getMessage()));
            return null;
        });

    }

    public void shutdown() {
        executor.shutdown();
    }
}
