package com.sino.mci.channel.service;

import com.sino.mci.channel.entity.ChannelAccount;
import com.sino.mci.channel.entity.ChannelSubject;
import com.sino.mci.channel.entity.Conversation;
import com.sino.mci.channel.entity.SyncTask;
import com.sino.mci.channel.repository.ChannelAccountMapper;
import com.sino.mci.channel.repository.ChannelSubjectMapper;
import com.sino.mci.channel.wecom.sync.WeComContact;
import com.sino.mci.channel.wecom.sync.WeComConversation;
import com.sino.mci.channel.wecom.sync.WeComSyncClient;
import com.sino.mci.channel.wecom.sync.WeComSyncConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class SyncTaskExecutor {

    private final SyncTaskService syncTaskService;
    private final ChannelAccountMapper accountMapper;
    private final ChannelSubjectMapper subjectMapper;
    private final SyncDataPersister syncDataPersister;
    private final WeComSyncClient weComSyncClient;

    @Async("syncTaskPool")
    public void executeEnterpriseContactsSync(Long taskId) {
        SyncTask task = syncTaskService.getTask(taskId, null);
        if (task == null) {
            return;
        }
        syncTaskService.markRunning(taskId);
        try {
            ChannelSubject subject = subjectMapper.selectById(task.getTargetId());
            if (subject == null) {
                throw new RuntimeException("渠道主体不存在");
            }
            WeComSyncConfig config = WeComSyncConfig.builder()
                    .corpId(subject.getCorpId())
                    .agentId(subject.getAgentId())
                    .secret(subject.getAgentSecret())
                    .build();
            List<WeComContact> contacts = weComSyncClient.syncEnterpriseContacts(config);
            for (WeComContact contact : contacts) {
                syncDataPersister.upsertContact(subject.getTenantCode(), subject.getId(), contact);
            }
            syncTaskService.markSuccess(taskId, contacts.size());
        } catch (Exception e) {
            log.error("[SyncTask] 企业通讯录同步失败 taskId={}", taskId, e);
            syncTaskService.markFailed(taskId, e.getMessage());
        }
    }

    @Async("syncTaskPool")
    public void executeAccountContactsSync(Long taskId) {
        SyncTask task = syncTaskService.getTask(taskId, null);
        if (task == null) {
            return;
        }
        syncTaskService.markRunning(taskId);
        try {
            ChannelAccount account = accountMapper.selectById(task.getTargetId());
            if (account == null) {
                throw new RuntimeException("渠道账号不存在");
            }
            ChannelSubject subject = subjectMapper.selectById(account.getSubjectId());
            if (subject == null) {
                throw new RuntimeException("渠道主体不存在");
            }
            WeComSyncConfig config = WeComSyncConfig.builder()
                    .corpId(subject.getCorpId())
                    .agentId(subject.getAgentId())
                    .secret(subject.getAgentSecret())
                    .build();
            List<WeComContact> contacts = weComSyncClient.syncAccountContacts(config, account.getAccountId());
            for (WeComContact contact : contacts) {
                syncDataPersister.upsertContact(account.getTenantCode(), account.getSubjectId(), contact);
            }
            syncTaskService.markSuccess(taskId, contacts.size());
        } catch (Exception e) {
            log.error("[SyncTask] 账号客户同步失败 taskId={}", taskId, e);
            syncTaskService.markFailed(taskId, e.getMessage());
        }
    }

    @Async("syncTaskPool")
    public void executeAccountConversationsSync(Long taskId) {
        SyncTask task = syncTaskService.getTask(taskId, null);
        if (task == null) {
            return;
        }
        syncTaskService.markRunning(taskId);
        try {
            ChannelAccount account = accountMapper.selectById(task.getTargetId());
            if (account == null) {
                throw new RuntimeException("渠道账号不存在");
            }
            ChannelSubject subject = subjectMapper.selectById(account.getSubjectId());
            if (subject == null) {
                throw new RuntimeException("渠道主体不存在");
            }
            WeComSyncConfig config = WeComSyncConfig.builder()
                    .corpId(subject.getCorpId())
                    .agentId(subject.getAgentId())
                    .secret(subject.getAgentSecret())
                    .build();
            List<WeComConversation> conversations = weComSyncClient.syncAccountConversations(config, account.getAccountId());
            for (WeComConversation conversation : conversations) {
                Conversation saved = syncDataPersister.upsertConversation(account, subject.getId(), conversation);
                syncDataPersister.refreshParticipants(account.getTenantCode(), account.getSubjectId(), saved, conversation);
                syncDataPersister.bindAccountAsDefault(account.getId(), saved.getId());
            }
            syncTaskService.markSuccess(taskId, conversations.size());
        } catch (Exception e) {
            log.error("[SyncTask] 账号群聊同步失败 taskId={}", taskId, e);
            syncTaskService.markFailed(taskId, e.getMessage());
        }
    }
}
