/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.sys.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.jeeplus.common.SecurityUtils;
import com.jeeplus.common.constant.CacheNames;
import com.jeeplus.common.constant.CommonConstants;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.sys.domain.Role;
import com.jeeplus.sys.domain.SysConfig;
import com.jeeplus.sys.domain.Tenant;
import com.jeeplus.sys.domain.User;
import com.jeeplus.sys.mapper.RoleMapper;
import com.jeeplus.sys.mapper.TenantMapper;
import com.jeeplus.sys.mapper.UserMapper;
import com.jeeplus.sys.model.TenantForm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.UUID;

/**
 * 租户Service
 *
 * @author jeeplus
 * @version 2021-05-16
 */
@Service
@Transactional
public class TenantService extends ServiceImpl <TenantMapper, Tenant> {

    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;
    @Autowired
    private SysConfigService configService;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 根据id查询租户
     *
     * @param id
     * @return
     */
    public TenantForm get(String id) {

        Tenant tenant = super.getById ( id );//保存
        TenantForm tenantForm = new TenantForm ( );
        TenantForm.BasicForm basicForm = tenantForm.getBasicForm ( );
        BeanUtil.copyProperties ( tenant, basicForm );

        /**
         * 查询租户管理员信息
         */
        TenantForm.UserForm userForm = tenantForm.getUserForm ( );
        User user = userService.lambdaQuery ( ).eq ( User::getLoginName, "admin" ).eq ( User::getTenantId, id ).one ( );
        if ( user == null ) {
            userForm.setLoginName ( "admin" );
        } else {
            BeanUtil.copyProperties ( user, userForm );
            userForm.setEdit ( true );
        }
        /**
         * 查询租户角色超级管理员
         */
        TenantForm.RoleForm roleForm = tenantForm.getRoleForm ( );
        Role role = roleService.lambdaQuery ( ).eq ( Role::getEnName, "sys" ).eq ( Role::getTenantId, id ).one ( );
        if ( role != null ) {
            roleForm.setEnName ( role.getEnName ( ) );
            roleForm.setName ( role.getName ( ) );
            roleForm.setMenuIds ( StringUtils.join ( roleService.queryAllNotChildrenMenuId ( role.getId ( ) ), "," ) );
        } else {
            roleForm.setEnName ( "sys" );
            roleForm.setName ( "租户管理员" );
            roleForm.setMenuIds ( "" );
        }
        /**
         * 查询产品配置信息
         */
        TenantForm.ConfigForm configForm = tenantForm.getConfigForm ( );
        SysConfig config = configService.getByTenantId ( id );
        BeanUtil.copyProperties ( config, configForm );

        return tenantForm;
    }

    /**
     * 保存或者更新租户信息
     *
     * @param tenantForm
     */
    @CacheEvict(cacheNames = CacheNames.SYS_CACHE_TENANT, allEntries = true)
    public void saveOrUpdate(TenantForm tenantForm) {

        /**
         * 保存租户信息
         */
        TenantForm.BasicForm basicForm = tenantForm.getBasicForm ( );
        Tenant tenant = new Tenant ( );
        BeanUtil.copyProperties ( basicForm, tenant );
        if ( StrUtil.isBlank ( tenant.getId ( ) ) ) {
            String id = super.lambdaQuery ( ).orderByDesc ( Tenant::getId ).list ( ).get ( 0 ).getId ( );
            tenant.setId ( String.valueOf ( Integer.valueOf ( id ) + 1 ) );
        }
        super.saveOrUpdate ( tenant );//保存

        /**
         * 保存租户管理员信息
         */
        TenantForm.UserForm userForm = tenantForm.getUserForm ( );
        User user = userService.lambdaQuery ( ).eq ( User::getLoginName, userForm.getLoginName ( ) ).eq ( User::getTenantId, tenant.getId ( ) ).one ( );
        if ( user == null ) {
            user = new User ( );
        }
        BeanUtil.copyProperties ( userForm, user );
        user.setTenantId ( tenant.getId ( ) );
        // 如果新密码为空，则不更换密码
        if ( StrUtil.isNotBlank ( userForm.getNewPassword ( ) ) ) {
            user.setPassword ( SecurityUtils.encryptPassword ( userForm.getNewPassword ( ) ) );
        }

        if ( StrUtil.isNotBlank ( user.getId ( ) ) ) {
            userService.updateById ( user );
        } else {
            user.setLoginFlag ( CommonConstants.YES );
            userService.save ( user );
        }
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_LOGIN_NAME, user.getTenantId ( ) + ":" + user.getLoginName ( ) );
        /**
         * 保存租户角色超级管理员
         */
        TenantForm.RoleForm roleForm = tenantForm.getRoleForm ( );
        Role role = roleService.lambdaQuery ( ).eq ( Role::getEnName, "sys" ).eq ( Role::getTenantId, tenant.getId ( ) ).one ( );
        if ( role == null ) {
            role = new Role ( );
            role.setEnName ( roleForm.getEnName ( ) );
            role.setName ( roleForm.getName ( ) );
            role.setTenantId ( tenant.getId ( ) );
            role.setSysData ( CommonConstants.YES );
            role.setUseable ( CommonConstants.YES );
            roleService.save ( role );
        } else {
            role.setEnName ( roleForm.getEnName ( ) );
            role.setName ( roleForm.getName ( ) );
            role.setTenantId ( tenant.getId ( ) );
            role.setUseable ( CommonConstants.YES );
            roleService.updateById ( role );
        }
        String roleId = role.getId ( );
        roleMapper.deleteRoleMenu ( roleId );
        Lists.newArrayList ( roleForm.getMenuIds ( ).split ( "," ) ).forEach ( menuId -> {
            roleMapper.insertRoleMenu ( roleId, menuId );
        } );

        // 更新用户与角色关联
        userMapper.deleteUserRole ( user.getId ( ) );
        userMapper.insertUserRole ( user.getId ( ), roleId );
        /**
         * 保存产品配置信息
         */
        TenantForm.ConfigForm configForm = tenantForm.getConfigForm ( );
        SysConfig sysConfig = configService.getByTenantId ( tenant.getId ( ) );
        if ( sysConfig == null ) {
            sysConfig = new SysConfig ( );
        }
        BeanUtil.copyProperties ( configForm, sysConfig );
        sysConfig.setTenantId ( tenant.getId ( ) );
        if ( StrUtil.isNotBlank ( sysConfig.getId ( ) ) ) {
            configService.updateByTenantId ( sysConfig );
        } else {
            configService.save ( sysConfig );
        }

        /**
         * 新建租户时，初始化租户需要的sql数据
         */
        if ( StrUtil.isEmpty ( basicForm.getId ( ) ) ) {
            syncDataBaseForTenant ( tenant.getId ( ) );
        }

    }

    private void syncDataBaseForTenant(String tenantId) {
        /**
         * 工作流常用按钮
         */
        jdbcTemplate.execute ( "DELETE from `act_extension_button` WHERE tenant_id = '" + tenantId + "'" );
        jdbcTemplate.execute ( "INSERT INTO `act_extension_button`(id, name, code, sort, del_flag, tenant_id) VALUES " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '指定回退', '_flow_back', '4', '0', '" + tenantId + "')," +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '同意', '_flow_agree', '2',  '0', '" + tenantId + "')," +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '加签', '_flow_add_multi_instance', '5',  '0', '" + tenantId + "'), " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '转办', '_flow_transfer', '7',  '0', '" + tenantId + "'), " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '打印', '_flow_print', '10',  '0', '" + tenantId + "'), " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '暂存', '_flow_save', '1', '0', '" + tenantId + "')," +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '终止', '_flow_stop', '9',  '0', '" + tenantId + "'), " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '驳回', '_flow_reject', '3',  '0', '" + tenantId + "')," +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '减签', '_flow_del_multi_instance', '6',  '0', '" + tenantId + "'), " +
                "('" + UUID.randomUUID ( ).toString ( ) + "', '委派', '_flow_delegate', '8',  '0', '" + tenantId + "');" );
    }

    /**
     * 批量删除
     *
     * @param list
     * @return
     */
    @CacheEvict(cacheNames = CacheNames.SYS_CACHE_TENANT, allEntries = true)
    public boolean removeByIds(Collection <? extends Serializable> list) {
        return super.removeByIds ( list );
    }


}
