package com.social.media.application.socialaccount.service;

import com.social.media.application.socialaccount.command.ConnectSocialAccountCommand;
import com.social.media.application.socialaccount.command.DisconnectSocialAccountCommand;
import com.social.media.application.socialaccount.command.UpdateSocialAccountCommand;
import com.social.media.application.socialaccount.dto.SocialAccountResponseDto;
import com.social.media.infrastructure.persistence.socialaccount.SocialAccountRepositoryAdapter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Application Service for Social Account Context
 * Orchestrates business operations for social accounts
 */
@Service
@Transactional
public class SocialAccountApplicationService {
    
    private final SocialAccountRepositoryAdapter socialAccountRepository;
    
    public SocialAccountApplicationService(SocialAccountRepositoryAdapter socialAccountRepository) {
        this.socialAccountRepository = socialAccountRepository;
    }
    
    // Command Operations
    
    /**
     * Connect a new social account
     */
    public SocialAccountResponseDto connectSocialAccount(ConnectSocialAccountCommand command) {
        // Validate business rules
        Long socialNetworkId = Long.parseLong(command.socialNetworkId());
        
        // Check if account already exists
        if (socialAccountRepository.existsByUsernameAndSocialNetworkId(command.username(), socialNetworkId)) {
            throw new IllegalArgumentException("Social account already exists for this username and platform");
        }
        
        // Connect the account
        return socialAccountRepository.connectSocialAccount(
            command.companyId(),
            socialNetworkId,
            command.username(),
            command.accessToken(),
            command.refreshToken(),
            command.tokenType()
        );
    }
    
    /**
     * Update an existing social account
     */
    public SocialAccountResponseDto updateSocialAccount(UpdateSocialAccountCommand command) {
        Long id = Long.parseLong(command.socialAccountId());
        
        // Verify account exists
        if (socialAccountRepository.findById(id).isEmpty()) {
            throw new IllegalArgumentException("Social account not found with ID: " + id);
        }
        
        return socialAccountRepository.updateSocialAccount(
            id,
            command.displayName(),
            command.bio(),
            command.location(),
            command.website(),
            command.profilePhotoUrl(),
            command.contactPhone(),
            command.contactEmail(),
            command.category(),
            command.automationConfig(),
            command.responsibleUserId()
        );
    }
    
    /**
     * Disconnect a social account
     */
    public void disconnectSocialAccount(DisconnectSocialAccountCommand command) {
        Long id = Long.parseLong(command.socialAccountId());
        
        // Verify account exists
        if (socialAccountRepository.findById(id).isEmpty()) {
            throw new IllegalArgumentException("Social account not found with ID: " + id);
        }
        
        socialAccountRepository.disconnectSocialAccount(id);
    }
    
    /**
     * Delete a social account (soft delete)
     */
    public void deleteSocialAccount(String socialAccountId) {
        Long id = Long.parseLong(socialAccountId);
        
        // Verify account exists
        if (socialAccountRepository.findById(id).isEmpty()) {
            throw new IllegalArgumentException("Social account not found with ID: " + id);
        }
        
        socialAccountRepository.softDelete(id);
    }
    
    // Query Operations
    
    /**
     * Get social account by ID
     */
    public SocialAccountResponseDto getSocialAccountById(String socialAccountId) {
        Long id = Long.parseLong(socialAccountId);
        return socialAccountRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("Social account not found with ID: " + id));
    }
    
    /**
     * Get all social accounts for a company
     */
    public List<SocialAccountResponseDto> getSocialAccountsByCompany(String companyId) {
        Long id = Long.parseLong(companyId);
        return socialAccountRepository.findByCompanyId(id);
    }
    
    /**
     * Get all social accounts for a user
     */
    public List<SocialAccountResponseDto> getSocialAccountsByUser(String userId) {
        Long id = Long.parseLong(userId);
        return socialAccountRepository.findByResponsibleUserId(id);
    }
    
    /**
     * Get active social accounts for a company
     */
    public List<SocialAccountResponseDto> getActiveSocialAccountsByCompany(String companyId) {
        Long id = Long.parseLong(companyId);
        return socialAccountRepository.findActiveAccountsByCompanyId(id);
    }
    
    /**
     * Search social accounts by term
     */
    public List<SocialAccountResponseDto> searchSocialAccounts(String companyId, String searchTerm) {
        Long id = Long.parseLong(companyId);
        return socialAccountRepository.searchByUsernameOrDisplayName(id, searchTerm, 
                org.springframework.data.domain.Pageable.unpaged()).getContent();
    }
    
    /**
     * Toggle social account active status
     */
    public SocialAccountResponseDto toggleSocialAccountStatus(String socialAccountId) {
        Long id = Long.parseLong(socialAccountId);
        
        // Verify account exists
        if (socialAccountRepository.findById(id).isEmpty()) {
            throw new IllegalArgumentException("Social account not found with ID: " + id);
        }
        
        return socialAccountRepository.toggleActiveStatus(id);
    }
    
    /**
     * Sync social account data
     */
    public SocialAccountResponseDto syncSocialAccount(String socialAccountId) {
        Long id = Long.parseLong(socialAccountId);
        
        // Verify account exists
        SocialAccountResponseDto account = socialAccountRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("Social account not found with ID: " + id));
        
        // TODO: Implement actual sync logic with social media APIs
        // For now, just update the sync timestamp
        socialAccountRepository.updateSyncTimestamp(id);
        
        return socialAccountRepository.findById(id).get();
    }
    
    /**
     * Refresh authentication tokens
     */
    public SocialAccountResponseDto refreshTokens(String socialAccountId) {
        Long id = Long.parseLong(socialAccountId);
        
        // Verify account exists
        SocialAccountResponseDto account = socialAccountRepository.findById(id)
            .orElseThrow(() -> new IllegalArgumentException("Social account not found with ID: " + id));
        
        // TODO: Implement actual token refresh logic with social media APIs
        // For now, just update the sync timestamp
        socialAccountRepository.updateSyncTimestamp(id);
        
        return socialAccountRepository.findById(id).get();
    }
    
    /**
     * Get social accounts count by company
     */
    public long getSocialAccountsCountByCompany(String companyId) {
        Long id = Long.parseLong(companyId);
        return socialAccountRepository.countByCompanyId(id);
    }
    
    /**
     * Get active social accounts count by company
     */
    public long getActiveSocialAccountsCountByCompany(String companyId) {
        Long id = Long.parseLong(companyId);
        return socialAccountRepository.countActiveByCompanyId(id);
    }
}

