package com.qqchen.deploy.backend.deploy.integration.impl;

import com.qqchen.deploy.backend.deploy.entity.ExternalSystem;
import com.qqchen.deploy.backend.deploy.integration.IGitServiceIntegration;
import com.qqchen.deploy.backend.deploy.integration.response.GitBranchResponse;
import com.qqchen.deploy.backend.deploy.integration.response.GitGroupResponse;
import com.qqchen.deploy.backend.deploy.integration.response.GitProjectResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Git服务集成实现
 * 主要负责与外部Git系统(如GitLab)的API交互
 */
@Slf4j
@Service
public class GitServiceIntegrationImpl implements IGitServiceIntegration {

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public boolean testConnection(ExternalSystem system) {
        try {
            String url = system.getUrl() + "/api/v4/version";
            HttpHeaders headers = createHeaders(system);
            HttpEntity<String> entity = new HttpEntity<>(headers);

            ResponseEntity<String> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                entity,
                String.class
            );

            return response.getStatusCode() == HttpStatus.OK;
        } catch (Exception e) {
            log.error("Git connection test failed for system: {}", system.getName(), e);
            return false;
        }
    }

    @Override
    public List<GitGroupResponse> groups(ExternalSystem system) {
        try {
            String url = String.format("%s/api/v4/groups?per_page=100", system.getUrl());
            HttpHeaders headers = createHeaders(system);
            HttpEntity<String> entity = new HttpEntity<>(headers);

            ResponseEntity<List<GitGroupResponse>> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                entity,
                new ParameterizedTypeReference<>() {
                }
            );

            return response.getBody() != null ? response.getBody() : Collections.emptyList();
        } catch (Exception e) {
            log.error("Failed to fetch git groups for system: {}", system.getName(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public List<GitProjectResponse> projects(ExternalSystem system) {
        try {
            String url = String.format("%s/api/v4/projects", system.getUrl());
            HttpHeaders headers = createHeaders(system);
            HttpEntity<String> entity = new HttpEntity<>(headers);

            ResponseEntity<List<GitProjectResponse>> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                entity,
                new ParameterizedTypeReference<>() {
                }
            );

            return response.getBody() != null ? response.getBody() : Collections.emptyList();
        } catch (Exception e) {
            log.error("Failed to fetch git projects for system: {}", system.getName(), e);
            return Collections.emptyList();
        }
    }

    @Override
    public List<GitProjectResponse> projectsByGroup(ExternalSystem system, Long groupId) {
        try {
            String url = String.format("%s/api/v4/groups/%d/projects?per_page=100", system.getUrl(), groupId);
            HttpHeaders headers = createHeaders(system);
            HttpEntity<String> entity = new HttpEntity<>(headers);

            ResponseEntity<List<GitProjectResponse>> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                entity,
                new ParameterizedTypeReference<>() {
                }
            );

            return response.getBody() != null ? response.getBody() : Collections.emptyList();
        } catch (Exception e) {
            log.error("Failed to fetch git projects for system: {} and group: {}", system.getName(), groupId, e);
            return Collections.emptyList();
        }
    }

    @Override
    public List<GitBranchResponse> branches(ExternalSystem system, Long projectId) {
        try {
            String url = String.format("%s/api/v4/projects/%d/repository/branches?per_page=100", system.getUrl(), projectId);
            HttpHeaders headers = createHeaders(system);
            HttpEntity<String> entity = new HttpEntity<>(headers);
            // 然后解析为对象
            ResponseEntity<List<GitBranchResponse>> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                entity,
                new ParameterizedTypeReference<>() {
                }
            );

            List<GitBranchResponse> branches = response.getBody();
            if (branches != null && !branches.isEmpty()) {
                log.info("Found {} branches, first branch: {}", branches.size(), branches.getFirst().getName());
            } else {
                log.warn("No branches found for project: {}", projectId);
            }

            return branches != null ? branches : Collections.emptyList();
        } catch (Exception e) {
            log.error("Failed to fetch git branches for system: {} and project: {}", system.getName(), projectId, e);
            return Collections.emptyList();
        }
    }

    /**
     * 创建HTTP请求头
     */
    private HttpHeaders createHeaders(ExternalSystem system) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 根据认证类型设置认证信息
        switch (system.getAuthType()) {
            case BASIC -> {
                // Basic认证
                String auth = system.getUsername() + ":" + system.getPassword();
                byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
                String authHeader = "Basic " + new String(encodedAuth);
                headers.set("Authorization", authHeader);
            }
            case TOKEN -> {
                // Token认证 - GitLab使用Private Token
                headers.set("PRIVATE-TOKEN", system.getToken());
            }
            case OAUTH -> {
                // OAuth认证
                headers.set("Authorization", "Bearer " + system.getToken());
            }
            default -> throw new RuntimeException("Unsupported authentication type: " + system.getAuthType());
        }

        return headers;
    }
}