package com.sino.mci.channel.wecom.sync;

import com.sino.mci.channel.wecom.support.WeComServiceFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatInfo;
import me.chanjar.weixin.cp.bean.external.WxCpUserExternalGroupChatList;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 企业微信通讯录与群聊真实同步客户端。
 *
 * <p>基于 {@link WxCpService} 调用企微开放接口，拉取企业内部成员、外部联系人及客户群。</p>
 */
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnProperty(name = "mci.wecom.sync.mock", havingValue = "false", matchIfMissing = true)
public class RealWeComSyncClient implements WeComSyncClient {

    private final WeComServiceFactory serviceFactory;

    @Override
    public List<WeComContact> syncEnterpriseContacts(WeComSyncConfig config) {
        WxCpService service = resolveService(config);
        if (service == null) {
            log.warn("[WeComSync] 无法创建 WxCpService，跳过企业通讯录同步");
            return Collections.emptyList();
        }

        List<WeComContact> contacts = new ArrayList<>();
        contacts.addAll(syncInternalUsers(service, config));
        contacts.addAll(syncExternalContacts(service, config));
        log.info("[WeComSync] 同步企业通讯录完成，共 {} 条", contacts.size());
        return contacts;
    }

    @Override
    public List<WeComContact> syncAccountContacts(WeComSyncConfig config, String userId) {
        WxCpService service = resolveService(config);
        if (service == null) {
            log.warn("[WeComSync] 无法创建 WxCpService，跳过账号客户同步");
            return Collections.emptyList();
        }

        List<WeComContact> contacts = syncExternalContactsForUser(service, config, userId);
        log.info("[WeComSync] 同步账号 {} 的客户完成，共 {} 条", userId, contacts.size());
        return contacts;
    }

    @Override
    public List<WeComConversation> syncAccountConversations(WeComSyncConfig config, String userId) {
        WxCpService service = resolveService(config);
        if (service == null) {
            log.warn("[WeComSync] 无法创建 WxCpService，跳过账号群聊同步");
            return Collections.emptyList();
        }

        List<WeComConversation> conversations = new ArrayList<>();
        try {
            String cursor = "";
            do {
                WxCpUserExternalGroupChatList result = service.getExternalContactService()
                        .listGroupChat(1000, cursor, 0, new String[]{userId});
                if (result == null || result.getGroupChatList() == null) {
                    break;
                }
                for (WxCpUserExternalGroupChatList.ChatStatus chat : result.getGroupChatList()) {
                    WeComConversation conversation = fetchGroupChatDetail(service, chat.getChatId());
                    if (conversation != null) {
                        conversations.add(conversation);
                    }
                }
                cursor = result.getNextCursor();
            } while (cursor != null && !cursor.isEmpty());
        } catch (WxErrorException e) {
            log.warn("[WeComSync] 拉取账号 {} 的客户群列表失败，可能应用缺少客户联系权限: {}", userId, e.getMessage());
        } catch (Exception e) {
            log.warn("[WeComSync] 拉取账号 {} 的客户群列表异常", userId, e);
        }
        log.info("[WeComSync] 同步账号 {} 的群聊完成，共 {} 条", userId, conversations.size());
        return conversations;
    }

    private WxCpService resolveService(WeComSyncConfig config) {
        if (config == null || config.getCorpId() == null || config.getAgentId() == null || config.getSecret() == null) {
            return null;
        }
        try {
            return serviceFactory.getOrCreateService(
                    config.getCorpId(), Integer.valueOf(config.getAgentId()), config.getSecret());
        } catch (Exception e) {
            log.warn("[WeComSync] 创建 WxCpService 失败", e);
            return null;
        }
    }

    private List<WeComContact> syncInternalUsers(WxCpService service, WeComSyncConfig config) {
        List<WeComContact> contacts = new ArrayList<>();
        try {
            List<WxCpDepart> departments = service.getDepartmentService().list(null);
            if (departments == null || departments.isEmpty()) {
                return contacts;
            }
            for (WxCpDepart dept : departments) {
                try {
                    List<WxCpUser> users = service.getUserService().listByDepartment(dept.getId(), true, 0);
                    if (users == null) {
                        continue;
                    }
                    for (WxCpUser user : users) {
                        contacts.add(WeComContact.builder()
                                .userId(user.getUserId())
                                .name(user.getName())
                                .mobile(user.getMobile())
                                .type(WeComContactType.INTERNAL)
                                .departmentIds(user.getDepartIds() == null
                                        ? Collections.emptyList()
                                        : Arrays.stream(user.getDepartIds()).collect(Collectors.toList()))
                                .build());
                    }
                } catch (WxErrorException e) {
                    log.warn("[WeComSync] 获取部门 {} 成员失败: {}", dept.getId(), e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            log.warn("[WeComSync] 拉取部门列表失败，可能应用缺少通讯录权限: {}", e.getMessage());
        } catch (Exception e) {
            log.warn("[WeComSync] 拉取内部成员异常", e);
        }
        return contacts;
    }

    private List<WeComContact> syncExternalContacts(WxCpService service, WeComSyncConfig config) {
        List<WeComContact> contacts = new ArrayList<>();
        try {
            List<String> followUsers = service.getExternalContactService().listFollowers();
            if (followUsers == null || followUsers.isEmpty()) {
                return contacts;
            }
            for (String userId : followUsers) {
                contacts.addAll(syncExternalContactsForUser(service, config, userId));
            }
        } catch (WxErrorException e) {
            log.warn("[WeComSync] 拉取客户联系成员失败，可能应用缺少客户联系权限: {}", e.getMessage());
        } catch (Exception e) {
            log.warn("[WeComSync] 拉取外部联系人异常", e);
        }
        return contacts;
    }

    private List<WeComContact> syncExternalContactsForUser(WxCpService service, WeComSyncConfig config, String userId) {
        List<WeComContact> contacts = new ArrayList<>();
        try {
            List<String> externalUserIds = service.getExternalContactService().listExternalContacts(userId);
            if (externalUserIds == null) {
                return contacts;
            }
            for (String externalUserId : externalUserIds) {
                try {
                    WxCpExternalContactInfo info = service.getExternalContactService()
                            .getContactDetail(externalUserId, null);
                    if (info == null || info.getExternalContact() == null) {
                        continue;
                    }
                    contacts.add(WeComContact.builder()
                            .userId(externalUserId)
                            .name(info.getExternalContact().getName())
                            .mobile(null)
                            .type(WeComContactType.EXTERNAL)
                            .departmentIds(Collections.emptyList())
                            .build());
                } catch (WxErrorException e) {
                    log.warn("[WeComSync] 获取外部联系人 {} 详情失败: {}", externalUserId, e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            log.warn("[WeComSync] 获取成员 {} 的客户列表失败: {}", userId, e.getMessage());
        }
        return contacts;
    }

    private WeComConversation fetchGroupChatDetail(WxCpService service, String chatId) {
        try {
            WxCpUserExternalGroupChatInfo detail = service.getExternalContactService().getGroupChat(chatId, 0);
            if (detail == null || detail.getGroupChat() == null) {
                return null;
            }
            WxCpUserExternalGroupChatInfo.GroupChat groupChat = detail.getGroupChat();
            List<WeComConversationMember> members = new ArrayList<>();
            if (groupChat.getMemberList() != null) {
                for (WxCpUserExternalGroupChatInfo.GroupMember member : groupChat.getMemberList()) {
                    members.add(WeComConversationMember.builder()
                            .userId(member.getUserId())
                            .name(resolveMemberName(service, member))
                            .type(member.getType())
                            .build());
                }
            }
            return WeComConversation.builder()
                    .chatId(groupChat.getChatId())
                    .chatName(groupChat.getName())
                    .ownerUserId(groupChat.getOwner())
                    .memberList(members)
                    .build();
        } catch (WxErrorException e) {
            log.warn("[WeComSync] 获取群聊 {} 详情失败: {}", chatId, e.getMessage());
            return null;
        } catch (Exception e) {
            log.warn("[WeComSync] 获取群聊 {} 详情异常", chatId, e);
            return null;
        }
    }

    private String resolveMemberName(WxCpService service, WxCpUserExternalGroupChatInfo.GroupMember member) {
        if (StringUtils.isNotBlank(member.getName())) {
            return member.getName();
        }
        String userId = member.getUserId();
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        // 外部联系人：通过客户详情接口补全名称
        if (userId.startsWith("wm")) {
            try {
                WxCpExternalContactInfo info = service.getExternalContactService().getContactDetail(userId, null);
                if (info != null && info.getExternalContact() != null
                        && StringUtils.isNotBlank(info.getExternalContact().getName())) {
                    return info.getExternalContact().getName();
                }
            } catch (WxErrorException e) {
                log.debug("[WeComSync] 获取外部联系人 {} 名称失败: {}", userId, e.getMessage());
            }
        }
        // 内部成员：通过通讯录接口补全名称
        try {
            WxCpUser user = service.getUserService().getById(userId);
            if (user != null && StringUtils.isNotBlank(user.getName())) {
                return user.getName();
            }
        } catch (WxErrorException e) {
            log.debug("[WeComSync] 获取内部成员 {} 名称失败: {}", userId, e.getMessage());
        }
        return userId;
    }
}
