package com.saas.voip.controller;

import com.saas.admin.entity.PhoneNumber;
import com.saas.admin.entity.Tenant;
import com.saas.admin.repository.PhoneNumberRepository;
import com.saas.admin.repository.TenantRepository;
import com.saas.shared.core.TenantContext;
import com.saas.shared.enums.Provider;
import com.saas.tenant.entity.InboundCallRequest;
import com.saas.tenant.repository.InboundCallRequestRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@RestController
@RequestMapping("/api/voip/ziwo")
@RequiredArgsConstructor
@Slf4j
public class ZiwoSmsCallbackController {

    private final PhoneNumberRepository phoneNumberRepository;
    private final TenantRepository tenantRepository;
    private final InboundCallRequestRepository inboundCallRequestRepository;

    @PostMapping("/sms/status-callback")
    public ResponseEntity<Map<String, Object>> handleSmsStatusCallback(@RequestBody Map<String, Object> payload) {
        log.info("Received Ziwo SMS status callback: {}", payload);

        try {
            String messageSid = payload.get("message_id") != null ? payload.get("message_id").toString() : null;
            String smsStatus = payload.get("status") != null ? payload.get("status").toString() : null;
            String fromNumber = payload.get("from") != null ? payload.get("from").toString() : null;

            if (messageSid == null || smsStatus == null) {
                log.warn("Missing message_id or status in Ziwo SMS callback");
                return ResponseEntity.badRequest().body(Map.of("error", "Missing required fields"));
            }

            if (fromNumber == null || fromNumber.isEmpty()) {
                log.warn("No 'from' number in Ziwo SMS callback");
                return ResponseEntity.badRequest().body(Map.of("error", "Missing 'from' number"));
            }

            TenantContext.clear();

            Optional<PhoneNumber> phoneOpt = phoneNumberRepository.findByPhoneNumber(fromNumber);
            
            if (!phoneOpt.isPresent() || phoneOpt.get().getProvider() != Provider.ZIWO) {
                log.warn("No Ziwo phone number found for SMS from: {}", fromNumber);
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("error", "Phone number not configured"));
            }

            PhoneNumber phoneNumber = phoneOpt.get();
            String tenantId = phoneNumber.getTenantId();
            
            Optional<Tenant> tenantOpt = tenantRepository.findByTenantId(tenantId);
            if (!tenantOpt.isPresent()) {
                log.error("Tenant not found for phone number: {}", fromNumber);
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("error", "Tenant not found"));
            }

            Tenant tenant = tenantOpt.get();
            String schemaName = tenant.getSchemaName();
            
            TenantContext.setTenantId(schemaName);
            log.info("Set tenant context for Ziwo SMS callback: {}", schemaName);

            try {
                Optional<InboundCallRequest> requestOpt = inboundCallRequestRepository.findBySmsSid(messageSid);
                
                if (requestOpt.isPresent()) {
                    InboundCallRequest request = requestOpt.get();
                    request.setSmsStatus(smsStatus);
                    inboundCallRequestRepository.save(request);
                    log.info("Updated SMS status to '{}' for messageSid: {}", smsStatus, messageSid);
                } else {
                    log.warn("No InboundCallRequest found for Ziwo messageSid: {}", messageSid);
                }

                Map<String, Object> response = new HashMap<>();
                response.put("status", "success");
                response.put("message", "SMS status updated");

                return ResponseEntity.ok(response);
            } finally {
                TenantContext.clear();
            }

        } catch (Exception e) {
            log.error("Error handling Ziwo SMS status callback", e);
            TenantContext.clear();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(Map.of("error", "Internal server error"));
        }
    }
}
