package kz.konturai.parser.service;

import kz.konturai.parser.model.SocialMediaCredentials;
import kz.konturai.parser.repository.SocialMediaCredentialsRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

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

@Service
public class SocialMediaCredentialsService {

    private static final Logger logger = LoggerFactory.getLogger(SocialMediaCredentialsService.class);

    private final SocialMediaCredentialsRepository repository;
    private final EncryptionService encryptionService;

    public SocialMediaCredentialsService(
            SocialMediaCredentialsRepository repository,
            EncryptionService encryptionService) {
        this.repository = repository;
        this.encryptionService = encryptionService;
    }

    /**
     * Сохраняет или обновляет credentials пользователя для платформы
     * 
     * @param userId      ID пользователя
     * @param platform    Платформа (facebook, instagram, telegram, etc.)
     * @param credentials Открытые credentials (могут быть String для токена или
     *                    JSON строка для объектов, например для Telegram:
     *                    {"botToken": "...", "chatId": "..."})
     * @return Сохраненные credentials
     */
    public SocialMediaCredentials saveCredentials(String userId, String platform, String credentials) {
        if (userId == null || platform == null || credentials == null || credentials.isEmpty()) {
            throw new IllegalArgumentException("UserId, platform and credentials are required");
        }

        // Проверяем существующие credentials
        Optional<SocialMediaCredentials> existing = repository.findByUserIdAndPlatform(userId, platform);

        SocialMediaCredentials credentialsEntity;
        if (existing.isPresent()) {
            credentialsEntity = existing.get();
            logger.info("Updating existing credentials for user {} and platform {}", userId, platform);
        } else {
            credentialsEntity = new SocialMediaCredentials();
            credentialsEntity.setUserId(userId);
            credentialsEntity.setPlatform(platform.toLowerCase());
            logger.info("Creating new credentials for user {} and platform {}", userId, platform);
        }

        // Шифруем credentials перед сохранением
        String encryptedCredentials = encryptionService.encrypt(credentials);
        credentialsEntity.setEncryptedCredentials(encryptedCredentials);

        return repository.save(credentialsEntity);
    }

    /**
     * Получает и расшифровывает credentials пользователя для платформы
     * 
     * @param userId   ID пользователя
     * @param platform Платформа
     * @return Расшифрованные credentials или null если не найдены
     */
    public String getCredentials(String userId, String platform) {
        if (userId == null || platform == null) {
            return null;
        }

        Optional<SocialMediaCredentials> optCredentials = repository.findByUserIdAndPlatform(
                userId, platform.toLowerCase());

        if (optCredentials.isEmpty()) {
            logger.debug("Credentials not found for user {} and platform {}", userId, platform);
            return null;
        }

        try {
            SocialMediaCredentials credentialsEntity = optCredentials.get();
            Object encryptedCreds = credentialsEntity.getEncryptedCredentials();

            // Если это String (старый формат или зашифрованная строка), расшифровываем
            if (encryptedCreds instanceof String) {
                return encryptionService.decrypt((String) encryptedCreds);
            }

            // Если это Object (например, Map из MongoDB), сериализуем в JSON, затем
            // расшифровываем
            // Но обычно зашифрованные данные хранятся как String
            if (encryptedCreds != null) {
                String encryptedString = encryptedCreds.toString();
                return encryptionService.decrypt(encryptedString);
            }

            return null;
        } catch (Exception e) {
            logger.error("Failed to decrypt credentials for user {} and platform {}", userId, platform, e);
            throw new RuntimeException("Failed to decrypt credentials", e);
        }
    }

    /**
     * Проверяет наличие credentials для пользователя и платформы
     * 
     * @param userId   ID пользователя
     * @param platform Платформа
     * @return true если credentials существуют
     */
    public boolean hasCredentials(String userId, String platform) {
        if (userId == null || platform == null) {
            return false;
        }

        return repository.findByUserIdAndPlatform(userId, platform.toLowerCase()).isPresent();
    }

    /**
     * Удаляет credentials пользователя для платформы
     * 
     * @param userId   ID пользователя
     * @param platform Платформа
     */
    public void deleteCredentials(String userId, String platform) {
        if (userId == null || platform == null) {
            throw new IllegalArgumentException("UserId and platform are required");
        }

        repository.deleteByUserIdAndPlatform(userId, platform.toLowerCase());
        logger.info("Deleted credentials for user {} and platform {}", userId, platform);
    }

    /**
     * Получает список всех платформ, для которых у пользователя есть credentials
     * 
     * @param userId ID пользователя
     * @return Список платформ
     */
    public List<String> getUserPlatforms(String userId) {
        if (userId == null) {
            return List.of();
        }

        return repository.findByUserId(userId).stream()
                .map(SocialMediaCredentials::getPlatform)
                .toList();
    }

    /**
     * Получает все credentials пользователя (без расшифровки)
     * 
     * @param userId ID пользователя
     * @return Список credentials entities
     */
    public List<SocialMediaCredentials> getUserCredentials(String userId) {
        if (userId == null) {
            return List.of();
        }

        return repository.findByUserId(userId);
    }

    /**
     * Обновляет выбранный рекламный аккаунт для платформы
     *
     * @param userId      ID пользователя
     * @param platform    Платформа
     * @param adAccountId ID выбранного рекламного кабинета
     */
    public void updateAdAccountId(String userId, String platform, String adAccountId) {
        if (userId == null || platform == null || adAccountId == null) {
            throw new IllegalArgumentException("UserId, platform and adAccountId are required");
        }
        
        Optional<SocialMediaCredentials> existing = repository.findByUserIdAndPlatform(userId, platform.toLowerCase());
        if (existing.isPresent()) {
            SocialMediaCredentials credentials = existing.get();
            credentials.setAdAccountId(adAccountId);
            repository.save(credentials);
            logger.info("Updated adAccountId for user {} and platform {}", userId, platform);
        } else {
            throw new IllegalArgumentException("Credentials not found for user " + userId + " and platform " + platform);
        }
    }
}
