package com.social.media.interfaces.web.controller;

import com.social.media.application.campaign.command.CreateAutomationCampaignCommand;
import com.social.media.application.campaign.dto.AutomationCampaignDto;
import com.social.media.application.campaign.dto.CampaignExecutionDto;
import com.social.media.application.campaign.service.AutomationCampaignApplicationService;
import com.social.media.domain.campaign.valueobject.CampaignStatus;
import com.social.media.domain.campaign.valueobject.CampaignType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import com.social.media.domain.user.valueobject.UserId;

import java.util.List;
import java.util.Map;

/**
 * REST Controller for Automation Campaign Management
 */
@RestController
@RequestMapping("/api/v1/automation-campaigns")
@RequiredArgsConstructor
@Tag(name = "Automation Campaigns", description = "Automation campaign management operations")
public class AutomationCampaignController {
    
    private final AutomationCampaignApplicationService campaignService;
    
    @PostMapping
    @Operation(summary = "Create a new automation campaign")
    public ResponseEntity<AutomationCampaignDto> createCampaign(
            @Valid @RequestBody CreateAutomationCampaignCommand command) {
        
        var authInfo = getAuthenticatedUserInfo();
        // Authentication context handled by the service layer
        
        AutomationCampaignDto created = campaignService.createCampaign(command);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }
    
    @GetMapping("/{id}")
    @Operation(summary = "Get campaign by ID")
    public ResponseEntity<AutomationCampaignDto> getCampaignById(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        
        var authInfo = getAuthenticatedUserInfo();
        AutomationCampaignDto campaign = campaignService.getCampaignById(id);
        return ResponseEntity.ok(campaign);
    }
    
    @GetMapping("/code/{campaignCode}")
    @Operation(summary = "Get campaign by code")
    public ResponseEntity<AutomationCampaignDto> getCampaignByCode(
            @Parameter(description = "Campaign code") @PathVariable String campaignCode) {
        AutomationCampaignDto campaign = campaignService.getCampaignByCode(campaignCode);
        return ResponseEntity.ok(campaign);
    }
    
    @GetMapping
    @Operation(summary = "Get campaigns with filtering and pagination")
    public ResponseEntity<Page<AutomationCampaignDto>> getCampaigns(
            @Parameter(description = "Company ID") @RequestParam(required = false) Long companyId,
            @Parameter(description = "Campaign status") @RequestParam(required = false) CampaignStatus status,
            @Parameter(description = "Campaign type") @RequestParam(required = false) CampaignType type,
            @Parameter(description = "Social account ID") @RequestParam(required = false) Long socialAccountId,
            @PageableDefault(size = 20) Pageable pageable) {
        
        var authInfo = getAuthenticatedUserInfo();
        
        // Use logged user's company if companyId not provided or different from user's company
        Long validatedCompanyId = (companyId == null || !companyId.equals(authInfo.companyId())) 
                                    ? authInfo.companyId() 
                                    : companyId;
        
        Page<AutomationCampaignDto> campaigns = campaignService.getCampaigns(
                validatedCompanyId, status, type, socialAccountId, pageable);
        return ResponseEntity.ok(campaigns);
    }
    
    @PutMapping("/{id}")
    @Operation(summary = "Update campaign")
    public ResponseEntity<AutomationCampaignDto> updateCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id,
            @Valid @RequestBody AutomationCampaignDto campaignDto) {
        AutomationCampaignDto updated = campaignService.updateCampaign(id, campaignDto);
        return ResponseEntity.ok(updated);
    }
    
    @PostMapping("/{id}/start")
    @Operation(summary = "Start campaign")
    public ResponseEntity<AutomationCampaignDto> startCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignDto campaign = campaignService.startCampaign(id);
        return ResponseEntity.ok(campaign);
    }
    
    @PostMapping("/{id}/pause")
    @Operation(summary = "Pause campaign")
    public ResponseEntity<AutomationCampaignDto> pauseCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignDto campaign = campaignService.pauseCampaign(id);
        return ResponseEntity.ok(campaign);
    }
    
    @PostMapping("/{id}/resume")
    @Operation(summary = "Resume campaign")
    public ResponseEntity<AutomationCampaignDto> resumeCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignDto campaign = campaignService.resumeCampaign(id);
        return ResponseEntity.ok(campaign);
    }
    
    @PostMapping("/{id}/complete")
    @Operation(summary = "Complete campaign")
    public ResponseEntity<AutomationCampaignDto> completeCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignDto campaign = campaignService.completeCampaign(id);
        return ResponseEntity.ok(campaign);
    }
    
    @PostMapping("/{id}/cancel")
    @Operation(summary = "Cancel campaign")
    public ResponseEntity<AutomationCampaignDto> cancelCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignDto campaign = campaignService.cancelCampaign(id);
        return ResponseEntity.ok(campaign);
    }
    
    @DeleteMapping("/{id}")
    @Operation(summary = "Delete campaign")
    public ResponseEntity<Void> deleteCampaign(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        campaignService.deleteCampaign(id);
        return ResponseEntity.noContent().build();
    }
    
    @GetMapping("/{id}/executions")
    @Operation(summary = "Get campaign executions")
    public ResponseEntity<Page<CampaignExecutionDto>> getCampaignExecutions(
            @Parameter(description = "Campaign ID") @PathVariable Long id,
            @PageableDefault(size = 20) Pageable pageable) {
        Page<CampaignExecutionDto> executions = campaignService.getCampaignExecutions(id, pageable);
        return ResponseEntity.ok(executions);
    }
    
    @GetMapping("/{id}/statistics")
    @Operation(summary = "Get campaign statistics")
    public ResponseEntity<AutomationCampaignApplicationService.CampaignStatisticsDto> getCampaignStatistics(
            @Parameter(description = "Campaign ID") @PathVariable Long id) {
        AutomationCampaignApplicationService.CampaignStatisticsDto statistics = campaignService.getCampaignStatistics(id);
        return ResponseEntity.ok(statistics);
    }
    
    @GetMapping("/company/{companyId}/statistics")
    @Operation(summary = "Get company campaigns statistics")
    public ResponseEntity<Map<String, Object>> getCompanyStatistics(
            @Parameter(description = "Company ID") @PathVariable Long companyId) {
        Map<String, Object> statistics = campaignService.getCompanyStatistics(companyId);
        return ResponseEntity.ok(statistics);
    }
    
    @GetMapping("/scheduled")
    @Operation(summary = "Get campaigns ready to start")
    public ResponseEntity<List<AutomationCampaignDto>> getScheduledCampaigns() {
        List<AutomationCampaignDto> campaigns = campaignService.getCampaignsReadyToStart();
        return ResponseEntity.ok(campaigns);
    }
    
    @GetMapping("/ending")
    @Operation(summary = "Get campaigns ready to end")
    public ResponseEntity<List<AutomationCampaignDto>> getEndingCampaigns() {
        var authInfo = getAuthenticatedUserInfo();
        List<AutomationCampaignDto> campaigns = campaignService.getCampaignsReadyToEnd();
        return ResponseEntity.ok(campaigns);
    }
    
    /**
     * Helper method to get authenticated user information
     */
    private AuthenticatedUserInfo getAuthenticatedUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("User not authenticated");
        }
        
        // Extract user ID and company ID from authentication
        Long userId = extractUserIdFromAuthentication(authentication);
        Long companyId = extractCompanyIdFromAuthentication(authentication);
        
        return new AuthenticatedUserInfo(UserId.of(userId), companyId);
    }
    
    private Long extractUserIdFromAuthentication(Authentication authentication) {
        // TODO: Implement based on your JWT/session structure
        return 1L; // Temporary
    }
    
    private Long extractCompanyIdFromAuthentication(Authentication authentication) {
        // TODO: Implement based on your JWT/session structure
        return 1L; // Temporary
    }
    
    /**
     * Record to hold authenticated user information
     */
    private record AuthenticatedUserInfo(UserId userId, Long companyId) {}
}
