package com.chenyang.nse.bussiness.service;

import com.chenyang.nse.bussiness.dao.table.base.TBaseGroupDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseGroupMenuDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseGroupRoleDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseMenuDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseMenuresourceDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseResourceDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseRoleDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseRolemenuDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseUserDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseUserMenuDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseUsergroupDao;
import com.chenyang.nse.bussiness.dao.table.base.TBaseUserroleDao;
import com.chenyang.nse.bussiness.dao.table.console.TConsolePrivilegeDao;
import com.chenyang.nse.bussiness.dao.table.console.TConsoleSearchregexDao;
import com.chenyang.nse.bussiness.dao.table.console.TConsoleSystemSettingDao;
import com.chenyang.nse.bussiness.entity.orm.table.TInitEntity;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseGroup;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseGroupmenu;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseGrouprole;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseMenu;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseResource;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseRole;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseRolemenu;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUser;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUsergroup;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUsermenu;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUserproject;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUserrole;
import com.chenyang.nse.bussiness.entity.orm.table.base.TBaseUsersys;
import com.chenyang.nse.bussiness.entity.orm.table.console.TConsolePrivilege;
import com.chenyang.nse.bussiness.entity.orm.table.console.TConsoleSystemSetting;
import com.chenyang.nse.bussiness.entity.vo.UserVO;
import com.chenyang.nse.bussiness.service.console.UserService;
import com.chenyang.nse.bussiness.tools.string.PasswordEncryptTool;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

@Service
public class IndexServiceImpl implements IndexService {
   @Autowired
   private TBaseMenuDao menuDao;
   @Autowired
   private TBaseResourceDao resourceDao;
   @Autowired
   private TBaseMenuresourceDao menuresourceDao;
   @Autowired
   private TBaseGroupDao groupDao;
   @Autowired
   private TBaseRoleDao roleDao;
   @Autowired
   private TBaseRolemenuDao rolemenuDao;
   @Autowired
   private TBaseUserDao userDao;
   @Autowired
   private TBaseUsergroupDao usergroupDao;
   @Autowired
   private TBaseUserroleDao userroleDao;
   @Autowired
   private TConsoleSearchregexDao searchregexDao;
   @Autowired
   private TConsolePrivilegeDao privilegeDao;
   @Autowired
   private TConsoleSystemSettingDao tConsoleSystemSettingDao;
   @Autowired
   private UserService userService;
   @Autowired
   private TBaseUserMenuDao userMenuDao;
   @Autowired
   private TBaseGroupMenuDao groupMenuDao;
   @Autowired
   private TBaseGroupRoleDao groupRoleDao;
   @Autowired
   private TBaseMenuDao tBaseMenuDao;

   public TBaseUser login(TBaseUser user) {
      Criterion cusername = Restrictions.eq("username", user.getUsername());
      Criterion cpassword = Restrictions.eq("password", PasswordEncryptTool.generatePassword(user.getPassword()));
      user = (TBaseUser)this.userDao.queryUnique(new Criterion[]{cusername, cpassword});
      return user;
   }

   public TBaseUser login1(TBaseUser user) {
      Criterion cusername = Restrictions.eq("username", user.getUsername());
      user = (TBaseUser)this.userDao.queryUnique(new Criterion[]{cusername});
      return user;
   }

   public List<TBaseGroup> queryGroupByUserId(String userid) {
      Criterion cuserid = Restrictions.eq("userid", userid);
      List<TBaseUsergroup> tBaseUsergroups = this.usergroupDao.queryAll(new Criterion[]{cuserid});
      List<TBaseGroup> list = new ArrayList();

      for(TBaseUsergroup tBaseUsergroup : tBaseUsergroups) {
         TBaseGroup group = (TBaseGroup)this.groupDao.get(tBaseUsergroup.getGroupid());
         list.add(group);
      }

      return list;
   }

   public List<TBaseRole> queryRoleByUserId(String userid) {
      List<TBaseRole> role = new ArrayList();
      Criterion cuserid = Restrictions.eq("userid", userid);
      List<TBaseUserrole> userroleList = this.userroleDao.queryAll(new Criterion[]{cuserid});
      if (userroleList.size() == 0) {
         return role;
      } else {
         List<String> roleidList = (List)userroleList.stream().map(TBaseUserrole::getRoleid).collect(Collectors.toList());
         role = this.roleDao.queryAll(new Criterion[]{Restrictions.in("id", roleidList)});
         return role;
      }
   }

   public List<TBaseMenu> qeuryMenusByRoleId(List<TBaseRole> roles) {
      List<String> lrole = new ArrayList();

      for(TBaseRole role : roles) {
         lrole.add(role.getId());
      }

      List<TBaseRolemenu> role_menu = this.rolemenuDao.queryAll(new Criterion[]{Restrictions.in("roleid", lrole)});
      List<String> menuidlist = new ArrayList();

      for(TBaseRolemenu item : role_menu) {
         menuidlist.add(item.getMenuid());
      }

      menuidlist = (List)menuidlist.stream().distinct().collect(Collectors.toList());
      new ArrayList();
      return this.menuDao.qeuryMenusByRoleId(lrole, menuidlist);
   }

   public List<TBaseMenu> queryMenusByUserId(String userId) {
      List<TBaseMenu> allMenus = new ArrayList();
      Set<String> resultMenuIds = new HashSet();
      Criterion cUserId = Restrictions.eq("userid", userId);
      List<TBaseUsermenu> userMenus = this.userMenuDao.queryAll(new Criterion[]{cUserId});
      userMenus.forEach((menux) -> resultMenuIds.add(menux.getMenuid()));
      List<TBaseGroup> groupList = this.queryGroupByUserId(userId);
      List<TBaseGrouprole> groupRoleIds = new ArrayList();

      for(TBaseGroup group : groupList) {
         Criterion cGroupId = Restrictions.eq("groupid", group.getId());
         List<TBaseGroupmenu> groupMenus = this.groupMenuDao.queryAll(new Criterion[]{cGroupId});
         groupMenus.forEach((groupMenu) -> resultMenuIds.add(groupMenu.getMenuid()));
         groupRoleIds.addAll(this.groupRoleDao.queryAll(new Criterion[]{cGroupId}));
      }

      List<TBaseRole> allRole = new ArrayList();
      List<TBaseRole> tRole = this.queryRoleByUserId(userId);
      groupRoleIds.forEach((x) -> {
         TBaseRole groupRole = new TBaseRole();
         groupRole.setId(x.getRoleid());
         allRole.add(groupRole);
      });
      allRole.addAll(tRole);
      List<TBaseMenu> list = new ArrayList();
      if (resultMenuIds.size() != 0) {
         List<TBaseMenu> menusById = this.menuDao.queryAll(new Criterion[]{Restrictions.in("id", resultMenuIds)});
         list.addAll(menusById);
      }

      if (allRole.size() != 0) {
         List<TBaseMenu> menusByRole = this.qeuryMenusByRoleId(allRole);
         list.addAll(menusByRole);
      }

      List<TBaseMenu> list1 = (List)list.stream().filter((x) -> x.getParentid() == null).collect(Collectors.toList());
      List<TBaseMenu> list2 = (List)list.stream().filter((x) -> x.getParentid() != null).collect(Collectors.toList());
      List<String> list3 = new ArrayList();
      List<TBaseMenu> list4 = new ArrayList();

      for(TBaseMenu tBaseMenu : list2) {
         list3.add(tBaseMenu.getParentid());
      }

      for(String s : list3.stream().distinct().collect(Collectors.toList())) {
         TBaseMenu fa_menu = (TBaseMenu)this.tBaseMenuDao.queryUnique(new Criterion[]{Restrictions.eq("id", s)});
         List<TBaseMenu> sublist = new ArrayList();

         for(TBaseMenu tBaseMenu : list2) {
            if (tBaseMenu.getParentid().equals(s)) {
               sublist.add(tBaseMenu);
            }
         }

         if (null != fa_menu) {
            fa_menu.setSubmenu(sublist);
            list4.add(fa_menu);
         }
      }

      allMenus.addAll(list1);
      allMenus.addAll(list4);
      allMenus = (List)allMenus.stream().distinct().collect(Collectors.toList());
      Map<String, TBaseMenu> maps = (Map)allMenus.stream().collect(Collectors.toMap(TInitEntity::getId, Function.identity()));
      allMenus.clear();

      for(Map.Entry<String, TBaseMenu> entry : maps.entrySet()) {
         if (((TBaseMenu)entry.getValue()).getParentid() != null) {
            if (!ObjectUtils.isEmpty(((TBaseMenu)maps.get(((TBaseMenu)entry.getValue()).getParentid())).getSubmenu())) {
               ((TBaseMenu)maps.get(((TBaseMenu)entry.getValue()).getParentid())).getSubmenu().add(entry.getValue());
            }
         } else {
            allMenus.add(entry.getValue());
         }
      }

      for(TBaseMenu menu : allMenus) {
         if (menu.getSubmenu() != null && menu.getSubmenu().size() != 0) {
            List<TBaseMenu> submenu = menu.getSubmenu();
            submenu = (List)submenu.stream().distinct().collect(Collectors.toList());
            menu.setSubmenu(submenu);
         }
      }

      allMenus.forEach((x) -> {
         if (x.getSubmenu() != null) {
            Collections.sort(x.getSubmenu());
         } else {
            x.setSubmenu(new ArrayList());
         }

      });
      Collections.sort(allMenus);
      return allMenus;
   }

   public List<TBaseMenu> qeuryMenus() {
      List<TBaseMenu> tBaseMenus = this.menuDao.qeuryAllMenus();
      List<TBaseMenu> collect = (List)tBaseMenus.stream().filter((x) -> !"3".equals(x.getType())).collect(Collectors.toList());
      return collect;
   }

   public TBaseMenu queryMenusBySubName(String submenuname) {
      return this.menuDao.queryMenusBySubName(submenuname);
   }

   @Transactional
   public List<TBaseResource> queryResourcesListByRoleId(List<TBaseRole> trole) {
      List<String> lrole = new ArrayList();

      for(TBaseRole role : trole) {
         lrole.add(role.getId());
      }

      List<String> menuid = this.rolemenuDao.queryMenuIdListByRoleId(lrole);
      List<String> resourceid = this.menuresourceDao.queryResourceIdListByMenuId(menuid);
      if (ObjectUtils.isEmpty(resourceid)) {
         return null;
      } else {
         Criterion criterion = Restrictions.in("id", resourceid);
         List<TBaseResource> list = this.resourceDao.queryAll(new Criterion[]{criterion});
         return list;
      }
   }

   public List<TConsolePrivilege> queryPrivilegeByRoleId(List<TBaseRole> trole) {
      List<String> lrole = new ArrayList();

      for(TBaseRole role : trole) {
         lrole.add(role.getId());
      }

      Criterion criterion = Restrictions.in("roleid", lrole);
      List<TConsolePrivilege> list = this.privilegeDao.queryAll(new Criterion[]{criterion});
      return list;
   }

   @Transactional
   public void saveOrUpdate(TBaseUser user) {
      this.userDao.saveOrUpdate(user);
   }

   public List<TConsoleSystemSetting> querySystemSettings() {
      List<TConsoleSystemSetting> tcssLst = this.tConsoleSystemSettingDao.queryAll();
      return tcssLst;
   }

   public TBaseUser querykeyByUsername(String username) {
      TBaseUser tBaseUser = (TBaseUser)this.userDao.queryUnique(new Criterion[]{Restrictions.eq("username", username)});
      return tBaseUser;
   }

   public List<TBaseMenu> queryMenusByType(String s) {
      List<TBaseMenu> tBaseMenus = this.menuDao.qeuryAllMenus();
      List<TBaseMenu> collect = (List)tBaseMenus.stream().filter((x) -> s.equals(x.getType())).collect(Collectors.toList());
      return collect;
   }

   public List<TBaseUsersys> qeurySysByUserId(String userid) {
      List<TBaseUsersys> userSysLst = this.userService.queryusersysbyuserid(userid);
      UserVO uservo = this.userService.queryByUserid(userid);
      if (uservo == null) {
         return userSysLst;
      } else {
         List<TBaseUsersys> groupSysLst = this.userService.queryusersysbyuserid(uservo.getGroupid());
         Map<String, TBaseUsersys> mapAllSys = new HashMap();

         for(TBaseUsersys usersys : userSysLst) {
            mapAllSys.put(usersys.getSysid(), usersys);
         }

         for(TBaseUsersys groupsys : groupSysLst) {
            if (mapAllSys.get(groupsys.getSysid()) != null && groupsys.getCrud() != null) {
               if (Integer.parseInt(((TBaseUsersys)mapAllSys.get(groupsys.getSysid())).getCrud()) < Integer.parseInt(groupsys.getCrud())) {
                  mapAllSys.put(groupsys.getSysid(), groupsys);
               }
            } else {
               mapAllSys.put(groupsys.getSysid(), groupsys);
            }
         }

         List<TBaseUsersys> allSysList = new ArrayList();

         for(Map.Entry<String, TBaseUsersys> a : mapAllSys.entrySet()) {
            allSysList.add(a.getValue());
         }

         return allSysList;
      }
   }

   public List<TBaseUserproject> qeuryProjectByUserId(String userid) {
      List<TBaseUserproject> userProList = null;
      return userProList;
   }
}
