package com.cm.common.base;

import com.alibaba.fastjson.JSONObject;
import com.cm.common.component.SecurityComponent;
import com.cm.common.constants.ISystemConstant;
import com.cm.common.enums.RoleDataAuthorityEnum;
import com.cm.common.exception.AccessTokenException;
import com.cm.common.exception.SearchException;
import com.cm.common.pojo.bos.UserInfoBO;
import com.cm.common.pojo.dtos.ZTreeDTO;
import com.cm.common.token.app.AppTokenManager;
import com.cm.common.token.app.entity.AppTokenUser;
import com.cm.common.utils.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @ClassName: AbstractService
 * @Description: baseinfo service
 * @Author: wenc
 * @Date: 2018/9/27 下午3:49
 * @Version: 1.0
 **/
@Component
public abstract class AbstractService {

    protected static Logger LOG = LoggerFactory.getLogger(AbstractService.class);
    @Autowired
    protected SecurityComponent securityComponent;
    @Autowired
    private HttpSession httpSession;

    /**
     * 设置新增基础数据
     *
     * @param params
     */
    protected void setSaveInfo(Map<String, Object> params) {
        UserInfoBO userInfoBO = securityComponent.getCurrentUser();
        if (userInfoBO != null) {
            setSave(userInfoBO.getUserId(), params);
        } else {
            setSave("1", params);
        }
    }

    /**
     * token类型设置新增基础数据
     *
     * @param token
     * @param params
     */
    protected void setSaveInfo(String token, Map<String, Object> params) {
        AppTokenUser appTokenUser = AppTokenManager.getInstance().getToken(token).getAppTokenUser();
        setSave(appTokenUser.getId(), params);
    }

    /**
     * 设置新增基础信息
     *
     * @param params
     * @param userId
     */
    protected void setSaveInfoByUserId(Map<String, Object> params, String userId) {
        setSave(userId, params);
    }

    /**
     * 设置新增
     *
     * @param userId
     * @param params
     */
    private void setSave(String userId, Map<String, Object> params) {
        String currentDate = DateUtil.getTime();
        params.put("creator", userId);
        params.put("gmtCreate", currentDate);
        params.put("modifier", userId);
        params.put("gmtModified", currentDate);
        params.put("isDelete", 0);
    }

    /**
     * 设置修改基础数据
     *
     * @param params
     */
    protected void setUpdateInfo(Map<String, Object> params) {
        UserInfoBO userInfoBO = securityComponent.getCurrentUser();
        if (userInfoBO != null) {
            setUpdate(userInfoBO.getUserId(), params);
        } else {
            setUpdateInfo("1", params);
        }
    }

    /**
     * token类型设置修改基础数据
     *
     * @param token
     * @param params
     */
    protected void setUpdateInfo(String token, Map<String, Object> params) {
        AppTokenUser appTokenUser = AppTokenManager.getInstance().getToken(token).getAppTokenUser();
        setUpdate(appTokenUser.getId(), params);
    }

    /**
     * 设置更新基础信息
     *
     * @param params
     * @param userId
     */
    protected void setUpdateInfoByUserId(Map<String, Object> params, String userId) {
        setUpdate(userId, params);
    }

    /**
     * 设置修改
     *
     * @param userId
     * @param params
     */
    private void setUpdate(String userId, Map<String, Object> params) {
        String currentDate = DateUtil.getTime();
        params.put("modifier", userId);
        params.put("gmtModified", currentDate);
    }

    /**
     * 设置zTree内容
     *
     * @param zTreeDTO
     * @param subCount
     */
    protected void setZTreeInfo(ZTreeDTO zTreeDTO, Integer subCount) {
        zTreeDTO.setUrl("javascript:void(0);");
        if (null != subCount && 0 < subCount) {
            zTreeDTO.setIsParent(true);
        } else {
            zTreeDTO.setIsParent(false);
        }
    }

    /**
     * 获取新的code
     *
     * @param code
     * @param parentCode
     * @return
     */
    protected String getNewCode(String code, String parentCode) {
        // 最后的code长度
        int lastCodeLength = code.length();
        int lastNumber = Integer.parseInt(code.substring(lastCodeLength - 4, lastCodeLength)) + 1;
        code = String.format("%04d", lastNumber);
        if (!StringUtils.isEmpty(parentCode)) {
            code = parentCode + code;
        }
        return code;
    }

    /**
     * 获取session
     *
     * @return
     */
    protected HttpSession getHttpSession() {
        return httpSession;
    }

    /**
     * 获取HashMap
     *
     * @return
     */
    protected Map<String, Object> getHashMap(int initSize) {
        return new HashMap<>(initSize);
    }

    /**
     * 是否管理员
     *
     * @return
     */
    protected boolean isAdmin() {
        if (ISystemConstant.ADMIN.equalsIgnoreCase(securityComponent.getCurrentUsername())) {
            return true;
        }
        return false;
    }

    /**
     * 获取基础部门ID列表
     *
     * @return
     */
    protected List<String> listBaseDepartmentIds() {
        if (isAdmin()) {
            return null;
        }
        return securityComponent.getCurrentUser().getBaseDepartmentIds();
    }

    /**
     * 查询资源结果
     *
     * @param result       结果
     * @param errorMessage 异常提示
     * @throws AccessTokenException
     * @throws SearchException
     */
    protected void searchResourceResult(String result, String errorMessage) throws AccessTokenException, SearchException {
        if (result == null) {
            throw new AccessTokenException("认证失败");
        }
        if (result.isEmpty()) {
            throw new SearchException(errorMessage);
        }
    }

    /**
     * 更新结果
     *
     * @param result
     * @param errorMessage
     * @throws AccessTokenException
     * @throws SearchException
     */
    protected void updateResourceResult(String result, String errorMessage) throws AccessTokenException, SearchException {
        if (result == null) {
            throw new AccessTokenException("认证失败");
        }
        if (result.isEmpty()) {
            throw new SearchException(errorMessage);
        }
        JSONObject resultObj = JSONObject.parseObject(result);
        if (resultObj.getString("msg") != null) {
            throw new SearchException(resultObj.getString("msg"));
        }
    }

    /**
     * 简单Excel的Header
     *
     * @param names
     * @return
     */
    protected List<List<String>> simpleExcelHeader(String... names) {
        List<List<String>> listHeaders = new ArrayList<>();
        for (String name : names) {
            List<String> listHeader = new ArrayList<>();
            listHeader.add(name);
            listHeaders.add(listHeader);
        }
        return listHeaders;
    }

    /**
     * 设置数据权限信息
     *
     * @param params
     */
    protected void setDataAuthorityInfo(Map<String, Object> params) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        if (ISystemConstant.ADMIN.equals(securityComponent.getCurrentUser().getUserName())) {
            return;
        }
        String dataAuthority = currentUser.getDataAuthority();
        List<String> dataAuthorityUserIds = currentUser.getDataAuthorityUserIds();
        if (org.apache.commons.lang3.StringUtils.equals(RoleDataAuthorityEnum.ALL.getDataAuthorityType(), dataAuthority)) {
            return;
        } else if (org.apache.commons.lang3.StringUtils.equals(RoleDataAuthorityEnum.SELF.getDataAuthorityType(), dataAuthority)) {
            params.put(ISystemConstant.DATA_AUTHORITY, dataAuthority);
            params.put(ISystemConstant.DATA_CREATOR, currentUser.getUserId());
        } else if (org.apache.commons.lang3.StringUtils.equals(RoleDataAuthorityEnum.DEPARTMENT.getDataAuthorityType(), dataAuthority)
                || org.apache.commons.lang3.StringUtils.equals(RoleDataAuthorityEnum.CUSTOM.getDataAuthorityType(), dataAuthority)) {
            if (Objects.isNull(dataAuthorityUserIds) || dataAuthorityUserIds.isEmpty()) {
                LOG.debug("权限列表为空，设置查看个人");
                params.put(ISystemConstant.DATA_AUTHORITY, RoleDataAuthorityEnum.SELF.getDataAuthorityType());
                params.put(ISystemConstant.DATA_CREATOR, currentUser.getUserId());
            } else {
                params.put(ISystemConstant.DATA_AUTHORITY, dataAuthority);
                params.put(ISystemConstant.DATA_CREATORS, dataAuthorityUserIds);
            }
        }
    }

}
