package com.gcsc.connection.apikey.service;

import com.gcsc.connection.apikey.dto.PermissionResponse;
import com.gcsc.connection.apikey.dto.UpdatePermissionsRequest;
import com.gcsc.connection.apikey.entity.SnpApiKey;
import com.gcsc.connection.apikey.entity.SnpApiPermission;
import com.gcsc.connection.apikey.repository.SnpApiKeyRepository;
import com.gcsc.connection.apikey.repository.SnpApiPermissionRepository;
import com.gcsc.connection.common.exception.BusinessException;
import com.gcsc.connection.common.exception.ErrorCode;
import com.gcsc.connection.service.repository.SnpServiceApiRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * API Key 권한 관리 서비스
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ApiKeyPermissionService {

    private final SnpApiPermissionRepository snpApiPermissionRepository;
    private final SnpApiKeyRepository snpApiKeyRepository;
    private final SnpServiceApiRepository snpServiceApiRepository;

    /**
     * API Key 권한 목록 조회
     */
    @Transactional(readOnly = true)
    public List<PermissionResponse> getPermissions(Long apiKeyId) {
        return snpApiPermissionRepository.findByApiKeyApiKeyId(apiKeyId).stream()
            .map(PermissionResponse::from)
            .toList();
    }

    /**
     * API Key 권한 수정 (기존 삭제 후 재생성)
     */
    @Transactional
    public List<PermissionResponse> updatePermissions(Long apiKeyId, Long grantedByUserId,
                                                      UpdatePermissionsRequest request) {
        SnpApiKey apiKey = snpApiKeyRepository.findById(apiKeyId)
            .orElseThrow(() -> new BusinessException(ErrorCode.API_KEY_NOT_FOUND));

        snpApiPermissionRepository.deleteByApiKeyApiKeyId(apiKeyId);
        snpApiPermissionRepository.flush();

        if (request.apiIds() == null || request.apiIds().isEmpty()) {
            return List.of();
        }

        List<SnpApiPermission> permissions = request.apiIds().stream()
            .map(apiId -> snpServiceApiRepository.findById(apiId)
                .map(serviceApi -> SnpApiPermission.builder()
                    .apiKey(apiKey)
                    .api(serviceApi)
                    .isActive(true)
                    .grantedBy(grantedByUserId)
                    .grantedAt(LocalDateTime.now())
                    .build())
                .orElse(null))
            .filter(perm -> perm != null)
            .toList();

        List<SnpApiPermission> saved = snpApiPermissionRepository.saveAll(permissions);
        return saved.stream()
            .map(PermissionResponse::from)
            .toList();
    }
}
