package com.njzscloud.supervisory.sys.user.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.util.EncryptUtil;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.supervisory.biz.constant.BizObj;
import com.njzscloud.supervisory.biz.pojo.param.AddBizCompanyParam;
import com.njzscloud.supervisory.biz.service.BizCompanyService;
import com.njzscloud.supervisory.money.pojo.entity.MoneyAccountEntity;
import com.njzscloud.supervisory.money.service.MoneyAccountService;
import com.njzscloud.supervisory.sys.role.pojo.entity.RoleEntity;
import com.njzscloud.supervisory.sys.role.pojo.result.RoleDetailResult;
import com.njzscloud.supervisory.sys.user.contant.Gender;
import com.njzscloud.supervisory.sys.user.mapper.UserMapper;
import com.njzscloud.supervisory.sys.user.pojo.entity.UserAccountEntity;
import com.njzscloud.supervisory.sys.user.pojo.entity.UserEntity;
import com.njzscloud.supervisory.sys.user.pojo.param.*;
import com.njzscloud.supervisory.sys.user.pojo.result.UserAccountDetailResult;
import com.njzscloud.supervisory.sys.user.pojo.result.UserDetailResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户信息表
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService extends ServiceImpl<UserMapper, UserEntity> implements IService<UserEntity> {
    private final UserAccountService userAccountService;
    private final UserRoleService userRoleService;
    private final BizCompanyService bizCompanyService;
    private final MoneyAccountService moneyAccountService;

    /**
     * 新增
     */
    @Transactional(rollbackFor = Exception.class)
    public Long add(AddUserParam addUserParam) {
        AddUserAccountParam addUserAccountParam = addUserParam.getAccount();

        UserEntity userEntity = BeanUtil.copyProperties(addUserParam, UserEntity.class);
        this.save(userEntity);

        Long userEntityId = userEntity.getId();

        userAccountService.add(addUserAccountParam.setUserId(userEntityId));

        List<RoleEntity> roles = addUserParam.getRoles();
        if (CollUtil.isEmpty(roles)) {
            return userEntityId;
        }
        Set<Long> roleIds = roles.stream().map(RoleEntity::getId).collect(Collectors.toSet());
        userRoleService.bindUserRole(userEntityId, roleIds);

        return userEntityId;
    }

    /**
     * 修改
     */
    @Transactional(rollbackFor = Exception.class)
    public void modify(UserModifyParam userModifyParam) {
        Long id = userModifyParam.getId();
        UserEntity userEntity = this.getById(id);
        Assert.notNull(userEntity, () -> Exceptions.clierr("要修改的数据不存在"));

        userEntity = BeanUtil.copyProperties(userModifyParam, UserEntity.class);
        this.updateById(userEntity);

        List<RoleEntity> roles = userModifyParam.getRoles();
        if (roles != null && !roles.isEmpty()) {
            Set<Long> collect = roles.stream().map(RoleEntity::getId).collect(Collectors.toSet());
            userRoleService.bindUserRole(id, collect);
        }
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeByIds(ids);
        userAccountService.delByUserIds(ids);
        userRoleService.delByUserIds(ids);
    }

    /**
     * 详情
     */
    public UserDetailResult detail(Long id) {
        UserEntity userEntity = this.getById(id);
        Assert.notNull(userEntity, "未查询到用户信息");
        UserDetailResult userDetailResult = BeanUtil.copyProperties(userEntity, UserDetailResult.class);
        UserAccountEntity userAccountEntity = userAccountService.getOne(Wrappers.<UserAccountEntity>lambdaQuery().eq(UserAccountEntity::getUserId, id));
        Assert.notNull(userAccountEntity, "未查询到用户信息");
        UserAccountDetailResult userAccountDetailResult = BeanUtil.copyProperties(userAccountEntity, UserAccountDetailResult.class);
        List<RoleDetailResult> roleDetailResults = userRoleService.listRole(id);
        return userDetailResult
                .setTenantId(userEntity.getTenantId())
                .setAccount(userAccountDetailResult)
                .setRoles(roleDetailResults);
    }

    /**
     * 分页查询
     */
    public PageResult<UserDetailResult> paging(IPage<UserDetailResult> page, UserQueryParam userQueryParam) {
        String nickname = userQueryParam.getNickname();
        Gender gender = userQueryParam.getGender();
        String email = userQueryParam.getEmail();
        String phone = userQueryParam.getPhone();
        String username = userQueryParam.getUsername();
        Boolean disabled = userQueryParam.getDisabled();
        QueryWrapper<UserDetailResult> ew = Wrappers.<UserDetailResult>query()
                .and(it ->
                        it.eq("a.biz_obj", BizObj.SiBang)
                                .or().isNull("a.biz_obj")
                )
                .like(StrUtil.isNotBlank(nickname), "a.nickname", nickname)
                .eq(gender != null, "a.gender", gender)
                .like(StrUtil.isNotBlank(email), "a.email", email)
                .like(StrUtil.isNotBlank(phone), "a.phone", phone)
                .like(StrUtil.isNotBlank(username), "b.username", username)
                .eq(disabled != null, "b.disabled", disabled);
        return PageResult.of(baseMapper.paging(page, ew));
    }

    /**
     * 用户注册
     *
     * @param userRegisterParam 参数
     */
    @Transactional(rollbackFor = Exception.class)
    public void register(UserRegisterParam userRegisterParam) {
        UserRegisterParam.Account account = userRegisterParam.getAccount();
        Assert.notNull(account, () -> Exceptions.clierr("账号信息不能为空"));
        BizObj bizObj = userRegisterParam.getBizObj();
        if (bizObj == BizObj.GeRen) {
            Assert.notBlank(account.getPhone(), () -> Exceptions.clierr("手机号不能为空"));
            Assert.notBlank(account.getWechatOpenid(), () -> Exceptions.clierr("微信号不能为空"));
        } else if (bizObj == BizObj.ShiGongDanWei
                || bizObj == BizObj.WuYe
                || bizObj == BizObj.ChaiQian
                || bizObj == BizObj.SheQu
                || bizObj == BizObj.QiTa
                || bizObj == BizObj.QiYe
                || bizObj == BizObj.GeTi
        ) {
            Assert.notBlank(account.getUsername(), () -> Exceptions.clierr("用户名不能为空"));
            Assert.notBlank(account.getSecret(), () -> Exceptions.clierr("密码不能为空"));
        } else {
            throw Exceptions.clierr("业务对象错误");
        }

        String nickname = userRegisterParam.getNickname();
        Assert.notBlank(nickname, () -> Exceptions.clierr("用户姓名不能为空"));

        if (bizObj.isWastePersonal()) {
            String wechatOpenid = account.getWechatOpenid();
            String wechatUnionid = account.getWechatUnionid();
            UserAccountEntity oldAccount = userAccountService.getOne(Wrappers.<UserAccountEntity>lambdaQuery()
                    .eq(StrUtil.isNotBlank(wechatUnionid), UserAccountEntity::getWechatUnionid, wechatUnionid)
                    .eq(UserAccountEntity::getWechatOpenid, wechatOpenid));

            if (oldAccount != null) {
                String oldUserPhone = oldAccount.getPhone();
                Assert.isTrue(oldUserPhone.equals(account.getPhone()), () -> Exceptions.clierr("手机号错误"));
                return;
            }
        }

        AddUserParam addUserParam = BeanUtil.copyProperties(userRegisterParam, AddUserParam.class);
        addUserParam.setAccount(BeanUtil.copyProperties(account, AddUserAccountParam.class));
        Long userId = this.add(addUserParam);
//        if (bizObj == BizObj.GeRen) {
//            entity.setUserId(userId);
//            moneyAccountService.add(entity);
//            return;
//        }
        Long companyId = null;
        if (!bizObj.isWastePersonal()) {
            UserRegisterParam.Company company = userRegisterParam.getCompany();
            Assert.notNull(company, "公司信息不能为空");
            AddBizCompanyParam addBizCompanyParam = BeanUtil
                    .copyProperties(company, AddBizCompanyParam.class)
                    .setUserId(userId);
            companyId = bizCompanyService.add(addBizCompanyParam);
        }


        // 添加账户信息
        if (bizObj.isTrans()) {
            MoneyAccountEntity entity = new MoneyAccountEntity();
            entity.setStationId(companyId);
            moneyAccountService.add(entity);
        }
    }

    /**
     * 修改密码
     */
    @Transactional(rollbackFor = Exception.class)
    public void modifyPasswd(ModifyPasswdParam modifyPasswdParam) {
        Long userId = SecurityUtil.currentUserId();
        userAccountService.modifyPasswd(userId, modifyPasswdParam);
    }

    public void resetPasswd(Long id) {
        userAccountService.update(Wrappers.<UserAccountEntity>lambdaUpdate().eq(UserAccountEntity::getUserId, id)
                .set(UserAccountEntity::getSecret, EncryptUtil.encrypt("666666")));
    }
}
