package com.erp.ai.service;

import com.erp.ai.client.OpenClawClient;
import com.erp.ai.config.OpenClawProperties;
import com.erp.ai.exception.OpenClawException;
import com.erp.ai.mapper.AiAgentMapper;
import com.erp.ai.mapper.AiLlmProviderMapper;
import com.erp.ai.model.AiAgent;
import com.erp.ai.model.AiLlmProvider;
import com.erp.ai.util.AesGcmCipher;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Pipeline DB → OpenClaw config 동기화.
 * vexplor openClawSyncService.ts 1:1 포팅 (HTTP API 방식).
 * OpenClaw 가 비활성(enabled=false) 이면 모든 메서드는 no-op.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OpenClawSyncService {

    private final AiLlmProviderMapper providerMapper;
    private final AiAgentMapper agentMapper;
    private final AesGcmCipher cipher;
    private final OpenClawClient openClawClient;
    private final OpenClawProperties openClawProperties;

    /**
     * LLM 프로바이더를 OpenClaw auth profiles 로 동기화.
     */
    public void syncProviders() {
        if (!openClawProperties.isEnabled()) {
            log.debug("OpenClaw 비활성 — providers sync skip");
            return;
        }
        try {
            List<AiLlmProvider> providers = providerMapper.listActive();
            Map<String, Object> authProfiles = new HashMap<>();
            for (AiLlmProvider p : providers) {
                String decryptedKey = cipher.decrypt(p.getApi_key_encrypted());
                String profileKey = "pipeline-" + p.getName() + "-" + p.getId();
                Map<String, Object> profile = buildAuthProfile(p, decryptedKey);
                if (profile != null) authProfiles.put(profileKey, profile);
            }

            Map<String, Object> body = new HashMap<>();
            body.put("authProfiles", authProfiles);
            if (!providers.isEmpty()) {
                AiLlmProvider primary = providers.get(0);
                Map<String, Object> models = new HashMap<>();
                models.put("default", primary.getName() + ":" + primary.getModel_name());
                models.put("authProfile", "pipeline-" + primary.getName() + "-" + primary.getId());
                body.put("models", models);
            }

            openClawClient.syncAuthProfiles(body);
            log.info("OpenClaw 프로바이더 동기화: {}개", providers.size());
        } catch (OpenClawException e) {
            log.warn("OpenClaw 프로바이더 동기화 실패 (graceful): {}", e.getMessage());
        } catch (Exception e) {
            log.error("OpenClaw 프로바이더 동기화 오류", e);
        }
    }

    /**
     * 에이전트를 OpenClaw agents 로 동기화.
     */
    public void syncAgents() {
        if (!openClawProperties.isEnabled()) {
            log.debug("OpenClaw 비활성 — agents sync skip");
            return;
        }
        try {
            List<AiAgent> agents = agentMapper.getActiveAgents();
            Map<String, Object> clawAgents = new HashMap<>();
            for (AiAgent agent : agents) {
                Map<String, Object> entry = new HashMap<>();
                entry.put("displayName", agent.getName());
                entry.put("description", agent.getDescription() != null ? agent.getDescription() : "");
                entry.put("model", agent.getModel());
                entry.put("systemPrompt", agent.getSystem_prompt() != null ? agent.getSystem_prompt() : "");
                entry.put("tools", agent.getTools());
                entry.put("config", agent.getConfig());
                clawAgents.put(agent.getAgent_id(), entry);
            }
            openClawClient.syncAgents(Map.of("agents", clawAgents));
            log.info("OpenClaw 에이전트 동기화: {}개", agents.size());
        } catch (OpenClawException e) {
            log.warn("OpenClaw 에이전트 동기화 실패 (graceful): {}", e.getMessage());
        } catch (Exception e) {
            log.error("OpenClaw 에이전트 동기화 오류", e);
        }
    }

    public void syncAll() {
        syncProviders();
        syncAgents();
    }

    private Map<String, Object> buildAuthProfile(AiLlmProvider p, String decryptedKey) {
        Map<String, Object> profile = new HashMap<>();
        switch (p.getName()) {
            case "anthropic", "openai", "google" -> {
                profile.put("provider", p.getName());
                profile.put("apiKey", decryptedKey);
            }
            case "deepseek" -> {
                profile.put("provider", "openai-compat");
                profile.put("apiKey", decryptedKey);
                profile.put("baseUrl", p.getEndpoint() != null ? p.getEndpoint() : "https://api.deepseek.com/v1");
            }
            case "ollama" -> {
                profile.put("provider", "ollama");
                profile.put("baseUrl", p.getEndpoint() != null ? p.getEndpoint() : "http://localhost:11434");
            }
            default -> {
                return null;
            }
        }
        return profile;
    }
}
