package com.storlead.system.util;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.storlead.framework.annotate.AnnotateEnumType;
import com.storlead.framework.annotate.OrgAutoMateAnnotate;
import com.storlead.system.pojo.entity.SysDictDetailEntity;
import com.storlead.system.pojo.entity.SysDictEntity;
import com.storlead.system.service.SysDictDetailService;
import com.storlead.system.service.SysDictService;
import com.storlead.user.pojo.entity.DeptEntity;
import com.storlead.user.pojo.entity.SubCompanyEntity;
import com.storlead.user.pojo.entity.UserEntity;
import com.storlead.user.service.IDepartService;
import com.storlead.user.service.ISubCompanyService;
import com.storlead.user.service.IUserService;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2024-05-21 16:51
 */
@Component
public class OrgAnnotateConvertUtils {

    @Resource
    private SysDictService dictService;

    @Resource
    private SysDictDetailService dictDetailService;

    @Resource
    private ISubCompanyService subCompanyService;

    @Resource
    private IDepartService departService;

    @Resource
    private IUserService userService;

    public void convertOrg(List<Object> targets) {
        List<OrgDefinition> definitions = getMetadata(targets.get(0));
        if (CollectionUtils.isEmpty(definitions)) return;

        List<OrgDefinition> subCompanyAnns = definitions.stream().filter(e ->e.getOrgAnnotate().annotateType().equals(AnnotateEnumType.SUB_COMPANY)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(subCompanyAnns)) {
            List<SubCompanyEntity> subCompanys = subCompanyService.list();
            Map<String,String> subCompanyMap = subCompanys.stream().collect(Collectors.toMap(e -> String.valueOf(e.getId()), SubCompanyEntity::getName));
            for (Object t : targets) {
                doConvertOrg(t, subCompanyAnns, subCompanyMap);
            }
        }
        List<OrgDefinition> deptAnns = definitions.stream().filter(e ->e.getOrgAnnotate().annotateType().equals(AnnotateEnumType.DEPT)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(deptAnns)) {
            List<DeptEntity> depts = departService.list();
            Map<String,String> deptMap = depts.stream().collect(Collectors.toMap(e -> String.valueOf(e.getId()), DeptEntity::getName));
            for (Object t : targets) {
                doConvertOrg(t, deptAnns, deptMap);
            }
        }
        List<OrgDefinition> userAnns = definitions.stream().filter(e ->e.getOrgAnnotate().annotateType().equals(AnnotateEnumType.USER)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(userAnns)) {
            List<UserEntity> users = userService.list();
            Map<String,String> userMap = users.stream().collect(Collectors.toMap(e -> String.valueOf(e.getId()), UserEntity::getRealName));
            for (Object t : targets) {
                doConvertOrg(t, userAnns, userMap);
            }
        }
    }


    @SneakyThrows
    public void doConvertOrg(Object target, List<OrgDefinition> definitions,
                              Map<String, String> dataMap) {

        for (OrgDefinition definition : definitions) {
            OrgAutoMateAnnotate annotation = definition.getOrgAnnotate();
            Field field = definition.getField();
            // 需要取值的字段
            String getFieldName = StrUtil.isNotBlank(annotation.valueField()) ? field.getName() : annotation.keyField();
            Field getField = FieldUtils.getField(target.getClass(), getFieldName, true);
            if (Objects.isNull(getField)) {
                continue;
            }
            // 需要赋值的字段
            String setFieldName = StrUtil.isNotBlank(annotation.valueField()) ? annotation.valueField() : field.getName();
            Field setField = FieldUtils.getField(target.getClass(), setFieldName, true);
            if (Objects.isNull(setField)) {
                continue;
            }
            if (annotation.multiple()) {
                String fieldValue = String.valueOf(FieldUtils.readField(target,getFieldName, true));
                if (StrUtil.isNotBlank(fieldValue)) {
                    String[] dictValues = fieldValue.split(",");
                    StringBuilder dictValue = new StringBuilder();
                    for (String value : dictValues) {
                        Map<String, String> dictKeyMap = StrUtil.isNotBlank(annotation.valueField()) ? dataMap : MapUtil.swapKeysAndValues(dataMap);
                        dictValue.append(dictKeyMap.get(value)).append(",");
                    }
                    /**
                     * 不需要最后一个逗号分隔符
                     */
                    if (StrUtil.isNotBlank(dictValue)) {
                        dictValue.deleteCharAt(dictValue.length() - 1);
                    }
                    FieldUtils.writeField(target,setFieldName, dictValue.toString(), true);
                }
            } else {
                 String dictValue = String.valueOf(FieldUtils.readField(target, getFieldName, true));
                Map<String, String> dictKeyMap = StrUtil.isNotBlank(annotation.valueField()) ? dataMap : MapUtil.swapKeysAndValues(dataMap);
                FieldUtils.writeField(target,setFieldName, dictKeyMap.get(dictValue), true);
            }
        }
    }

    @SneakyThrows
    private Map<String, Map<String, String>> getDictMap(List<String> dictCode) {
        QueryWrapper<SysDictEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(SysDictEntity::getCode,dictCode);
        List<SysDictEntity> dictList = dictService.list(wrapper);

        QueryWrapper<SysDictDetailEntity> detailWrapper = new QueryWrapper<>();
        List<Long> dIds = dictList.stream().map(SysDictEntity::getDictId).collect(Collectors.toList());
        detailWrapper.lambda().in(SysDictDetailEntity::getDictId,dIds);
        List<SysDictDetailEntity> detailList = dictDetailService.list(detailWrapper);

        Map<String, Map<String, String>> dictMap = new HashMap<>();
        for (SysDictEntity  dict : dictList) {
            dictMap.put(dict.getCode(), detailList.stream().filter(d -> d.getDictId().equals(dict.getDictId())).collect(Collectors.toMap(SysDictDetailEntity::getValue, SysDictDetailEntity::getLabel)));
        }
        return dictMap;
    }

    private static List<OrgDefinition> getMetadata(Object target) {
        List<OrgDefinition> definitions = new ArrayList<>();
        if (ClassUtils.isPrimitiveOrWrapper(target.getClass())
                || target instanceof Map || target instanceof String) {
            return definitions;
        }
        List<Field> fields = FieldUtils.getAllFieldsList(target.getClass());
        for (Field field : fields) {
            OrgAutoMateAnnotate orgAnnotate = AnnotationUtils.getAnnotation(field, OrgAutoMateAnnotate.class);
            if (orgAnnotate != null) {
                OrgDefinition definition = new OrgDefinition(orgAnnotate,field);
                definitions.add(definition);
            }
        }
        return definitions;
    }

    @Data
    public static class OrgDefinition {
        private OrgAutoMateAnnotate orgAnnotate;
        private Field field;

        //构造方法
        public OrgDefinition(OrgAutoMateAnnotate orgAnnotate,Field field) {
            this.orgAnnotate = orgAnnotate;
            this.field = field;
        }
    }
}
