package com.zhongshu.card.server.core.service.dictionary;

import ch.qos.logback.core.joran.conditional.IfAction;
import com.github.microservice.auth.security.helper.AuthHelper;
import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
import com.github.microservice.net.ResultContent;
import com.zhongshu.card.client.model.dictionary.*;
import com.zhongshu.card.client.type.DictionaryType;
import com.zhongshu.card.client.type.DictionaryUpdateStatus;
import com.zhongshu.card.server.core.dao.dictionary.DictionaryDao;
import com.zhongshu.card.server.core.dao.dictionary.DictionaryItemDao;
import com.zhongshu.card.server.core.dataConfig.DictionaryInitConfig;
import com.zhongshu.card.server.core.domain.dictionary.Dictionary;
import com.zhongshu.card.server.core.domain.dictionary.DictionaryItem;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.model.dictionary.DItemChildrenResult;
import com.zhongshu.card.server.core.service.base.SuperService;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.KeysetScrollPosition;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DictionaryService extends SuperService {

    @Autowired
    private DictionaryDao dictionaryDao;

    @Autowired
    private DictionaryItemDao dictionaryItemDao;

    @Autowired
    DictionaryInitConfig dictionaryInitConfig;

    public ResultContent init(){
        return null;
    }

    /**
     * 添加字典
     * @param param
     * @return
     */
    public ResultContent addDictionary(AddDictionaryParam param){
        Dictionary byProjectIdAndKey = dictionaryDao.findTopByProjectIdAndKey(param.getProjectId(), param.getKey());
        if (byProjectIdAndKey != null){
            return ResultContent.buildFail("字典编码已存在");
        }

        if (StringUtils.isNotBlank(param.getId())){
            UpdateDictionaryParam updateParam = new UpdateDictionaryParam();
            BeanUtils.copyProperties(param, updateParam);
            return updateDictionary(updateParam);
        }

        Dictionary dictionary = new Dictionary();

        BeanUtils.copyProperties(param, dictionary);
        dictionary.setType(DictionaryType.Customize);
        dictionaryDao.save(dictionary);
        return ResultContent.buildSuccess();
    }

    /**
     * 编辑字典
     */
    public ResultContent updateDictionary(UpdateDictionaryParam param){
        Dictionary dictionary = dictionaryDao.findTopById(param.getId());
        if (dictionary == null){
            return ResultContent.buildFail("数据不存在");
        }

        DictionaryType type = dictionary.getType();
        if (DictionaryType.Standard.equals(type)){//如果为标准类型
            if (StringUtils.isNotBlank(param.getKey())){
                return ResultContent.buildFail("标准类型字典编码不允许修改");
            }
            if (param.isDisabled()){
                return ResultContent.buildFail("标准类型字典不允许禁用");
            }
        }

        Dictionary byProjectIdAndKey = dictionaryDao.findTopByProjectIdAndKey(dictionary.getProjectId(), param.getKey());
        if (byProjectIdAndKey != null && !byProjectIdAndKey.getId().equals(param.getId())){
            return ResultContent.buildFail("字典编码已存在");
        }
        com.zhongshu.card.server.core.util.BeanUtils.copyPropertiesWithoutNull(param, dictionary);
        dictionaryDao.save(dictionary);
        return ResultContent.buildSuccess();
    }

    /**
     * 删除字典
     */
    public ResultContent deleteDictionary(String id){
        Dictionary dictionary = dictionaryDao.findTopById(id);
        if (dictionary == null){
            return ResultContent.buildFail("数据不存在");
        }
        if (DictionaryType.Standard.equals(dictionary.getType())){
            return ResultContent.buildFail("标准字典不允许删除");
        }
        dictionaryDao.deleteById(id);
        //TODO 删除字典下的字典项
        return ResultContent.buildSuccess();
    }

    public Object page(Pageable pageable, DictionaryQueryParam param){
        String projectId = param.getProjectId();
        if (StringUtils.isBlank(projectId)){
            projectId = getCurrentProjectOid();
        }
        if (StringUtils.isBlank(projectId)){
            return ResultContent.buildFail("项目id不能为空");
        };

        Page<Dictionary> page = dictionaryDao.page(pageable, param.getProjectId(), param.getName(), param.getType());
        return ResultContent.buildContent(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    private DictionaryModel toModel(Dictionary dictionary){
        DictionaryModel dictionaryModel = new DictionaryModel();
        if (dictionary != null){
            BeanUtils.copyProperties(dictionary, dictionaryModel);
        }
        return dictionaryModel;
    }

    /**
     * 添加项
     */
    public ResultContent addItem(AddDictionaryItemParam param){
        Dictionary dictionary = dictionaryDao.findTopById(param.getDictionaryId());
        if (dictionary == null){
            return ResultContent.buildFail("字典不存在");
        }

        if (dictionary.getType().equals(DictionaryType.Standard)){
            return ResultContent.buildFail("标准字典不允许添加项");
        }

        DictionaryItem dictionaryItem = new DictionaryItem();
        BeanUtils.copyProperties(param, dictionaryItem, "id");
        dictionaryItem.setType(DictionaryType.Customize);
        dictionaryItem.setDictionary(dictionary);
        String id = new ObjectId().toHexString();
        dictionaryItem.setId(id);
        dictionaryItem.setIdString(id);
        dictionaryItem.setCreateTime(System.currentTimeMillis());
        dictionaryItemDao.save(dictionaryItem);
        return ResultContent.buildSuccess();
    }

    /**
     * 编辑项
     */
    public ResultContent updateItem(AddDictionaryItemParam param){
        if (StringUtils.isBlank(param.getId())){
            return ResultContent.buildFail("id不能为null");
        }
        DictionaryItem dictionaryItem = dictionaryItemDao.findTopById(param.getId());
        if (dictionaryItem == null){
            return ResultContent.buildFail("数据不存在");
        }

        if (dictionaryItem.getType().equals(DictionaryType.Standard)){//标准
            if (StringUtils.isNotBlank(param.getKey())){
                return ResultContent.buildFail("标准字典的项编码不允许修改");
            }
        }

        DictionaryItem updateItem = dictionaryItemDao.findTopByDictionary_IdAndKey(param.getDictionaryId(), param.getKey());
        if (updateItem != null && !updateItem.getId().equals(param.getId())){
            return ResultContent.buildFail("项编码已存在");
        }

        BeanUtils.copyProperties(param, dictionaryItem, "parentId", "dictionaryId");
        dictionaryItemDao.save(dictionaryItem);
        return ResultContent.buildSuccess();
    }

    /**
     * 删除项
     */
    public ResultContent deleteItem(String id){
        DictionaryItem dictionaryItem = dictionaryItemDao.findTopById(id);
        if (dictionaryItem == null){
            return ResultContent.buildFail("数据不存在");
        }
        if (DictionaryType.Standard.equals(dictionaryItem.getType())){
            return ResultContent.buildFail("标准字典的项不允许删除");
        }
        dictionaryItemDao.deleteById(id);
        return ResultContent.buildSuccess();
    }

    public Object pageItem(Pageable pageable, DictionaryItemQueryParam param){
        Page<DictionaryItem> page = dictionaryItemDao.page(pageable, param.getDictionaryId(), param.getName(), param.getParentId());
        Page<DictionaryItemModel> pageModel = PageEntityUtil.concurrent2PageModel(page, it -> {
            return toItemModel(it);
        });

        List<DictionaryItemModel> dItemChildrenResults = dictionaryItemDao.deepAggregate(param.getDictionaryId(), pageModel.getContent().stream().map(DictionaryItemModel::getKey).toList());
        List<DictionaryItemModel> ret = new ArrayList<>();
        dItemChildrenResults.forEach(it->{
            if (it.getChildren()!=null && it.getChildren().size() > 0){
                ret.addAll(it.getChildren());
            }
            it.setChildren(new ArrayList<>());
            ret.add(it);
        });

        List<DictionaryItemModel> modelList = buildTree(ret, null);
        return ResultContent.buildContent(PageEntityUtil.buildPage(modelList, pageable, page.getTotalElements()));
    }

    public static DictionaryItemModel buildChildren(List<DictionaryItemModel> allItems, String rootId) {
        // 使用一个Map来根据idString查找节点
        Map<String, DictionaryItemModel> itemMap = new HashMap<>();
        for (DictionaryItemModel item : allItems) {
            itemMap.put(item.getId(), item);
        }

        // 获取根节点
        DictionaryItemModel root = itemMap.get(rootId);
        if (root != null) {
            // 从根节点开始构建树
            buildSubTree(itemMap, root);
        }
        return root;
    }
    // 递归构建子树
    private static void buildSubTree(Map<String, DictionaryItemModel> itemMap, DictionaryItemModel parent) {
        // 遍历所有节点，查找当前parent的子节点
        for (DictionaryItemModel item : itemMap.values()) {
            if (item.getParentId() != null && item.getParentId().equals(parent.getId())) {
                // 找到子节点，添加到父节点的children列表中
                parent.addChild(item);
                // 递归处理子节点
                buildSubTree(itemMap, item);
            }
        }
    }

    private DictionaryItemModel toItemModel(DictionaryItem dictionaryItem){
        DictionaryItemModel dictionaryItemModel = new DictionaryItemModel();
        if (dictionaryItem != null){
            BeanUtils.copyProperties(dictionaryItem, dictionaryItemModel);
            dictionaryItemModel.setDictionaryId(dictionaryItem.getDictionary().getId());
        }
        return dictionaryItemModel;
    }

    /**
     * 根据字典编码获取字典
     * @param param
     * @return
     */
    public ResultContent listDictionary(ListDictionaryParam param){

        String projectId = param.getProjectId();
        if (StringUtils.isBlank(projectId)){
            projectId = getCurrentProjectOid();
        }
        if (StringUtils.isBlank(projectId)){
            return ResultContent.buildFail("项目id不能为空");
        };

        if (param.getKeys()==null || param.getKeys().isEmpty()){
            return ResultContent.buildFail("字典编码不能为null或空");
        }

        List<Dictionary> dictionaryList = dictionaryDao.findTopByProjectIdAndKeyIn(projectId, param.getKeys());
        return ResultContent.buildContent(dictionaryList.stream().map(this::toModel).toList());
    }

//    public ResultContent listItem(String projectId,String dictionary, String key){
//        dictionaryItemDao.findTopByDictionary_IdAndKeyIn()
//    }

    /**
     * 根据项编码获取项
     * @param param
     * @return
     */
    public ResultContent listItem(ListDictionaryParam param){

        if (StringUtils.isBlank(param.getDictionaryKey())){
            return ResultContent.buildFail("字典编码不能为空");
        }


        Dictionary dictionary = dictionaryDao.findTopByProjectIdAndKey(param.getProjectId(), param.getDictionaryKey());
        if (dictionary == null){
            return ResultContent.buildFail("字典不存在");
        }

        List<DictionaryItem> dictionaryItemList = new ArrayList<>();

        if (param.getKeys()==null || param.getKeys().isEmpty()){
            dictionaryItemList = dictionaryItemDao.findByDictionary_Id(dictionary.getId());
        }else {
            dictionaryItemList = dictionaryItemDao.findTopByDictionary_IdAndKeyIn(dictionary.getId(), param.getKeys());
        }
        return ResultContent.buildContent(dictionaryItemList.stream().map(this::toItemModel).toList());
    }

    public Object deepTreeItem(String projectId, String dictionaryKey, String dictionaryId){
        if (StringUtils.isBlank(dictionaryKey) && StringUtils.isBlank(dictionaryId)){
            return ResultContent.buildFail("字典编码和字典id不能为空");
        }

        Dictionary dictionary = null;

        if (StringUtils.isNotBlank(dictionaryId)){
            dictionary = dictionaryDao.findTopById(dictionaryId);
        }else if (StringUtils.isNotBlank(dictionaryKey)){
            dictionary = dictionaryDao.findTopByProjectIdAndKey(projectId, dictionaryKey);
        }

        if (dictionary == null){
            return ResultContent.buildFail("字典不存在");
        }
        if (dictionary.isDisabled()){
            return ResultContent.buildFail("字典已被禁用");
        }

        List<DictionaryItem> list = dictionaryItemDao.findByDictionary_Id(dictionary.getId());
        List<DictionaryItemModel> modelList = list.stream().map(this::toItemModel).toList();

        return ResultContent.buildContent(buildTree(modelList, null));
    }

    private List<DictionaryItemModel> buildTree(List<DictionaryItemModel> list, String parentId){
        Map<String, DictionaryItemModel> itemMap = new HashMap<>();
        itemMap = list.stream().collect(Collectors.toMap(DictionaryItemModel::getId, it->it));

        List<DictionaryItemModel> rootItems = new ArrayList<>();

//        for (DictionaryItemModel item : list) {
//            if (item.getParentId() == null || item.getParentId().isEmpty()) {
//                // 没有父节点的项是根节点
//                rootItems.add(item);
//            } else {
//                // 将子节点添加到父节点的 children 中
//                DictionaryItemModel parentItem = itemMap.get(item.getParentId());
//                if (parentItem != null) {
//                    parentItem.addChild(item);
//                }
//            }
//        }

        if (StringUtils.isNotBlank(parentId)){
            for (DictionaryItemModel item : list) {
                if (item.getId().equals(parentId)) {
                    // 没有父节点的项是根节点
                    rootItems.add(item);
                } else {
                    // 将子节点添加到父节点的 children 中
                    DictionaryItemModel parentItem = itemMap.get(item.getParentId());
                    if (parentItem != null) {
                        parentItem.addChild(item);
                    }
                }
            }
        }else {
            for (DictionaryItemModel item : list) {
                if (item.getParentId() == null || item.getParentId().isEmpty()) {
                    // 没有父节点的项是根节点
                    rootItems.add(item);
                } else {
                    // 将子节点添加到父节点的 children 中
                    DictionaryItemModel parentItem = itemMap.get(item.getParentId());
                    if (parentItem != null) {
                        parentItem.addChild(item);
                    }
                }
            }
        }
        return rootItems;
    }

    /**
     * 更新检查
     */
    public ResultContent<DictionaryUpdateStatus> updateCheck(String projectId){
        if (StringUtils.isBlank(projectId)){
            projectId = getCurrentProjectOid();
        }

        if (StringUtils.isBlank(projectId)){
            return ResultContent.buildFail("项目id不能未空");
        }
        return ResultContent.buildContent(getUpdateStatus(projectId));
    }


    public DictionaryUpdateStatus getUpdateStatus(String projectId){
        List<DictionaryInitConfig.Dictionary> initDicList = dictionaryInitConfig.getDictionaryList();
        List<String> initDictKeys = new ArrayList<>();
        List<String> initItemKeys = new ArrayList<>();
        getConfigKey(initDicList, initDictKeys, initItemKeys);

        List<Dictionary> dic = dictionaryDao.findByProjectId(projectId);
        if (dic.isEmpty()){//未初始化
            return DictionaryUpdateStatus.NoInit;
        }
        List<String> dictKeys = new ArrayList<>(dic.stream().map(Dictionary::getKey).toList());

        List<DictionaryItem> item = dictionaryItemDao.findByDictionary_IdIn(dic.stream().map(SuperEntity::getId).toList());
        List<String> itemKeys = item.stream().map(DictionaryItem::getKey).toList();

        if (initDictKeys.size() != dictKeys.size() || initItemKeys != itemKeys){//需要更新
            return DictionaryUpdateStatus.Update;
        }
        //无需更新
        return DictionaryUpdateStatus.LastVersion;
    }

    private void getConfigKey(List<DictionaryInitConfig.Dictionary> dictionaryList, List<String> dictKeys, List<String> itemKeys){

        for (DictionaryInitConfig.Dictionary dictionary : dictionaryList) {
            dictKeys.add(dictionary.getKey());
            if (dictionary.getItem() != null && !dictionary.getItem().isEmpty()){
                getConfigItemKey(dictionary.getItem(), itemKeys);
            }
        }
    }

    private void getConfigItemKey(List<DictionaryInitConfig.Dictionary> dictionaryList, List<String> keys){
        for (DictionaryInitConfig.Dictionary dictionary : dictionaryList) {
            keys.add(dictionary.getKey());
            if (dictionary.getItem() != null && !dictionary.getItem().isEmpty()){
                getConfigItemKey(dictionary.getItem(), keys);
            }
        }
    }

    /**
     * 更新标签字典初始化数据
     * @return
     */
    public ResultContent updateInit(String projectId, boolean coverName, boolean coverCustomize){
        DictionaryUpdateStatus updateStatus = getUpdateStatus(projectId);

        if (updateStatus.equals(DictionaryUpdateStatus.LastVersion)){
            return ResultContent.buildFail("已是最新版本，无需修复或更新");
        }
        //TODO 更新至最新版本

        List<DictionaryInitConfig.Dictionary> dictionaryList = dictionaryInitConfig.getDictionaryList();
        if (dictionaryList == null || dictionaryList.isEmpty()) {
            return ResultContent.buildFail("初始化数据不存在");
        }

        List<DictionaryType> typeList = new ArrayList<>(List.of(DictionaryType.Standard));

        if (coverCustomize){
            typeList.add(DictionaryType.Customize);
        }

        updateInitDictionary(projectId, dictionaryList, coverName, typeList);

        List<String> initDictKeys = new ArrayList<>();
        List<String> initItemKeys = new ArrayList<>();

        getConfigKey(dictionaryList, initDictKeys, initItemKeys);

        dictionaryDao.deleteByProjectIdAndKeyNotInAndTypeIn(projectId, initDictKeys, typeList);

        return ResultContent.buildSuccess();
    }


    public void updateInitDictionary(String projectId, List<DictionaryInitConfig.Dictionary> dictionaryList, boolean coverName, List<DictionaryType> typeList) {
        for(DictionaryInitConfig.Dictionary dict : dictionaryList){
            Dictionary dictionary = syncDictionary(projectId, dict, coverName);
            if (dict.getItem() != null) {
                List<String> itemKeys = dict.getItem().stream().map(DictionaryInitConfig.Dictionary::getKey).toList();
                dictionaryItemDao.deleteByDictionary_IdAndKeyNotInAndTypeIn(dictionary.getId(), itemKeys, typeList);
                for (DictionaryInitConfig.Dictionary item : dict.getItem()){
                    syncDictionaryItem(item, null, dictionary, coverName);
                }
            }
        }
    }

    private Dictionary syncDictionary(String projectId, DictionaryInitConfig.Dictionary dict, boolean coverName) {
        Dictionary dictionary = dictionaryDao.findTopByProjectIdAndKey(projectId, dict.getKey());
        if (dictionary == null) {
            dictionary = new Dictionary();
            BeanUtils.copyProperties(dict, dictionary);
            dictionary.setProjectId(projectId);
            dictionary.setType(DictionaryType.Standard);
            dictionary.setDisabled(false);
            dictionary.setId(new ObjectId().toHexString());
            dictionaryDao.save(dictionary);
        }else if (coverName){
            dictionary.setName(dict.getName());
            dictionary.setDescription(dict.getDescription());
            dictionaryDao.save(dictionary);
        }
        return dictionary;
    }

    private void syncDictionaryItem(DictionaryInitConfig.Dictionary dict, DictionaryItem parent, Dictionary dictionary, boolean coverName) {
        DictionaryItem item = dictionaryItemDao.findTopByDictionary_IdAndKey(dictionary.getId(), dict.getKey());

        if (item == null) {
            item = new DictionaryItem();
            BeanUtils.copyProperties(dict, item);
            if (parent != null) {
                item.setParentId(parent.getId());
            }
            item.setDictionary(dictionary);
            item.setType(DictionaryType.Standard);
            String id = new ObjectId().toHexString();
            item.setId(id);
            item.setIdString(id);
            item.setCreateTime(System.currentTimeMillis());
            item.setDisable(false);
            dictionaryItemDao.save(item);
        }else if (coverName){
            item.setName(dict.getName());
            item.setDescription(dict.getDescription());

        }

        if (dict.getItem() !=null && !dict.getItem().isEmpty()){
            for (DictionaryInitConfig.Dictionary children: dict.getItem()){
                syncDictionaryItem(children, item, dictionary, coverName);
            }
        }
    }

//    /**
//     * 字典项向下查询
//     */
//    public Object deepListItem(DeepQueryParam queryParam){
//
//        List<DeepQueryParam.KeyFilter> keyFilters = queryParam.getKeyFilters();
//
//        keyFilters.stream().map(keyFilter -> {
//           Dictionary dictionary = dictionaryDao.findTopByProjectIdAndKey(queryParam.getProjectId(), keyFilter.getDictionaryKey());
//
//           if (queryParam.isDeep() && !keyFilter.getKeys().isEmpty()){
//               List<DItemChildrenResult> itemList = dictionaryItemDao.deepAggregate(dictionary.getId(), keyFilter.getKeys());
//           }
//
//       }).toList();
//
//        Dictionary dictionary = dictionaryDao.findTopByProjectIdAndKey(projectId, dictionaryKey);
//
//        dictionaryItemDao.f
//    }


}
