package com.saas.voip.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.HttpClientErrorException;

import java.util.*;

@Service
@Slf4j
public class ZiwoApiService {

    private final RestTemplate restTemplate = new RestTemplate();

    @Value("${ziwo.api.key:}")
    private String apiKey;

    @Value("${ziwo.instance.name:}")
    private String instanceName;

    private static final String BASE_URL_PATTERN = "https://{instance}-api.aswat.co";

    public Map<String, Object> getCallDetails(String callId) {
        if (apiKey == null || apiKey.isEmpty() || instanceName == null || instanceName.isEmpty()) {
            log.warn("Ziwo API key or instance name not configured");
            return null;
        }

        try {
            String url = BASE_URL_PATTERN.replace("{instance}", instanceName) + "/calls/" + callId;

            HttpHeaders headers = new HttpHeaders();
            headers.set("api_key", apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Void> request = new HttpEntity<>(headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                url, HttpMethod.GET, request, Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> body = response.getBody();
                if (body.containsKey("result") && Boolean.TRUE.equals(body.get("result"))) {
                    return (Map<String, Object>) body.get("content");
                }
            }

            log.warn("Failed to get call details from Ziwo: {}", response.getStatusCode());
            return null;

        } catch (HttpClientErrorException e) {
            log.error("Error calling Ziwo API for call details: {}", e.getMessage());
            return null;
        } catch (Exception e) {
            log.error("Unexpected error calling Ziwo API", e);
            return null;
        }
    }

    public String getRecordingUrl(String callId) {
        if (apiKey == null || apiKey.isEmpty() || instanceName == null || instanceName.isEmpty()) {
            log.warn("Ziwo API key or instance name not configured");
            return null;
        }

        try {
            String url = BASE_URL_PATTERN.replace("{instance}", instanceName) 
                       + "/recordings?call_id=" + callId;

            HttpHeaders headers = new HttpHeaders();
            headers.set("api_key", apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Void> request = new HttpEntity<>(headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                url, HttpMethod.GET, request, Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> body = response.getBody();
                if (body.containsKey("result") && Boolean.TRUE.equals(body.get("result"))) {
                    Object content = body.get("content");
                    if (content instanceof List) {
                        List<Map> recordings = (List<Map>) content;
                        if (!recordings.isEmpty()) {
                            return (String) recordings.get(0).get("url");
                        }
                    }
                }
            }

            log.warn("No recording found for call: {}", callId);
            return null;

        } catch (Exception e) {
            log.error("Error getting recording URL from Ziwo", e);
            return null;
        }
    }

    public Map<String, Object> makeOutboundCall(String from, String to, String aiAgentId) {
        if (apiKey == null || apiKey.isEmpty() || instanceName == null || instanceName.isEmpty()) {
            log.warn("Ziwo API key or instance name not configured");
            return null;
        }

        try {
            String url = BASE_URL_PATTERN.replace("{instance}", instanceName) + "/calls";

            HttpHeaders headers = new HttpHeaders();
            headers.set("api_key", apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("from", from);
            requestBody.put("to", to);
            if (aiAgentId != null && !aiAgentId.isEmpty()) {
                requestBody.put("ai_agent_id", aiAgentId);
            }

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                url, HttpMethod.POST, request, Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> body = response.getBody();
                if (body.containsKey("result") && Boolean.TRUE.equals(body.get("result"))) {
                    return (Map<String, Object>) body.get("content");
                }
            }

            log.warn("Failed to make outbound call via Ziwo: {}", response.getStatusCode());
            return null;

        } catch (Exception e) {
            log.error("Error making outbound call via Ziwo", e);
            return null;
        }
    }

    public boolean hangupCall(String callId) {
        if (apiKey == null || apiKey.isEmpty() || instanceName == null || instanceName.isEmpty()) {
            log.warn("Ziwo API key or instance name not configured");
            return false;
        }

        try {
            String url = BASE_URL_PATTERN.replace("{instance}", instanceName) 
                       + "/calls/" + callId + "/hangup";

            HttpHeaders headers = new HttpHeaders();
            headers.set("api_key", apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<Void> request = new HttpEntity<>(headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                url, HttpMethod.POST, request, Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> body = response.getBody();
                return body.containsKey("result") && Boolean.TRUE.equals(body.get("result"));
            }

            return false;

        } catch (Exception e) {
            log.error("Error hanging up call via Ziwo", e);
            return false;
        }
    }

    public Map<String, Object> sendSms(String from, String to, String message) {
        if (apiKey == null || apiKey.isEmpty() || instanceName == null || instanceName.isEmpty()) {
            log.warn("Ziwo API key or instance name not configured");
            return null;
        }

        try {
            String url = BASE_URL_PATTERN.replace("{instance}", instanceName) + "/sms";

            HttpHeaders headers = new HttpHeaders();
            headers.set("api_key", apiKey);
            headers.setContentType(MediaType.APPLICATION_JSON);

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("from", from);
            requestBody.put("to", to);
            requestBody.put("message", message);

            HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);

            ResponseEntity<Map> response = restTemplate.exchange(
                url, HttpMethod.POST, request, Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> body = response.getBody();
                if (body.containsKey("result") && Boolean.TRUE.equals(body.get("result"))) {
                    return (Map<String, Object>) body.get("content");
                }
            }

            log.warn("Failed to send SMS via Ziwo: {}", response.getStatusCode());
            return null;

        } catch (Exception e) {
            log.error("Error sending SMS via Ziwo", e);
            return null;
        }
    }
}
