package com.bonus.canteen.core.auth.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.allocation.api.AllocCanteenApi;
import com.bonus.canteen.core.allocation.canteen.vo.AllocAreaVO;
import com.bonus.canteen.core.allocation.canteen.vo.AllocCanteenTreeVO;
import com.bonus.canteen.core.allocation.canteen.vo.AllocCanteenVO;
import com.bonus.canteen.core.allocation.canteen.vo.AllocStallVO;
import com.bonus.canteen.core.auth.enums.DataTreeTypeEnum;
import com.bonus.canteen.core.auth.role.mapper.MgrRoleAreaMapper;
import com.bonus.canteen.core.auth.role.mapper.MgrRoleCanteenMapper;
import com.bonus.canteen.core.common.utils.TenantContextHolder;
import com.bonus.canteen.core.merchant.api.MercMerchantApi;
import com.bonus.canteen.core.merchant.entity.MercMerchant;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.canteen.core.auth.enums.RoleCodeV2Enum;
import com.bonus.canteen.core.auth.po.MgrUserAuthPO;
import com.bonus.canteen.core.auth.role.MgrRoleTypeV2Enum;
import com.bonus.canteen.core.auth.role.mapper.MgrRoleOrgMapper;
import com.bonus.canteen.core.customer.dto.CustOrgTreeDTO;
import com.bonus.canteen.core.customer.utils.SecureManager;
import com.bonus.common.houqin.i18n.I18n;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class MgrAuthApi {

   private MgrRoleOrgMapper mgrRoleOrgMapper;

   @Autowired
   private MgrRoleCanteenMapper mgrRoleCanteenMapper;
   @Resource
   @Lazy
   private MgrRoleAreaMapper mgrRoleAreaMapper;

   @Autowired
   @Lazy
   private MercMerchantApi mercMerchantApi;

   @Lazy
   @Autowired
   private AllocCanteenApi allocCanteenApi;

   public List<CustOrgTreeDTO> getTenantOrg(Integer excludeMiddle, Integer delFlag, boolean filterOtherRole) {
      MgrUserAuthPO mgrUserAuthPO = this.getUserAuthPO();
      return (filterOtherRole && ObjectUtil.notEqual(mgrUserAuthPO.getRoleType(), MgrRoleTypeV2Enum.ROLE_ORG.getKey()) ? CollUtil.newArrayList(new CustOrgTreeDTO[0]) : this.mgrRoleOrgMapper.getTenantOrg(excludeMiddle, mgrUserAuthPO, delFlag));
   }

   public List<CustOrgTreeDTO> getTenantOrg(Integer excludeMiddle, Integer delFlag) {
      return this.getTenantOrg(excludeMiddle, delFlag, false);
   }

   public List<CustOrgTreeDTO> getTenantOrg(Integer excludeMiddle) {
      return this.getTenantOrg(excludeMiddle, DelFlagEnum.DEL_FALSE.key());
   }

   public MgrUserAuthPO getUserAuthPO() {
      MgrUserAuthPO userAuthPO = new MgrUserAuthPO();
      LoginUser user = SecurityUtils.getLoginUser();
      user.setUserid(SecurityUtils.getUserId());
      user.setUsername(SecurityUtils.getUsername());
      String roleCode = (String) SecureManager.getSubjectData().get("roleCode");
      if (ObjectUtil.isEmpty(roleCode)) {
         throw new ServiceException(I18n.getMessage("auth_user_no_role_code", new Object[0]));
      } else {
         Integer roleType;
         if (roleCode.startsWith(RoleCodeV2Enum.ROLE_ADMIN.key())) {
            if (CharSequenceUtil.split(roleCode, "&&").size() > 1) {
               roleType = MgrRoleTypeV2Enum.ROLE_ADMIN.getKey();
            } else {
               roleType = LeConstants.DATA_DEFAULT_INTEGER;
            }
         } else if (roleCode.startsWith(RoleCodeV2Enum.ROLE_ORG.key())) {
            roleType = MgrRoleTypeV2Enum.ROLE_ORG.getKey();
         } else {
            if (!roleCode.startsWith(RoleCodeV2Enum.ROLE_MERCHANT.key())) {
               throw new ServiceException(I18n.getMessage("auth_role_type_error", new Object[0]));
            }

            roleType = MgrRoleTypeV2Enum.ROLE_MERCHANT.getKey();
         }

         userAuthPO.setUserId(user.getUserid());
         userAuthPO.setRoleType(roleType);
         userAuthPO.setRoleCode(roleCode);
         userAuthPO.setUserName(user.getUsername());
         return userAuthPO;
      }
   }


   public List<Long> getTenantAreaIdList() {
      return this.getTenantAreaIdList(LeConstants.COMMON_YES);
   }

   public List<Long> getTenantAreaIdList(Integer excludeMiddle) {
      MgrUserAuthPO mgrUserAuthPO = this.getUserAuthPO();
      return ObjectUtil.equal(mgrUserAuthPO.getRoleType(), LeConstants.DATA_DEFAULT_INTEGER) ? CollUtil.newArrayList(new Long[0]) : this.mgrRoleAreaMapper.getTenantAreaIdList(excludeMiddle, mgrUserAuthPO);
   }

   public List<AllocCanteenTreeVO> getTenantCanteen(Integer excludeMiddle, Integer delFlag, boolean filterOtherRole) {
      Long tenantId = TenantContextHolder.getTenantId();
      MgrUserAuthPO mgrUserAuthPO = this.getUserAuthPO();
      if (!filterOtherRole) {
         return CollUtil.newArrayList(new AllocCanteenTreeVO[0]);
      } else if (!ObjectUtil.equal(mgrUserAuthPO.getRoleType(), MgrRoleTypeV2Enum.ROLE_ADMIN.getKey()) && !ObjectUtil.equal(mgrUserAuthPO.getRoleType(), MgrRoleTypeV2Enum.ROLE_ORG.getKey())) {
         return this.mgrRoleCanteenMapper.getTenantCanteen(excludeMiddle, tenantId, mgrUserAuthPO, delFlag);
      } else {
         List<AllocCanteenTreeVO> list = CollUtil.newArrayList(new AllocCanteenTreeVO[0]);
         MercMerchant merchant = this.mercMerchantApi.getMerchant();
         AllocCanteenTreeVO merchantVO = new AllocCanteenTreeVO();
         merchantVO.setId(tenantId);
         merchantVO.setParentId(LeConstants.DATA_DEFAULT_LONG);
         merchantVO.setTreeName(merchant.getMerchantName());
         merchantVO.setTreeType(DataTreeTypeEnum.MERCHANT.getKey());
         merchantVO.setBizType(0);
         merchantVO.setHalfSelect(LeConstants.COMMON_YES);
         list.add(merchantVO);
         List<AllocAreaVO> allocAreaList = this.allocCanteenApi.listAreaByUserRole(mgrUserAuthPO);
         allocAreaList.forEach((area) -> {
            AllocCanteenTreeVO areaVO = new AllocCanteenTreeVO();
            areaVO.setId(area.getAreaId());
            areaVO.setParentId(area.getSuperId());
            areaVO.setTreeName(area.getAreaName());
            areaVO.setTreeType(DataTreeTypeEnum.AREA.getKey());
            areaVO.setBizType(0);
            areaVO.setHalfSelect(LeConstants.COMMON_YES);
            list.add(areaVO);
         });
         List<AllocCanteenVO> canteenList = this.allocCanteenApi.listCanteenByUserRole();
         canteenList.forEach((canteen) -> {
            AllocCanteenTreeVO canteenVO = new AllocCanteenTreeVO();
            canteenVO.setId(canteen.getCanteenId());
            canteenVO.setParentId(canteen.getAreaId());
            canteenVO.setTreeName(canteen.getCanteenName());
            canteenVO.setTreeType(DataTreeTypeEnum.CANTEEN.getKey());
            canteenVO.setBizType(canteen.getCanteenType());
            canteenVO.setHalfSelect(LeConstants.COMMON_YES);
            list.add(canteenVO);
         });
         List<AllocStallVO> stallList = this.allocCanteenApi.listStallByUserRole();
         stallList.forEach((stall) -> {
            AllocCanteenTreeVO stallVO = new AllocCanteenTreeVO();
            stallVO.setId(stall.getStallId());
            stallVO.setParentId(stall.getCanteenId());
            stallVO.setTreeName(stall.getStallName());
            stallVO.setTreeType(DataTreeTypeEnum.STALL.getKey());
            stallVO.setBizType(stall.getStallType());
            stallVO.setHalfSelect(LeConstants.COMMON_YES);
            list.add(stallVO);
         });
         return list;
      }
   }
}
