package com.blueland.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blueland.core.util.IdentifierGenerator;
import com.blueland.bo.*;
import com.blueland.dao.AdminUserDao;
import com.blueland.dao.AppDatabaseDao;
import com.blueland.dao.ApplicationDao;
import com.blueland.dao.ModuleDao;
import com.blueland.model.TPfApplication;
import com.blueland.model.TPfApplicationDb;
import com.blueland.service.IApplicationService;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ApplicationServiceImpl extends ServiceImpl<ApplicationDao, TPfApplication> implements IApplicationService {

    @Autowired
    private ApplicationDao applicationDao;
    @Resource
    private AdminUserDao adminUserDao;
    @Resource
    private AppDatabaseDao appDatabaseDao;
    @Resource
    private ModuleDao moduleDao;

    /**
     * 根据条件查询TagApplication列表(分页)
     */
    @Override
    public Page<ApplicationEntity> findApplicationPageListByParams(Map<String, Object> tagApplication, int curPage, int pageSize) {
        Page<ApplicationEntity> page = new Page<>(curPage, pageSize);
        Page<ApplicationEntity> list = applicationDao.findApplicationPageByParams(page, tagApplication);
        //拿系统管理员和数据库相关数据放进list，用于查看详情展示
        if (ObjectUtil.isNotEmpty(list.getRecords())) {
            for (ApplicationEntity applicationEntity : list.getRecords()) {
                Map<String, Object> params = Maps.newHashMap();
                Map<String, Object> paramsOrg = Maps.newHashMap();
                params.put("appId", applicationEntity.getAppId());
                params.put("adminType", "YYGL");
                paramsOrg.put("appId", applicationEntity.getAppId());
                paramsOrg.put("adminType", "ORG");
                List<AdminUserEntity> userList = adminUserDao.findAdminUserListByParams(params);
                AppDatabaseEntity appDatabaseList = appDatabaseDao.findList(params);

                List<AdminUserEntity> orgList = adminUserDao.findAdminOrgListByParams(paramsOrg);
                if (orgList.size() > 0) {
                    String adminOrg = "";
                    for (AdminUserEntity org : orgList) {
                        adminOrg = adminOrg + org.getUserOrgName() + "/" + org.getUserName() + ",";
                    }
                    adminOrg = adminOrg.substring(0, adminOrg.length() - 1);
                    applicationEntity.setAdminOrgName(adminOrg);
                    applicationEntity.setAdminOrgList(orgList);
                }

                if (userList.size() > 0) {
                    String adminUser = "";
                    for (AdminUserEntity pfAdminUserEntity : userList) {
                        adminUser = adminUser + pfAdminUserEntity.getUserOrgName() + "/" + pfAdminUserEntity.getUserName() + ",";
                    }
                    adminUser = adminUser.substring(0, adminUser.length() - 1);
                    applicationEntity.setAdminUserName(adminUser);
                    applicationEntity.setAdminUserList(userList);
                }
                applicationEntity.setAppDatabaseList(appDatabaseList);
            }
        }
        return list;
    }

    /**
     * 根据条件查询TagApplication列表(不分页)
     */
    @Override
    public List<ApplicationEntity> findTagApplicationListByParams(Map<String, Object> tagApplication) {
        return applicationDao.findApplicationListByParams(tagApplication);
    }

    ;

    /**
     * 处理应用相关数据库数据保存
     *
     * @param appdatabaseMap
     * @param application
     * @return
     */
    @Override
    public boolean dealAppDatabase(Map<String, Object> appdatabaseMap, ApplicationEntity application) {
        boolean flag = false;
        //先删除数据库管理表数据(根据appId删)
        appDatabaseDao.deleteAppDatabaseByAppId(application.getAppId());
        try {
            TPfApplicationDb pfAppDatabase = new TPfApplicationDb();
            pfAppDatabase.setAppId(application.getAppId());
            if ("Y".equals(application.getIsService())) {
                pfAppDatabase.setTypeName(appdatabaseMap.get("typeName").toString());
                pfAppDatabase.setUrl(appdatabaseMap.get("url").toString());
                pfAppDatabase.setInstanceName(appdatabaseMap.get("instanceName").toString());
                pfAppDatabase.setUsername(appdatabaseMap.get("username").toString());
                pfAppDatabase.setPassword(appdatabaseMap.get("password").toString());
                pfAppDatabase.setDriverName(appdatabaseMap.get("driverName").toString());
            }
            int count = appDatabaseDao.insert(pfAppDatabase);
            if (count > 0) {
                flag = true;
            }

        } catch (Exception e) {
            log.error("pfApplicationService --> dealAdminUser,detailMap:" + appdatabaseMap + ",application:" + application + "," + e.getMessage());
        }
        return flag;
    }

    /**
     * 处理组织数据保存
     *
     * @param detailMap
     * @param application
     * @return
     */
    private boolean dealAdminOrg(List<Map<String, Object>> detailMap, ApplicationEntity application) {
        boolean flag = false;
        try {
            List<AdminUserEntity> list = new ArrayList<>();
            //处理管理员用户数据
            for (Map<String, Object> map : detailMap) {
                AdminUserEntity pfAdminUser = new AdminUserEntity();
                pfAdminUser.setId(IdentifierGenerator.createPrimaryKeySeq());
                pfAdminUser.setAppId(application.getAppId());
                pfAdminUser.setAdminType("ORG");
                pfAdminUser.setUserCode(map.get("deptId").toString());
                pfAdminUser.setUserName(map.get("userDeptName").toString());
                pfAdminUser.setUserOrgId(map.get("userOrgId").toString());
                pfAdminUser.setUserOrgName(map.get("userOrgName").toString());
                pfAdminUser.setUserDeptId(map.get("userDeptId").toString());
                pfAdminUser.setUserDeptName(map.get("userDeptName").toString());
                list.add(pfAdminUser);
            }
            int count = adminUserDao.insertBatchAdminUser(list);
            if (count > 0) {
                flag = true;
            }

        } catch (Exception e) {
            log.error("tagApplicationService --> dealAdminUser,detailMap:" + detailMap + ",application:" + application + "," + e.getMessage());
        }
        return flag;
    }

    /**
     * 处理用户管理员数据保存
     *
     * @param detailMap
     * @param application
     * @return
     */
    @Override
    public boolean dealAdminUser(List<Map<String, Object>> detailMap, ApplicationEntity application) {
        boolean flag = false;
        //先删除 管理员用户表数据
        adminUserDao.deleteAdminUserByBizId(application.getAppId());
        try {
            List<AdminUserEntity> list = new ArrayList<>();
            //处理管理员用户数据
            for (Map<String, Object> map : detailMap) {
                AdminUserEntity pfAdminUser = new AdminUserEntity();
                pfAdminUser.setId(IdentifierGenerator.createPrimaryKeySeq());
                pfAdminUser.setAppId(application.getAppId());
                //应用管理
                pfAdminUser.setAdminType("YYGL");
                pfAdminUser.setUserCode(map.get("userCode").toString());
                pfAdminUser.setUserName(map.get("userName").toString());
                pfAdminUser.setUserOrgId(map.get("userOrgId").toString());
                pfAdminUser.setUserOrgName(map.get("userOrgName").toString());
                pfAdminUser.setUserDeptId(map.get("userDeptId").toString());
                pfAdminUser.setUserDeptName(map.get("userDeptName").toString());
                list.add(pfAdminUser);
            }
            int count = adminUserDao.insertBatchAdminUser(list);
            if (count > 0) {
                flag = true;
            }

        } catch (Exception e) {
            log.error("tagApplicationService --> dealAdminUser,detailMap:" + detailMap + ",application:" + application + "," + e.getMessage());
        }
        return flag;
    }

    /**
     * 批量删除
     *
     * @param
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Integer batchDelete(String[] appIds) {
        if (appIds == null || appIds.length == 0) {
            return 0;
        }
        return applicationDao.batchDelete(appIds);
    }

    /**
     * 保存数据
     *
     * @param params
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Boolean saveDate(Map<String, Object> params) {
        boolean flag = false;
        if (!params.containsKey("application") && !params.containsKey("appDatabaseList") && !params.containsKey("adminUserList")) {
            return false;
        }
        boolean status = saveInformation(params);
        if (status) {
            TPfApplication application = JSON.parseObject(JSON.toJSONString(params), TPfApplication.class);
            if (ObjectUtil.isEmpty(application.getAppId())) {
                throw new RuntimeException("应用编码不能为空");
            }
            TPfApplication tPfApplication = applicationDao.selectById(application.getAppId());
            if (ObjectUtil.isNotEmpty(tPfApplication)) {
                throw new RuntimeException("该应用已存在：" + application.getAppId());
            }
            application.setCreateTime(new Date());
            int result = applicationDao.insert(application);
            if (result > 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 更新数据
     *
     * @param params
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Boolean updateDate(Map<String, Object> params) {
        boolean flag = false;
        if (!params.containsKey("application") && !params.containsKey("appDatabaseList") && !params.containsKey("adminUserList")) {
            return false;
        }
        boolean status = saveInformation(params);
        if (status) {
            TPfApplication application = JSON.parseObject(JSON.toJSONString(params), TPfApplication.class);
            application.setUpdateTime(new Date());
            int result = applicationDao.updateById(application);
            if (result > 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 保存数据-数据库相关信息和应用管理员
     */
    @Override
    public Boolean saveInformation(Map<String, Object> params) {
        boolean status = false;
        ApplicationEntity application = JSON.parseObject(JSON.toJSONString(params), ApplicationEntity.class);
        List<Map<String, Object>> detailMap = (List<Map<String, Object>>) params.get("adminUserList");

        Map<String, Object> appdatabaseMap = (Map<String, Object>) params.get("appDatabaseList");
        //处理用户管理员数据保存
        boolean flag = this.dealAdminUser(detailMap, application);

        if (params.containsKey("adminOrgList")) {
            List<Map<String, Object>> detailOrgMap = (List<Map<String, Object>>) params.get("adminOrgList");
            if (detailOrgMap.size() > 0) {
                boolean flagOrg = this.dealAdminOrg(detailOrgMap, application);
                if (!flagOrg) {
                    return false;
                }
            }
        }

        // 处理应用相关数据库数据保存
        boolean dataflag = true;
        // 企业内部普通应用
        if ("QYNBPT".equals(application.getAppType())) {
            dataflag = this.dealAppDatabase(appdatabaseMap, application);
        }

        if (flag && dataflag) {
            status = true;
        }
        return status;
    }


    /**
     * 查询应用、模块、组合树
     *
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> getCombinationTreeList(Map<String, Object> params) {
        long startTime = System.currentTimeMillis();
        List<Map<String, Object>> result = new ArrayList<>();
        // 查出所有应用
        List<ApplicationEntity> applicationList = applicationDao.findApplicationListByParams(params);
        for (ApplicationEntity applicationEntity : applicationList) {
            Map<String, Object> map = Maps.newHashMap();
            // 用于前台树上的唯一标识-id
            map.put("id", applicationEntity.getAppId());
            // 用于前台页面展示名称
            map.put("name", applicationEntity.getAppName());
            map.put("appId", applicationEntity.getAppId());
            map.put("appName", applicationEntity.getAppName());
            map.put("appStatus", applicationEntity.getAppStatus());
            map.put("moduleId", "");
            map.put("moduleName", "");
            map.put("appType", applicationEntity.getAppType());
            //用于前端判断层级
            map.put("hierarchy", 0);
            getTopNode(applicationEntity.getAppId(), map, applicationEntity.getAppType());
            result.add(map);
        }
        long endITme = System.currentTimeMillis();
        log.error("耗时" + (float) (endITme - startTime) / 1000 + "s");
        return result;
    }

    /**
     * 获取模块顶级节点后再查下面的子节点
     *
     * @param appId
     * @param map
     * @param appType
     * @return
     */
    private Map<String, Object> getTopNode(String appId, Map<String, Object> map, String appType) {
        //此appId下的所有模块
        List<ModuleEntity> allModuleList = moduleDao.findModuleListByAppId(appId);
        //获取模块一级分类数据
        List<ModuleEntity> topModuleList = allModuleList.stream().filter(item -> (item.getHierarchy()) == 1).collect(Collectors.toList());
        List<Map<String, Object>> children = new ArrayList<>();
        for (ModuleEntity topModuleEntity : topModuleList) {
            Map<String, Object> child = Maps.newHashMap();
            // 用于前台树上的唯一标识-id
            child.put("id", topModuleEntity.getModuleId());
            // 用于前台页面展示名称
            child.put("name", topModuleEntity.getName());
            child.put("appId", topModuleEntity.getAppId());
            child.put("appName", topModuleEntity.getAppName());
            child.put("moduleId", topModuleEntity.getModuleId());
            child.put("moduleName", topModuleEntity.getName());
            child.put("hierarchy", topModuleEntity.getHierarchy());
            child.put("appType", appType);
            children.add(child);
        }
        if (children.size() > 0) {
            map.put("children", children);
        }
        return map;
    }

    /**
     * 递归 根据父分类moduleId 查询子分类
     *
     * @param appId
     * @param map
     * @param allModuleList
     * @return
     */
//    private Map<String, Object> findChildren(Map<String, Object> map, List<ModuleEntity> allModuleList) {
//        List<Map<String, Object>> children = new ArrayList<>();
//        for (ModuleEntity moduleEntity : allModuleList) {
//            // 模块下还有子模块
//            if (map.get("moduleId").toString().equals(moduleEntity.getParentId())) {
//                Map<String, Object> child = Maps.newHashMap();
//                // 用于前台树上的唯一标识-id
//                child.put("id", moduleEntity.getModuleId());
//                child.put("moduleId", moduleEntity.getModuleId());
//                child.put("code", moduleEntity.getCode());
//                child.put("name", moduleEntity.getName());
//                child.put("appId", moduleEntity.getAppId());
//                child.put("appName", moduleEntity.getAppName());
//                child.put("accessUrl", moduleEntity.getAccessUrl());
//                child.put("menuSys", moduleEntity.getMenuSys());
//                child.put("parentId", moduleEntity.getParentId());
//                child.put("parentName", moduleEntity.getParentName());
//                child.put("hierarchy", moduleEntity.getHierarchy());
//                child.put("status", moduleEntity.getStatus());
//                child.put("sort", moduleEntity.getSort());
//                child.put("remark", moduleEntity.getRemark());
//                child.put("createUserId", moduleEntity.getCreateUserId());
//                child.put("createUserName", moduleEntity.getCreateUserName());
//                child.put("updateUserId", moduleEntity.getUpdateUserId());
//                child.put("updateUserName", moduleEntity.getUpdateUserName());
//                child.put("createTime", moduleEntity.getCreateTime());
//                child.put("updateTime", moduleEntity.getUpdateTime());
//                children.add(child);
//                this.findChildren(child, allModuleList);
//            }
//        }
//        // 查询当前应用当前模块下且category字段值为"LIST"的表单列表
//        Map<String, Object> param = Maps.newHashMap();
//        param.put("category", "LIST");
//        param.put("moduleId", map.get("moduleId").toString());
//        param.put("sortColumns", "sort");
//        List<CustomFormEntity> customFormEntityList = customFormDao.findCustomFormListByParams(param);
//        if (children.size() > 0) {
//            map.put("children", children);
//        }
//        return map;
//    }

    /**
     * 获取用户所有应用
     * @param userId
     * @return
     */
    @Override
    public List<ApplicationEntity> findApplicationListByUser(String userId){
    	return applicationDao.findApplicationListByUser(userId);
    }

    @Override
    public TPfApplication get(ApplicationEntity entity){
        return applicationDao.selectOne(buildQueryWrapper(entity));
    }

    @Override
    public List<ApplicationEntity> findList(ApplicationEntity entity){
        return applicationDao.findList(entity);
    }

    @Override
    public Page<ApplicationEntity> findPage(ApplicationEntity entity) {
        Page<ApplicationEntity> page = new Page(entity.getPageNum(), entity.getPageSize());
        return applicationDao.findPage(page, entity);
    }

    private LambdaQueryWrapper<TPfApplication> buildQueryWrapper(ApplicationEntity bo) {
        LambdaQueryWrapper<TPfApplication> lqw = Wrappers.lambdaQuery();;
        lqw.eq(ObjectUtil.isNotEmpty(bo.getAppId()), TPfApplication::getAppId, bo.getAppId());
        lqw.like(ObjectUtil.isNotEmpty(bo.getAppName()), TPfApplication::getAppName, bo.getAppName());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getAppStatus()), TPfApplication::getAppStatus, bo.getAppStatus());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getFrontPort()), TPfApplication::getFrontPort, bo.getFrontPort());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getRearPort()), TPfApplication::getRearPort, bo.getRearPort());
        lqw.eq(ObjectUtil.isNotEmpty(bo.getAppType()), TPfApplication::getAppType, bo.getAppType());
        lqw.like(ObjectUtil.isNotEmpty(bo.getAppDescribe()), TPfApplication::getAppDescribe, bo.getAppDescribe());
        return lqw;
    }
}
