package com.saas.admin.controller;

import com.saas.admin.dto.request.CreateVoipConfigRequest;
import com.saas.admin.dto.request.UpdateVoipConfigRequest;
import com.saas.admin.dto.response.VoipConfigResponse;
import com.saas.admin.entity.TenantVoipConfig;
import com.saas.admin.service.TenantVoipConfigAdminService;
import com.saas.shared.dto.mapper.VoipConfigMapper;
import com.saas.shared.enums.Provider;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * Admin API for managing tenant-specific VoIP configurations.
 * Allows system admins to configure Telnyx, Twilio, Ziwo settings per tenant.
 */
@RestController
@RequestMapping("/api/admin/tenants/{tenantId}/voip-configs")
@PreAuthorize("hasRole('SYSTEM_ADMIN')")
@RequiredArgsConstructor
@Slf4j
public class AdminTenantVoipConfigController {

    private final TenantVoipConfigAdminService voipConfigAdminService;
    private final VoipConfigMapper voipConfigMapper;

    /**
     * Create VoIP configuration for a tenant
     * POST /api/admin/tenants/{tenantId}/voip-configs
     */
    @PostMapping
    public ResponseEntity<VoipConfigResponse> createVoipConfig(
            @PathVariable String tenantId,
            @Valid @RequestBody CreateVoipConfigRequest request) {
        
        log.info("📞 Admin creating VoIP config for tenant: {}, provider: {}", tenantId, request.getProvider());
        
        TenantVoipConfig config = voipConfigMapper.toEntity(request);
        config.setTenantId(tenantId);
        
        TenantVoipConfig saved = voipConfigAdminService.saveVoipConfig(config);
        VoipConfigResponse response = voipConfigMapper.toResponse(saved);
        
        log.info("✅ VoIP config created successfully with ID: {}", saved.getId());
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }

    /**
     * Get all VoIP configs for a tenant
     * GET /api/admin/tenants/{tenantId}/voip-configs
     */
    @GetMapping
    public ResponseEntity<List<VoipConfigResponse>> getAllVoipConfigs(@PathVariable String tenantId) {
        log.info("📋 Fetching all VoIP configs for tenant: {}", tenantId);
        
        List<TenantVoipConfig> configs = voipConfigAdminService.getAllConfigsForTenant(tenantId);
        List<VoipConfigResponse> responses = voipConfigMapper.toResponseList(configs);
        
        return ResponseEntity.ok(responses);
    }

    /**
     * Get VoIP config for specific provider
     * GET /api/admin/tenants/{tenantId}/voip-configs/{provider}
     */
    @GetMapping("/{provider}")
    public ResponseEntity<VoipConfigResponse> getVoipConfigByProvider(
            @PathVariable String tenantId,
            @PathVariable Provider provider) {
        
        log.info("🔍 Fetching VoIP config for tenant: {}, provider: {}", tenantId, provider);
        
        Optional<TenantVoipConfig> config = voipConfigAdminService.getVoipConfig(tenantId, provider);
        
        if (config.isEmpty()) {
            log.info("⚠️ No DB config found - tenant is using environment variable defaults");
            return ResponseEntity.notFound().build();
        }
        
        VoipConfigResponse response = voipConfigMapper.toResponse(config.get());
        return ResponseEntity.ok(response);
    }

    /**
     * Update VoIP configuration
     * PUT /api/admin/tenants/{tenantId}/voip-configs/{provider}
     */
    @PutMapping("/{provider}")
    public ResponseEntity<VoipConfigResponse> updateVoipConfig(
            @PathVariable String tenantId,
            @PathVariable Provider provider,
            @Valid @RequestBody UpdateVoipConfigRequest request) {
        
        log.info("✏️ Admin updating VoIP config for tenant: {}, provider: {}", tenantId, provider);
        
        Optional<TenantVoipConfig> configOpt = voipConfigAdminService.getVoipConfig(tenantId, provider);
        
        if (configOpt.isEmpty()) {
            log.warn("⚠️ Cannot update non-existent config for tenant: {}, provider: {}", tenantId, provider);
            return ResponseEntity.notFound().build();
        }
        
        TenantVoipConfig config = configOpt.get();
        
        // Apply updates (only non-null values)
        voipConfigMapper.updateEntity(request, config);
        config.setTenantId(tenantId);
        config.setProvider(provider);
        
        TenantVoipConfig updated = voipConfigAdminService.saveVoipConfig(config);
        VoipConfigResponse response = voipConfigMapper.toResponse(updated);
        
        log.info("✅ VoIP config updated successfully");
        return ResponseEntity.ok(response);
    }

    /**
     * Delete VoIP configuration
     * DELETE /api/admin/tenants/{tenantId}/voip-configs/{provider}
     */
    @DeleteMapping("/{provider}")
    public ResponseEntity<Void> deleteVoipConfig(
            @PathVariable String tenantId,
            @PathVariable Provider provider) {
        
        log.info("🗑️ Admin deleting VoIP config for tenant: {}, provider: {}", tenantId, provider);
        voipConfigAdminService.deleteVoipConfig(tenantId, provider);
        
        return ResponseEntity.noContent().build();
    }

    /**
     * Activate VoIP configuration
     * PATCH /api/admin/tenants/{tenantId}/voip-configs/{provider}/activate
     */
    @PatchMapping("/{provider}/activate")
    public ResponseEntity<Void> activateVoipConfig(
            @PathVariable String tenantId,
            @PathVariable Provider provider) {
        
        log.info("✅ Admin activating VoIP config for tenant: {}, provider: {}", tenantId, provider);
        voipConfigAdminService.toggleVoipConfig(tenantId, provider, true);
        
        return ResponseEntity.ok().build();
    }

    /**
     * Deactivate VoIP configuration
     * PATCH /api/admin/tenants/{tenantId}/voip-configs/{provider}/deactivate
     */
    @PatchMapping("/{provider}/deactivate")
    public ResponseEntity<Void> deactivateVoipConfig(
            @PathVariable String tenantId,
            @PathVariable Provider provider) {
        
        log.info("⛔ Admin deactivating VoIP config for tenant: {}, provider: {}", tenantId, provider);
        voipConfigAdminService.toggleVoipConfig(tenantId, provider, false);
        
        return ResponseEntity.ok().build();
    }
}
