package com.flightticket.controller;

import com.flightticket.dto.billing.PricingConfigRequest;
import com.flightticket.dto.billing.PricingConfigResponse;
import com.flightticket.model.entity.PricingConfig;
import com.flightticket.security.annotation.RequiresSuperAdmin;
import com.flightticket.service.PricingConfigService;
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.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * REST controller for managing API pricing configuration.
 * Provides endpoints for setting and retrieving global and client-specific pricing.
 * All endpoints require SUPER_ADMIN role.
 * 
 * Requirements: 2.1, 2.2, 2.5, 2.8, 8.1
 */
@Slf4j
@RestController
@RequestMapping("/api/admin/pricing")
@RequiresSuperAdmin
@RequiredArgsConstructor
public class PricingConfigController {
    
    private final PricingConfigService pricingConfigService;
    
    /**
     * Set global default pricing for a request type.
     * 
     * @param request The pricing configuration request
     * @return The created or updated pricing configuration
     * 
     * Requirements: 2.1, 2.2, 8.1
     */
    @PostMapping("/global")
    public ResponseEntity<PricingConfigResponse> setGlobalPrice(
            @Valid @RequestBody PricingConfigRequest request) {
        log.info("Setting global price for request type: {}, price: {}, currency: {}", 
                request.getRequestType(), request.getPrice(), request.getCurrency());
        
        PricingConfig config = pricingConfigService.setGlobalPrice(
                request.getRequestType(),
                request.getPrice(),
                request.getCurrency()
        );
        
        PricingConfigResponse response = toResponse(config);
        log.info("Global price set successfully with ID: {}", response.getId());
        
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }
    
    /**
     * Set client-specific pricing override for a request type.
     * 
     * @param clientId The client UUID
     * @param request The pricing configuration request
     * @return The created or updated pricing configuration
     * 
     * Requirements: 2.2, 2.5, 8.1
     */
    @PostMapping("/client/{clientId}")
    public ResponseEntity<PricingConfigResponse> setClientPrice(
            @PathVariable UUID clientId,
            @Valid @RequestBody PricingConfigRequest request) {
        log.info("Setting client-specific price for client: {}, request type: {}, price: {}, currency: {}", 
                clientId, request.getRequestType(), request.getPrice(), request.getCurrency());
        
        PricingConfig config = pricingConfigService.setClientPrice(
                clientId,
                request.getRequestType(),
                request.getPrice(),
                request.getCurrency()
        );
        
        PricingConfigResponse response = toResponse(config);
        log.info("Client-specific price set successfully with ID: {}", response.getId());
        
        return ResponseEntity.status(HttpStatus.CREATED).body(response);
    }
    
    /**
     * Get all global default pricing configurations.
     * 
     * @return List of all global pricing configurations
     * 
     * Requirements: 2.8
     */
    @GetMapping("/global")
    public ResponseEntity<List<PricingConfigResponse>> getAllGlobalPrices() {
        log.info("Retrieving all global pricing configurations");
        
        List<PricingConfig> configs = pricingConfigService.getAllGlobalPrices();
        List<PricingConfigResponse> responses = configs.stream()
                .map(this::toResponse)
                .collect(Collectors.toList());
        
        log.info("Retrieved {} global pricing configurations", responses.size());
        return ResponseEntity.ok(responses);
    }
    
    /**
     * Get all client-specific pricing configurations for a client.
     * 
     * @param clientId The client UUID
     * @return List of all pricing configurations for the client
     * 
     * Requirements: 2.8
     */
    @GetMapping("/client/{clientId}")
    public ResponseEntity<List<PricingConfigResponse>> getClientPrices(
            @PathVariable UUID clientId) {
        log.info("Retrieving pricing configurations for client: {}", clientId);
        
        List<PricingConfig> configs = pricingConfigService.getClientPrices(clientId);
        List<PricingConfigResponse> responses = configs.stream()
                .map(this::toResponse)
                .collect(Collectors.toList());
        
        log.info("Retrieved {} pricing configurations for client: {}", responses.size(), clientId);
        return ResponseEntity.ok(responses);
    }
    
    /**
     * Convert PricingConfig entity to PricingConfigResponse DTO.
     * 
     * @param config The pricing configuration entity
     * @return The pricing configuration response DTO
     */
    private PricingConfigResponse toResponse(PricingConfig config) {
        return new PricingConfigResponse(
                config.getId(),
                config.getClientId(),
                config.getRequestType(),
                config.getUnitPrice(),
                config.getCurrency(),
                config.getCreatedAt(),
                config.getUpdatedAt()
        );
    }
}
