package org.springblade.system.convert;

import org.apache.commons.lang3.StringUtils;
import org.mapstruct.*;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.DataStatusEnum;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.pojo.entity.User;
import org.springblade.system.pojo.entity.UserDept;
import org.springblade.system.pojo.enums.UserSex;
import org.springblade.system.pojo.enums.UserType;
import org.springblade.system.pojo.vo.UserListVO;
import org.springblade.thirdparty.mk.constant.MKConstant;
import org.springblade.thirdparty.mk.pojo.dto.MKAuxiliaryDeptDTO;
import org.springblade.thirdparty.mk.pojo.dto.MKPushPersonDTO;
import org.springblade.thirdparty.oa.constant.OAConvertConstant;
import org.springblade.thirdparty.oa.pojo.response.OAPersonResponse;
import org.springblade.thirdparty.oa.util.OAUtils;

import java.util.*;

/**
 * @author bfhuange
 * @date 2024/8/26
 */
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserConvert {

    List<UserListVO> entities2vos(List<User> list);

    default List<MKPushPersonDTO> entities2dtos(List<User> records, String defaultPassword) {
        if (CollectionUtil.isEmpty(records)) {
            return Collections.emptyList();
        }
        return records.stream()
                .map(user -> {
                    MKPushPersonDTO personDTO = entity2dto(user);
                    if (personDTO == null) {
                        return null;
                    }
                    if (CommonConstant.NO.equals(user.getIsPushMk())) {
                        // 未推送mk的才设置默认密码
                        personDTO.setFdPassword(defaultPassword);
                    }
                    return personDTO;
                }).toList();
    }

    @Mapping(source = "account", target = "fdId")
    @Mapping(source = "account", target = "fdLoginName")
    @Mapping(source = "name", target = "fdName")
    @Mapping(source = "phone", target = "fdMobileNo")
    @Mapping(source = "code", target = "fdNo")
    @Mapping(source = "sex", target = "fdSex", qualifiedByName = "fdSex")
    @Mapping(source = "status", target = "fdIsAvailable", qualifiedByName = "fdIsAvailable")
    @Mapping(source = "account", target = "fdSourceSystem", qualifiedByName = "fdSourceSystem")
    @Mapping(source = "deptCodes", target = "fdParent", qualifiedByName = "fdParent")
    @Mapping(source = "deptCodes", target = "fdAuxiliaryDept", qualifiedByName = "fdAuxiliaryDept")
    MKPushPersonDTO entity2dto(User entity);

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "status", ignore = true)
    @Mapping(target = "password", ignore = true)
    @Mapping(target = "birthday", ignore = true)
    @Mapping(target = "sex", ignore = true)
    @Mapping(source = "workcode", target = "code")
    @Mapping(source = "lastname", target = "name")
    @Mapping(source = "lastname", target = "realName")
    @Mapping(source = "mobile", target = "phone")
    @Mapping(source = "mobile", target = "account")
    @Mapping(source = "email", target = "email")
    User baseConvert(OAPersonResponse person);

    @Mapping(source = "subcompanyname", target = "companyName")
    @Mapping(source = "departmentname", target = "deptName")
    @Mapping(source = "id", target = "oaId")
    @Mapping(source = "loginid", target = "oaLoginId")
    UserDept userDeptConvert(OAPersonResponse person);

    /**
     *  oa人员转本系统用户
     * @param person
     * @param defaultPassword 默认密码
     * @return
     */
    default User person2user(OAPersonResponse person, String defaultPassword) {
        User user = baseConvert(person);

        // 密码
        user.setPassword(defaultPassword);
        // 性别
        user.setSex(UserSex.getCodeByName(person.getSex()));
        // 状态转换
        Integer status = getStatus(person);
        user.setStatus(status);
        // web平台
        user.setUserType(UserType.WEB.getCategory());
        user.setSyncTime(new Date());
        // 从oa同步的
        user.setIsOa(CommonConstant.YES);
        return user;
    }

    /**
     *  oa人员转本系统用户部门
     * @param person
     * @param userMap 所有用户手机号与id map
     * @return
     */
    default UserDept person2userDept(OAPersonResponse person, Map<String, Long> userMap) {
        UserDept userDept = userDeptConvert(person);
        // 公司编码添加前缀
        userDept.setCompanyCode(OAConvertConstant.COMPANY_OA_PREFIX + person.getSubcompanyid1());
        // 部门编码添加前缀
        userDept.setDeptCode(OAConvertConstant.DEPARTMENT_OA_PREFIX + person.getDepartmentid());
        // 状态转换
        Integer status = getStatus(person);
        userDept.setStatus(status);
        // 排序
        userDept.setSort(OAUtils.parseInt(person.getDsporder()));
        // 用户id
        userDept.setUserId(userMap.get(person.getMobile()));
        userDept.setSyncTime(new Date());
        return userDept;
    }

    /**
     *  转换状态
     * @param person
     * @return
     */
    private Integer getStatus(OAPersonResponse person) {
        // 过滤状态  0-试用   1-正式  2-临时  3-试用延期   4-解聘  5-离职   6-退休  7-无效
        return switch (person.getStatus()) {
            case "0", "1", "2", "3" -> DataStatusEnum.ENABLE.getCode();
            default -> DataStatusEnum.DISABLE.getCode();
        };
    }

    @Named("fdIsAvailable")
    default Boolean fdIsAvailable(Integer status) {
        return DataStatusEnum.ENABLE.getCode().equals(status);
    }

    @Named("fdSourceSystem")
    default String fdSourceSystem(String account) {
        return CommonConstant.SYSTEM_CODE;
    }

    @Named("fdSex")
    default String fdSex(Integer sex) {
        if (sex == null) {
            return null;
        }
        if (UserSex.MAN.getCode().equals(sex)) {
            return MKConstant.SEX_MAN;
        }
        if (UserSex.WOMAN.getCode().equals(sex)) {
            return MKConstant.SEX_WOMAN;
        }
        return MKConstant.SEX_UNKONW;
    }

    @Named("fdParent")
    default String fdParent(String deptCodes) {
        if (StringUtils.isBlank(deptCodes)) {
            return null;
        }
        // 第一个部门编码作为主部门id
        return Func.toStrList(deptCodes).stream()
                // 非外部组织编码
                .filter(deptCode -> !deptCode.startsWith(OAConvertConstant.COMPANY_EX_PREFIX) && !deptCode.startsWith(OAConvertConstant.DEPARTMENT_EX_PREFIX))
                .findFirst()
                .orElse(null);
    }

    @Named("fdAuxiliaryDept")
    default List<MKAuxiliaryDeptDTO> fdAuxiliaryDept(String deptCodes) {
        if (StringUtils.isBlank(deptCodes)) {
            return null;
        }
        List<String> deptCodeList = Func.toStrList(deptCodes).stream()
                // 非外部组织编码
                .filter(deptCode -> !deptCode.startsWith(OAConvertConstant.COMPANY_EX_PREFIX) && !deptCode.startsWith(OAConvertConstant.DEPARTMENT_EX_PREFIX))
                .toList();
        if (deptCodeList.size() <= 1) {
            return null;
        }
        deptCodeList = new ArrayList<>(deptCodeList);
        // 移除第一个部门编码，其他的作为辅部门
        deptCodeList.remove(0);
        return deptCodeList.stream()
                .map(deptCode -> {
                    MKAuxiliaryDeptDTO deptDTO = new MKAuxiliaryDeptDTO();
                    deptDTO.setFdId(deptCode);
                    return deptDTO;
                }).toList();
    }
}
