package com.social.media.controller;

import com.social.media.dto.SocialAccountDto;
import com.social.media.domain.entity.SocialAccount;
import com.social.media.service.SocialAccountService;
import com.social.media.domain.shared.PageResponse;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/social-accounts")
public class SocialAccountController {
    
    @Autowired
    private SocialAccountService socialAccountService;
    
    // CRUD Operations
    @GetMapping
    public ResponseEntity<PageResponse<SocialAccountDto>> getAllSocialAccounts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAllSocialAccounts(page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<SocialAccountDto> getSocialAccountById(@PathVariable Long id) {
        SocialAccountDto account = socialAccountService.getSocialAccountById(id);
        return ResponseEntity.ok(account);
    }
    
    @PostMapping
    public ResponseEntity<SocialAccountDto> createSocialAccount(@Valid @RequestBody SocialAccountDto socialAccountDto) {
        SocialAccountDto createdAccount = socialAccountService.createSocialAccount(socialAccountDto);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdAccount);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<SocialAccountDto> updateSocialAccount(
            @PathVariable Long id, 
            @Valid @RequestBody SocialAccountDto socialAccountDto) {
        SocialAccountDto updatedAccount = socialAccountService.updateSocialAccount(id, socialAccountDto);
        return ResponseEntity.ok(updatedAccount);
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteSocialAccount(@PathVariable Long id) {
        socialAccountService.deleteSocialAccount(id);
        return ResponseEntity.noContent().build();
    }
    
    // Company-based queries
    @GetMapping("/company/{companyId}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByCompany(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByCompany(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/active")
    public ResponseEntity<PageResponse<SocialAccountDto>> getActiveAccountsByCompany(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getActiveAccountsByCompany(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/connected")
    public ResponseEntity<PageResponse<SocialAccountDto>> getConnectedAccountsByCompany(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getConnectedAccountsByCompany(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    // Social network queries
    @GetMapping("/social-network/{socialNetworkId}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsBySocialNetwork(
            @PathVariable Long socialNetworkId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsBySocialNetwork(socialNetworkId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    // User-based queries
    @GetMapping("/user/{responsibleUserId}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByResponsibleUser(
            @PathVariable Long responsibleUserId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByResponsibleUser(responsibleUserId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    // Search and filtering
    @GetMapping("/search")
    public ResponseEntity<PageResponse<SocialAccountDto>> searchAccountsByUsername(
            @RequestParam String username,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.searchAccountsByUsername(username, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/search")
    public ResponseEntity<PageResponse<SocialAccountDto>> searchAccountsByNameOrUsername(
            @PathVariable Long companyId,
            @RequestParam String searchTerm,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.searchAccountsByNameOrUsername(companyId, searchTerm, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/status/{status}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByConnectionStatus(
            @PathVariable Long companyId,
            @PathVariable SocialAccount.ConnectionStatus status,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByConnectionStatus(companyId, status, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/engagement-range")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByEngagementRange(
            @RequestParam Double minEngagement,
            @RequestParam Double maxEngagement,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByEngagementRange(minEngagement, maxEngagement, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/followers-range")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByFollowersRange(
            @RequestParam Integer minFollowers,
            @RequestParam Integer maxFollowers,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByFollowersRange(minFollowers, maxFollowers, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    // Analytics and metrics
    @GetMapping("/company/{companyId}/top-followers")
    public ResponseEntity<PageResponse<SocialAccountDto>> getTopAccountsByFollowers(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getTopAccountsByFollowers(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/top-engagement")
    public ResponseEntity<PageResponse<SocialAccountDto>> getTopAccountsByEngagement(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getTopAccountsByEngagement(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/total-followers")
    public ResponseEntity<Long> getTotalFollowersByCompany(@PathVariable Long companyId) {
        Long totalFollowers = socialAccountService.getTotalFollowersByCompany(companyId);
        return ResponseEntity.ok(totalFollowers);
    }
    
    @GetMapping("/company/{companyId}/average-engagement")
    public ResponseEntity<Double> getAverageEngagementByCompany(@PathVariable Long companyId) {
        Double averageEngagement = socialAccountService.getAverageEngagementByCompany(companyId);
        return ResponseEntity.ok(averageEngagement);
    }
    
    @GetMapping("/reaching-follower-targets")
    public ResponseEntity<List<SocialAccountDto>> getAccountsReachingFollowerTargets() {
        List<SocialAccountDto> accounts = socialAccountService.getAccountsReachingFollowerTargets();
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/reaching-engagement-targets")
    public ResponseEntity<List<SocialAccountDto>> getAccountsReachingEngagementTargets() {
        List<SocialAccountDto> accounts = socialAccountService.getAccountsReachingEngagementTargets();
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/summary")
    public ResponseEntity<List<Object[]>> getConnectedAccountsSummaryByCompany(@PathVariable Long companyId) {
        List<Object[]> summary = socialAccountService.getConnectedAccountsSummaryByCompany(companyId);
        return ResponseEntity.ok(summary);
    }
    
    // Account management
    @PostMapping("/{id}/connect")
    public ResponseEntity<SocialAccountDto> connectAccount(
            @PathVariable Long id,
            @RequestBody Map<String, Object> connectionData) {
        SocialAccountDto account = socialAccountService.connectAccount(id, connectionData);
        return ResponseEntity.ok(account);
    }
    
    @PostMapping("/{id}/disconnect")
    public ResponseEntity<SocialAccountDto> disconnectAccount(@PathVariable Long id) {
        SocialAccountDto account = socialAccountService.disconnectAccount(id);
        return ResponseEntity.ok(account);
    }
    
    @PostMapping("/{id}/sync")
    public ResponseEntity<SocialAccountDto> syncAccount(@PathVariable Long id) {
        SocialAccountDto syncedAccount = socialAccountService.syncAccount(id);
        return ResponseEntity.ok(syncedAccount);
    }
    
    @PostMapping("/company/{companyId}/sync-all")
    public ResponseEntity<List<SocialAccountDto>> syncAccountsForCompany(@PathVariable Long companyId) {
        List<SocialAccountDto> syncedAccounts = socialAccountService.syncAccountsForCompany(companyId);
        return ResponseEntity.ok(syncedAccounts);
    }
    
    @GetMapping("/needing-sync")
    public ResponseEntity<List<SocialAccountDto>> getAccountsNeedingSync() {
        List<SocialAccountDto> accounts = socialAccountService.getAccountsNeedingSync();
        return ResponseEntity.ok(accounts);
    }
    
    // Validation and checks
    @GetMapping("/check-account-code")
    public ResponseEntity<Boolean> checkAccountCodeExists(@RequestParam String accountCode) {
        boolean exists = socialAccountService.existsByAccountCode(accountCode);
        return ResponseEntity.ok(exists);
    }
    
    @GetMapping("/check-username")
    public ResponseEntity<Boolean> checkUsernameExists(
            @RequestParam Long companyId,
            @RequestParam Long socialNetworkId,
            @RequestParam String username) {
        boolean exists = socialAccountService.existsByCompanyAndSocialNetworkAndUsername(companyId, socialNetworkId, username);
        return ResponseEntity.ok(exists);
    }
    
    // Metrics and performance
    @PutMapping("/{id}/metrics")
    public ResponseEntity<SocialAccountDto> updateAccountMetrics(
            @PathVariable Long id,
            @RequestBody Map<String, Object> metrics) {
        SocialAccountDto account = socialAccountService.updateAccountMetrics(id, metrics);
        return ResponseEntity.ok(account);
    }
    
    @GetMapping("/low-performing")
    public ResponseEntity<List<SocialAccountDto>> getLowPerformingAccounts() {
        List<SocialAccountDto> accounts = socialAccountService.getLowPerformingAccounts();
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/stale-metrics")
    public ResponseEntity<List<SocialAccountDto>> getAccountsWithStaleMetrics(
            @RequestParam(required = false) String cutoffDateStr) {
        LocalDateTime cutoffDate = cutoffDateStr != null ? 
            LocalDateTime.parse(cutoffDateStr) : 
            LocalDateTime.now().minusDays(7); // Default to 7 days ago
        List<SocialAccountDto> accounts = socialAccountService.getAccountsWithStaleMetrics(cutoffDate);
        return ResponseEntity.ok(accounts);
    }
    
    // Filtering by account properties
    @GetMapping("/verified")
    public ResponseEntity<PageResponse<SocialAccountDto>> getVerifiedAccounts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getVerifiedAccounts(page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/company/{companyId}/business")
    public ResponseEntity<PageResponse<SocialAccountDto>> getBusinessAccounts(
            @PathVariable Long companyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getBusinessAccounts(companyId, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/type/{accountType}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByType(
            @PathVariable String accountType,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByType(accountType, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/category/{businessCategory}")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsByCategory(
            @PathVariable String businessCategory,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsByCategory(businessCategory, page, size);
        return ResponseEntity.ok(accounts);
    }
    
    @GetMapping("/sync-errors")
    public ResponseEntity<PageResponse<SocialAccountDto>> getAccountsWithSyncErrors(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        PageResponse<SocialAccountDto> accounts = socialAccountService.getAccountsWithSyncErrors(page, size);
        return ResponseEntity.ok(accounts);
    }
    
    // Statistics
    @GetMapping("/company/{companyId}/count")
    public ResponseEntity<Long> countAccountsByCompany(@PathVariable Long companyId) {
        Long count = socialAccountService.countAccountsByCompany(companyId);
        return ResponseEntity.ok(count);
    }
    
    @GetMapping("/company/{companyId}/count-active")
    public ResponseEntity<Long> countActiveAccountsByCompany(@PathVariable Long companyId) {
        Long count = socialAccountService.countActiveAccountsByCompany(companyId);
        return ResponseEntity.ok(count);
    }
    
    @GetMapping("/company/{companyId}/count-connected")
    public ResponseEntity<Long> countConnectedAccountsByCompany(@PathVariable Long companyId) {
        Long count = socialAccountService.countConnectedAccountsByCompany(companyId);
        return ResponseEntity.ok(count);
    }
    
    @GetMapping("/social-network/{socialNetworkId}/count")
    public ResponseEntity<Long> countAccountsBySocialNetwork(@PathVariable Long socialNetworkId) {
        Long count = socialAccountService.countAccountsBySocialNetwork(socialNetworkId);
        return ResponseEntity.ok(count);
    }
}
