package com.sino.mci.channel.wechat.personal;

import com.sino.mci.channel.common.dto.CallbackPayload;
import com.sino.mci.channel.common.dto.ChannelInitRequest;
import com.sino.mci.channel.common.dto.ChannelInitResult;
import com.sino.mci.channel.common.dto.SendMessageRequest;
import com.sino.mci.channel.common.dto.SendMessageResult;
import com.sino.mci.channel.common.model.ChannelType;
import com.sino.mci.channel.common.spi.ChannelAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestClientException;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class WechatPersonalChannelAdapter implements ChannelAdapter {

    private static final ParameterizedTypeReference<Map<String, Object>> MAP_TYPE =
            new ParameterizedTypeReference<>() {};

    private final WechatPersonalProperties properties;

    private RestClient restClient;

    public WechatPersonalChannelAdapter(WechatPersonalProperties properties) {
        this.properties = properties;
    }

    private RestClient restClient() {
        if (restClient == null) {
            restClient = RestClient.builder().baseUrl(properties.getBaseUrl()).build();
        }
        return restClient;
    }

    @Override
    public ChannelType getChannelType() {
        return ChannelType.WECHAT_PERSONAL;
    }

    @Override
    public ChannelInitResult initAccount(ChannelInitRequest request) {
        ChannelInitResult result = new ChannelInitResult();
        if (request == null || request.getConfig() == null) {
            result.setSuccess(false);
            result.setMessage("个人微信初始化失败：请求或配置为空");
            return result;
        }

        String accountId = getString(request.getConfig(), "account_id");
        if (isBlank(accountId)) {
            result.setSuccess(false);
            result.setMessage("个人微信初始化失败：缺少 account_id");
            return result;
        }

        String accountName = getString(request.getConfig(), "account_name");

        Map<String, Object> body = new HashMap<>();
        body.put("account_id", accountId);
        body.put("account_name", accountName);

        try {
            // Python 侧 login/start 会 get_or_create 账号，因此该调用同时完成注册校验并返回二维码
            Map<String, Object> response = post("/v1/wechat-personal/login/start", body);
            if (response == null) {
                result.setSuccess(false);
                result.setMessage("个人微信初始化失败：Python 服务返回为空");
                return result;
            }

            String qrCodeUrl = getString(response, "qr_code_url");
            if (isBlank(qrCodeUrl)) {
                result.setSuccess(false);
                result.setMessage("个人微信初始化失败：Python 服务未返回二维码");
                return result;
            }

            result.setSuccess(true);
            result.setAccountId(accountId);
            result.setAccountName(isBlank(accountName) ? accountId : accountName);
            result.setQrCodeUrl(qrCodeUrl);
            result.setMessage("个人微信账号初始化成功，请扫描二维码登录");
        } catch (RestClientException e) {
            result.setSuccess(false);
            result.setMessage("个人微信初始化失败：" + e.getMessage());
            log.warn("[WechatPersonal] 初始化账号失败", e);
        }
        return result;
    }

    @Override
    public SendMessageResult sendMessage(SendMessageRequest request) {
        SendMessageResult result = new SendMessageResult();
        if (request == null) {
            result.setSuccess(false);
            result.setMessage("发送请求为空");
            return result;
        }

        String accountId = resolveAccountId(request);
        if (isBlank(accountId)) {
            result.setSuccess(false);
            result.setMessage("个人微信发送失败：缺少 account_id");
            return result;
        }

        String conversationId = defaultString(request.getConversationId());
        if (isBlank(conversationId)) {
            result.setSuccess(false);
            result.setMessage("个人微信发送失败：缺少 conversation_id");
            return result;
        }

        String contentType = defaultString(request.getContentType()).toLowerCase();
        String recordId = getString(request.getExtra(), "record_id");
        String tenantCode = defaultString(getString(request.getExtra(), "tenant_code"));
        try {
            Map<String, Object> response;
            if ("image".equals(contentType)) {
                response = sendImage(accountId, conversationId, recordId, tenantCode, request.getContent());
            } else {
                response = sendText(accountId, conversationId, recordId, tenantCode, request.getContent());
            }

            if (response == null) {
                result.setSuccess(false);
                result.setMessage("个人微信发送失败：Python 服务返回为空");
                return result;
            }

            Boolean success = getBoolean(response, "success");
            Boolean accepted = getBoolean(response, "accepted");
            if (!Boolean.TRUE.equals(success) && !Boolean.TRUE.equals(accepted)) {
                result.setSuccess(false);
                result.setMessage("个人微信发送失败：" + getString(response, "error"));
                return result;
            }

            result.setSuccess(true);
            result.setChannelMessageId(getString(response, "message_id"));
        } catch (RestClientException e) {
            result.setSuccess(false);
            result.setMessage("个人微信发送失败：" + e.getMessage());
            log.warn("[WechatPersonal] 发送消息失败", e);
        }
        return result;
    }

    @Override
    public CallbackPayload parseCallback(String rawBody) {
        CallbackPayload payload = new CallbackPayload();
        payload.setChannelType(ChannelType.WECHAT_PERSONAL.name());
        payload.setRawBody(rawBody);
        return payload;
    }

    private Map<String, Object> sendText(String accountId, String conversationId, String recordId, String tenantCode, Map<String, Object> content) {
        String text = getString(content, "text");
        if (isBlank(text)) {
            throw new IllegalArgumentException("文本内容为空");
        }
        Map<String, Object> body = new HashMap<>();
        body.put("account_id", accountId);
        body.put("conversation_id", conversationId);
        body.put("text", text);
        body.put("record_id", recordId);
        body.put("tenant_code", tenantCode);
        return post("/v1/wechat-personal/send/text", body);
    }

    private Map<String, Object> sendImage(String accountId, String conversationId, String recordId, String tenantCode, Map<String, Object> content) {
        String imageUrl = getString(content, "image_url");
        if (isBlank(imageUrl)) {
            throw new IllegalArgumentException("图片地址为空");
        }
        Map<String, Object> body = new HashMap<>();
        body.put("account_id", accountId);
        body.put("conversation_id", conversationId);
        body.put("image_url", imageUrl);
        body.put("record_id", recordId);
        body.put("tenant_code", tenantCode);
        return post("/v1/wechat-personal/send/image", body);
    }

    private Map<String, Object> post(String uri, Map<String, Object> body) {
        return restClient().post()
                .uri(uri)
                .contentType(MediaType.APPLICATION_JSON)
                .body(body)
                .retrieve()
                .body(MAP_TYPE);
    }

    private String resolveAccountId(SendMessageRequest request) {
        String accountId = getString(request.getExtra(), "account_id");
        if (isNotBlank(accountId)) {
            return accountId;
        }
        return getString(request.getContent(), "account_id");
    }

    private String getString(Map<?, ?> map, String key) {
        if (map == null) {
            return null;
        }
        Object value = map.get(key);
        return value == null ? null : Objects.toString(value);
    }

    private Boolean getBoolean(Map<?, ?> map, String key) {
        if (map == null) {
            return null;
        }
        Object value = map.get(key);
        if (value instanceof Boolean b) {
            return b;
        }
        if (value instanceof String s) {
            return "true".equalsIgnoreCase(s);
        }
        return null;
    }

    private boolean isBlank(String value) {
        return value == null || value.isBlank();
    }

    private boolean isNotBlank(String value) {
        return !isBlank(value);
    }

    private String defaultString(String value) {
        return value == null ? "" : value;
    }
}
