package com.fs.app.controller;

import com.fs.app.annotation.Login;
import com.fs.common.core.domain.R;
import com.fs.qw.domain.QwExternalContact;
import com.fs.qw.param.ImFsUserRemarkTagsParam;
import com.fs.qw.service.IQwExternalContactService;
import com.fs.qw.service.IQwTagService;
import com.fs.qw.vo.ImFsUserRemarkTagsVO;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * IM：按 fs_user 批量查企微外部联系人备注、标签（
 */
@Api("IM-企微客户")
@Slf4j
@RestController
@RequestMapping("/app/im/qwExternalContact")
public class ImQwExternalContactController extends AppBaseController {
    private static final Gson GSON = new Gson();
    private static final Pattern ID_PATTERN = Pattern.compile("^[Uu]?(\\d+)$");

    @Autowired
    private IQwExternalContactService qwExternalContactService;
    @Autowired
    private IQwTagService iQwTagService;
    @ApiOperation("批量查询企微备注与标签")
    @Login
    @PostMapping("/remarkTagsByFsUserIds")
    public R remarkTagsByFsUserIds(@RequestBody ImFsUserRemarkTagsParam param) {
        if (param == null || CollectionUtils.isEmpty(param.getUserIds())) {
            return R.ok().put("data", Collections.emptyList());
        }
        List<Long> requested = normalizeFsUserIds(param.getUserIds());
        if (CollectionUtils.isEmpty(requested)) {
            return R.ok().put("data", Collections.emptyList());
        }

        List<QwExternalContact> contacts = qwExternalContactService.selectExternalByFsUserIds(requested);
        Map<Long, QwExternalContact> bestByFsUser = pickBestExternalContactByFsUser(contacts);
        Map<String, List<String>> parsedTagIdCache = new HashMap<>();
        Map<String, String> tagNameMap = buildTagNameMap(bestByFsUser.values(), parsedTagIdCache);

        List<ImFsUserRemarkTagsVO> rows = new ArrayList<>(requested.size());
        for (Long uid : requested) {
            ImFsUserRemarkTagsVO row = new ImFsUserRemarkTagsVO();
            row.setUserId(uid);
            QwExternalContact c = bestByFsUser.get(uid);
            if (c != null) {
                row.setRemark(c.getRemark());
                row.setTagNames(resolveTagNamesLikeList(c.getTagIds(), parsedTagIdCache, tagNameMap));
            } else {
                row.setTagNames(Collections.emptyList());
            }
            rows.add(row);
        }
        return R.ok().put("data", rows);
    }

    private static Map<Long, QwExternalContact> pickBestExternalContactByFsUser(List<QwExternalContact> contacts) {
        Map<Long, QwExternalContact> out = new HashMap<>();
        if (CollectionUtils.isEmpty(contacts)) {
            return out;
        }
        for (QwExternalContact current : contacts) {
            if (current == null || current.getFsUserId() == null) {
                continue;
            }
            QwExternalContact best = out.get(current.getFsUserId());
            if (best == null || isBetter(current, best)) {
                out.put(current.getFsUserId(), current);
            }
        }
        return out;
    }

    private static boolean isBetter(QwExternalContact current, QwExternalContact best) {
        boolean currentActive = Integer.valueOf(0).equals(current.getStatus());
        boolean bestActive = Integer.valueOf(0).equals(best.getStatus());
        if (currentActive != bestActive) {
            return currentActive;
        }
        Long currentId = current.getId();
        Long bestId = best.getId();
        if (currentId == null) {
            return false;
        }
        if (bestId == null) {
            return true;
        }
        return currentId > bestId;
    }

    private Map<String, String> buildTagNameMap(Iterable<QwExternalContact> contacts, Map<String, List<String>> parsedTagIdCache) {
        LinkedHashSet<String> allTagIds = new LinkedHashSet<>();
        for (QwExternalContact contact : contacts) {
            allTagIds.addAll(parseTagIds(contact.getTagIds(), parsedTagIdCache));
        }
        if (allTagIds.isEmpty()) {
            return Collections.emptyMap();
        }
        return iQwTagService.selectTagNameMapByTagIds(new ArrayList<>(allTagIds));
    }

    private List<String> resolveTagNamesLikeList(String tagIds, Map<String, List<String>> parsedTagIdCache, Map<String, String> tagNameMap) {
        List<String> ids = parseTagIds(tagIds, parsedTagIdCache);
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<String> names = new ArrayList<>();
        for (String id : ids) {
            String name = tagNameMap.get(id);
            if (name != null) {
                names.add(name);
            }
        }
        return names;
    }

    private List<String> parseTagIds(String tagIds, Map<String, List<String>> parsedTagIdCache) {
        if (tagIds == null || Objects.equals(tagIds, "[]")) {
            return Collections.emptyList();
        }
        if (parsedTagIdCache.containsKey(tagIds)) {
            return parsedTagIdCache.get(tagIds);
        }
        List<String> ids;
        try {
            ids = GSON.fromJson(
                    tagIds,
                    new TypeToken<List<String>>() {
                    }.getType());
        } catch (Exception ex) {
            log.warn("IM标签解析失败, tagIds={}", tagIds, ex);
            parsedTagIdCache.put(tagIds, Collections.emptyList());
            return Collections.emptyList();
        }
        if (CollectionUtils.isEmpty(ids)) {
            parsedTagIdCache.put(tagIds, Collections.emptyList());
            return Collections.emptyList();
        }
        parsedTagIdCache.put(tagIds, ids);
        return ids;
    }

    private List<Long> normalizeFsUserIds(List<String> rawUserIds) {
        List<Long> normalized = new ArrayList<>();
        for (String raw : rawUserIds) {
            if (raw == null) {
                continue;
            }
            String trimmed = raw.trim();
            if (trimmed.isEmpty()) {
                continue;
            }
            Matcher matcher = ID_PATTERN.matcher(trimmed);
            if (!matcher.matches()) {
                log.warn("IM userId格式不支持, userId={}", raw);
                continue;
            }
            try {
                normalized.add(Long.parseLong(matcher.group(1)));
            } catch (NumberFormatException ex) {
                log.warn("IM userId转换失败, userId={}", raw, ex);
            }
        }
        return normalized.stream().distinct().collect(Collectors.toList());
    }
}
