package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.entity.auth.dto.*;
import com.engine.salary.entity.auth.param.*;
import com.engine.salary.entity.auth.po.AuthDataPO;
import com.engine.salary.entity.auth.po.AuthMemberPO;
import com.engine.salary.entity.auth.po.AuthRolePO;
import com.engine.salary.entity.auth.vo.Permission;
import com.engine.salary.enums.auth.DataLinkEnum;
import com.engine.salary.enums.auth.DataTargetTypeEnum;
import com.engine.salary.enums.auth.MemberTargetTypeEnum;
import com.engine.salary.mapper.auth.AuthMapper;
import com.engine.salary.service.auth.*;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import lombok.extern.slf4j.Slf4j;
import weaver.hrm.User;

import java.util.List;
import java.util.stream.Collectors;


@Slf4j
public class AuthWrapper extends Service {

    public AuthService getAuthService(User user) {
        return ServiceUtil.getService(AuthServiceImpl.class, user);
    }
    private AuthRoleService getAuthRoleService(User user) {
        return ServiceUtil.getService(AuthRoleServiceImpl.class, user);
    }

    private AuthMemberService getAuthMemberService(User user) {
        return ServiceUtil.getService(AuthMemberServiceImpl.class, user);
    }

    private AuthOptService getAuthOptService(User user) {
        return ServiceUtil.getService(AuthOptServiceImpl.class, user);
    }

    private AuthDataService getAuthDataService(User user) {
        return ServiceUtil.getService(AuthDataServiceImpl.class, user);
    }

    public PageInfo<AuthRoleDTO> roleList(AuthRoleListQueryParam param) {
        ValidUtil.doValidator(param);
        return getAuthRoleService(user).roleList(param);
    }

    public AuthRoleDTO getRole(Long id) {
        return getAuthRoleService(user).getRole(id);
    }

    public Long saveRole(AuthRoleSaveParam param) {
        ValidUtil.doValidator(param);
        return getAuthRoleService(user).saveRole(param);
    }


    public void deleteRole(List<Long> ids) {
        getAuthRoleService(user).deleteRole(ids);
    }

    public PageInfo<AuthMemberDTO> memberList(AuthMemberQueryParam param) {
        List<AuthMemberPO> authMemberPOS = getAuthMemberService(user).list(param.getRoleId());
        int total = authMemberPOS.size();
        authMemberPOS = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), authMemberPOS);
        List<AuthMemberDTO> dtos = authMemberPOS.stream()
                .map(po -> AuthMemberDTO.builder()
                        .id(po.getId())
                        .targetTypeName(MemberTargetTypeEnum.parseByValue(po.getTargetType()).getDefaultLabel())
                        .targetType(MemberTargetTypeEnum.parseByValue(po.getTargetType()))
                        .targetName(po.getTargetName())
                        .target(po.getTarget())
                        .build())
                .collect(Collectors.toList());
        PageInfo<AuthMemberDTO> authMemberDTOPageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), AuthMemberDTO.class);
        authMemberDTOPageInfo.setList(dtos);
        authMemberDTOPageInfo.setTotal(total);
        return authMemberDTOPageInfo;
    }


    public PageInfo<AuthRoleEmpDTO> memberDetail(AuthMemberQueryParam param) {
        List<AuthRoleEmpDTO> list = getAuthMemberService(user).listRoleEmp(param);
        return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), list, AuthRoleEmpDTO.class);
    }

    public void saveMember(List<AuthMemberSaveParam> param) {

        param.forEach(ValidUtil::modify);

        getAuthMemberService(user).save(param);
    }

    public void deleteMember(List<Long> ids) {
        getAuthMemberService(user).delete(ids);
    }

    public void syncMember(AuthSyncParam param) {
        getAuthMemberService(user).sync(param);
    }

    public AuthOptDTO optTree(Long roleId) {
        return getAuthOptService(user).optTree(roleId);
    }

    public void saveOpt(AuthOptSaveParam opt) {
        getAuthOptService(user).save(opt);
    }

    public PageInfo<AuthDataDTO> dataList(AuthDataQueryParam param) {
        List<AuthDataPO> list = getAuthDataService(user).list(param.getRoleId());
        int total = list.size();
        list = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), list);
        List<AuthDataDTO> dtos = list.stream().map(po -> AuthDataDTO.builder()
                        .id(po.getId())
                        .link(DataLinkEnum.parseByValue(po.getLink()))
                        .linkName(DataLinkEnum.parseByValue(po.getLink()).getDefaultLabel())
                        .targetTypeName(DataTargetTypeEnum.parseByValue(po.getTargetType()).getDefaultLabel())
                        .targetType(DataTargetTypeEnum.parseByValue(po.getTargetType()))
                        .targetName(po.getTargetName())
                        .target(po.getTarget())
                        .sortedIndex(po.getSortedIndex())
                        .build())
                .collect(Collectors.toList());

        PageInfo<AuthDataDTO> page = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), AuthDataDTO.class);
        page.setList(dtos);
        page.setTotal(total);
        return page;

    }


    public PageInfo<AuthRoleDataDTO> dataDetail(AuthDataQueryParam param) {
        List<AuthRoleDataDTO> authRoleDataDTOS = getAuthDataService(user).listRoleData(param);
        return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), authRoleDataDTOS, AuthRoleDataDTO.class);
    }

    public void saveData(List<AuthDataSaveParam> params) {
        params.forEach(ValidUtil::modify);

        getAuthDataService(user).save(params);
    }

    public void deleteData(List<Long> ids) {
        getAuthDataService(user).delete(ids);
    }

    public void syncData(AuthSyncParam param) {
        getAuthDataService(user).sync(param);
    }

    private AuthMapper getAuthMapper() {
        return MapperProxyFactory.getProxy(AuthMapper.class);
    }

    public Object auth(String page) {
        return getAuthMapper().getTaxEmpOptAuth((long) user.getUID(), page);
    }

    public Permission permission(String page) {
        return getAuthService(user).permission(page);
    }

    public AuthTreeDTO tree(AuthTreeQueryParam param) {
        return getAuthService(user).tree(param);
    }

    public String sync() {
        List<AuthRolePO> authRolePOS = getAuthRoleService(user).listAll();
        authRolePOS.forEach(po -> {
        AuthSyncParam param = AuthSyncParam.builder()
                .roleId(po.getId())
                .build();
            getAuthMemberService(user).sync(param);
            getAuthDataService(user).sync(param);
        });
        return "";
    }

}
