package cc.smtweb.system.bpm.web.sys.user.user;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.EntityDao;
import cc.smtweb.framework.core.db.impl.DefaultEntity;
import cc.smtweb.framework.core.db.jdbc.IDbWorker;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.common.BpmConst;
import cc.smtweb.system.bpm.web.design.form.define.PageDataset;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageDelHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageListHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageLoadHandler;
import cc.smtweb.system.bpm.web.engine.dynPage.DynPageSaveHandler;
import cc.smtweb.system.bpm.web.login.LoginHelper;
import cc.smtweb.system.bpm.web.sys.user.role.RoleCache;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by Akmm at 2022/7/1 15:47
 * 区划保存
 */
public class UserHandler {
    private final static String DS_UserParty = "userPartyList";
    private final static String DS_UserCard = "userCard";

    public static EntityDao<User> getUserDao() {
        return DbEngine.getInstance().findDao(User.ENTITY_NAME);
    }

    public static EntityDao<UserStatu> getUserStatuDao() {
        return DbEngine.getInstance().findDao(UserStatu.ENTITY_NAME);
    }

    public static EntityDao<UserParty> getUserPartyDao() {
        return DbEngine.getInstance().findDao(UserParty.ENTITY_NAME);
    }

    public static EntityDao<UserRole> getUserRoleDao() {
        return DbEngine.getInstance().findDao(UserRole.ENTITY_NAME);
    }

    static class UserSaveHandler extends DynPageSaveHandler {
        private UserStatu userStatu;
        private List<UserRole> roleList;
        private List<UserParty> partyList;

        @Override
        protected DefaultEntity readBeanFromPage(PageDataset pageDataSet, SwMap data) {
            if (pageDataSet._isCurDataSet(DS_UserCard)) {
                DefaultEntity bean = super.readBeanFromPage(pageDataSet, data);
                roleList = new ArrayList<>();
                partyList = new ArrayList<>();
                List<Map<String, Object>> rows = data.readListMap("partyData");
                if (CommUtil.isEmpty(rows)) throw new BizException("用户所属机构为空");
                for (Map<String, Object> row : rows) {
                    UserParty userParty = new UserParty();
                    userParty.init();
                    userParty.getData().putAll(row);
                    userParty.setUserId(bean.getEntityId());
                    userParty.setEntityId(DbEngine.getInstance().nextId());
                    partyList.add(userParty);

                    String roles = row.get("sup_roles").toString();
                    if (StringUtil.isEmpty(roles)) throw new BizException("用户机构所属角色为空");
                    for (String role_id : roles.split(",")) {
                        UserRole userRole = new UserRole();
                        userRole.init();
                        userRole.setEntityId(DbEngine.getInstance().nextId());
                        userRole.setSupId(userParty.getEntityId());
                        userRole.setRoleId(Long.valueOf(role_id));
                        roleList.add(userRole);
                    }
                }
                return bean;
            }
            return super.readBeanFromPage(pageDataSet, data);
        }

        @Override
        protected void saveBean(DefaultEntity bean) {
            if (bean instanceof User) {
                userStatu = UserStatuCache.getInstance().get(bean.getEntityId());
                if (userStatu == null || userStatu.isEmpty()) {
                    userStatu = new UserStatu();
                    userStatu.init();
                    userStatu.setEntityId(bean.getEntityId());
                    getUserStatuDao().insertEntity(userStatu);
                    UserStatuCache.getInstance().put(userStatu);
                }
                if (bean.isNew()) {
                    ((User) bean).setCreate(DateUtil.nowDateTimeLong());
                    ((User) bean).setPwd(LoginHelper.encodePwd(bean.getEntityId(), BpmConst.DEF_PWD));
                }

                Set<Long> up = UserPartyCache.getInstance().getIdByUser(bean.getEntityId());
                Set<Long> ur = UserRoleCache.getInstance().getIdByUser(bean.getEntityId());
                getUserRoleDao().deleteEntity(ur);
                getUserPartyDao().deleteEntity(up);
                getUserRoleDao().batchInsertEntity(roleList);
                getUserPartyDao().batchInsertEntity(partyList);

                UserRoleCache.getInstance().removeList(ur);
                UserPartyCache.getInstance().removeList(up);
                UserRoleCache.getInstance().putList(roleList);
                UserPartyCache.getInstance().putList(partyList);
            }
            super.saveBean(bean);
        }
    }

    static class UserDelHandler extends DynPageDelHandler {

        @Override
        protected void checkBean(PageDataset pageDataSet, long id) {

        }

        @Override
        protected void localDel(long id, ModelTable table) {
            super.localDel(id, table);
            if (table.getName().equals(User.ENTITY_NAME)) {
                getUserStatuDao().deleteEntity(id);
                getUserPartyDao().deleteEntity(UserPartyCache.getInstance().getIdByUser(id));
                getUserRoleDao().deleteEntity(UserRoleCache.getInstance().getIdByUser(id));
            }
        }

        @Override
        protected void localDelSuccess(long id, ModelTable table) {
            if (table.getName().equals(User.ENTITY_NAME)) {
                UserStatuCache.getInstance().remove(id);
                UserPartyCache.getInstance().removeList(UserPartyCache.getInstance().getIdByUser(id));
                UserRoleCache.getInstance().removeList(UserRoleCache.getInstance().getIdByUser(id));
            }
        }
    }

    static class UserListHandler extends DynPageListHandler {

        public UserListHandler(long pageId, SwMap filter, PageDataset pageDataSet) {
            super(pageId, filter, pageDataSet);
        }

        @Override
        protected void afterQuery(List<SwMap> listData) {
            if (pageDataSet._isCurDataSet(DS_UserParty)) {
                listData.forEach(sw -> {
                    sw.put("sup_roles", StringUtil.join(UserRoleCache.getInstance().getRoleByParty(sw.readLong("sup_id")),","));
                    sw.put("sup_roles_text", RoleCache.getInstance().getNamesByIds(UserRoleCache.getInstance().getRoleByParty(sw.readLong("sup_id"))));
                });
                return;
            }
            super.afterQuery(listData);
        }
    }

    static class UserLoadHandler extends DynPageLoadHandler {

        @Override
        public DynPageListHandler getListWorker(SwMap filter, PageDataset pageDataSet) {
            UserListHandler listHandler = new UserListHandler(form.getId(), filter, pageDataSet);
            listHandler.init(params, us);
            return listHandler;
        }
    }

    static class UserCustHandler extends AbstractHandler {

        public R batchDelParty() {
            Set<Long> idList = params.readLongSet("ids");
            Set<Long> roleIdList = UserRoleCache.getInstance().getByParty(idList);
            DbEngine.getInstance().doTrans(new IDbWorker() {
                @Override
                public void work() {
                    getUserPartyDao().deleteEntity(idList);
                    getUserRoleDao().deleteEntity(roleIdList);
                }

                @Override
                public void doAfterDbCommit() {
                    UserPartyCache.getInstance().removeList(idList);
                    UserRoleCache.getInstance().removeList(roleIdList);
                }
            });
            return R.success();
        }

        public R delAll() {
            long id = params.readLong("id");
            Set<Long> partyIds = UserPartyCache.getInstance().getIdByUser(id);
            Set<Long> roleIds = UserRoleCache.getInstance().getByParty(partyIds);
            DbEngine.getInstance().doTrans(new IDbWorker() {
                @Override
                public void work() {
                    getUserDao().deleteEntity(id);
                    getUserStatuDao().deleteEntity(id);
                    getUserRoleDao().deleteEntity(roleIds);
                    getUserPartyDao().deleteEntity(partyIds);
                }

                @Override
                public void doAfterDbCommit() {
                    UserCache.getInstance().remove(id);
                    UserStatuCache.getInstance().remove(id);
                    UserRoleCache.getInstance().removeList(roleIds);
                    UserPartyCache.getInstance().removeList(partyIds);
                }
            });
            return R.success();
        }

        public R resetPwd() {
            Set<Long> idList = params.readLongSet("ids");
            Set<User> userList = UserCache.getInstance().getUserList(idList);
            userList.forEach(user -> {
                user.setPwd(LoginHelper.encodePwd(user.getId(), BpmConst.DEF_PWD));
            });
            DbEngine.getInstance().doTrans(new IDbWorker() {
                @Override
                public void work() {
                    DbEngine.getInstance().findDao(User.ENTITY_NAME).batchUpdateEntity(userList);
                }

                @Override
                public void doAfterDbCommit() {
                    UserCache.getInstance().putList(userList);
                }
            });
            return R.success();
        }
    }
}
