package com.ruoyi.web.modules.merchant.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.modules.account.domain.BizMember;
import com.ruoyi.web.modules.account.mapper.BizMemberMapper;
import com.ruoyi.web.modules.merchant.constant.MerchantBindConstants;
import com.ruoyi.web.modules.merchant.dto.MerchantCreateDTO;
import com.ruoyi.web.modules.merchant.mapper.MerchantBindMapper;
import com.ruoyi.web.modules.merchant.service.IMerchantAccountBindService;
import com.ruoyi.web.modules.store.constant.ShopConstants;
import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;

@Service
public class MerchantAccountBindServiceImpl implements IMerchantAccountBindService
{
    private static final long DEFAULT_DEPT_ID = 100L;

    @Autowired
    private MerchantBindMapper merchantBindMapper;

    @Autowired
    private BizMerchantAccountMapper merchantAccountMapper;

    @Autowired
    private BizMemberMapper memberMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private SysRoleMapper roleMapper;

    @Override
    public void bindAccountOnMerchantCreate(Long merchantId, MerchantCreateDTO dto, String operator)
    {
        validateBindRequest(dto);
        if (MerchantBindConstants.BIND_SYS_USER.equals(dto.getBindType()))
        {
            bindFromSysUser(merchantId, dto.getBindUserId(), operator);
        }
        else if (MerchantBindConstants.BIND_MEMBER.equals(dto.getBindType()))
        {
            bindFromMember(merchantId, dto, operator);
        }
        else
        {
            throw new ServiceException(MerchantBindConstants.MSG_BIND_REQUIRED);
        }
    }

    private void bindFromSysUser(Long merchantId, Long userId, String operator)
    {
        if (userId == null)
        {
            throw new ServiceException(MerchantBindConstants.MSG_BIND_USER_REQUIRED);
        }
        SysUser user = sysUserService.selectUserById(userId);
        if (user == null)
        {
            throw new ServiceException(MerchantBindConstants.MSG_ADMIN_NOT_FOUND);
        }
        if (merchantBindMapper.countUserHasRole(userId, MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY) <= 0)
        {
            throw new ServiceException(MerchantBindConstants.MSG_ADMIN_NO_ROLE);
        }
        String loginName = user.getUserName();
        assertLoginNameAvailable(loginName);
        BizMerchantAccount account = new BizMerchantAccount();
        account.setMerchantId(merchantId);
        account.setLoginName(loginName);
        account.setAdminName(StringUtils.isNotEmpty(user.getNickName()) ? user.getNickName() : user.getUserName());
        account.setPassword(resolveMerchantAccountPassword(user.getPassword(), operator));
        account.setDelFlag(ShopConstants.DEL_NORMAL);
        account.setCreateBy(operator);
        merchantAccountMapper.insert(account);
    }

    private void bindFromMember(Long merchantId, MerchantCreateDTO dto, String operator)
    {
        Long memberId = dto.getBindMemberId();
        if (memberId == null)
        {
            throw new ServiceException(MerchantBindConstants.MSG_BIND_MEMBER_REQUIRED);
        }
        BizMember member = memberMapper.selectById(memberId);
        if (member == null)
        {
            throw new ServiceException(MerchantBindConstants.MSG_MEMBER_NOT_FOUND);
        }
        String memberName = StringUtils.isNotEmpty(member.getMemberCode()) ? member.getMemberCode() : member.getNickName();
        if (StringUtils.isEmpty(memberName))
        {
            memberName = "会员";
        }
        String adminName = memberName + memberId;
        String loginName = member.getNickName();
        if (StringUtils.isEmpty(loginName))
        {
            throw new ServiceException("会员昵称不能为空，无法作为经营账号登录名");
        }
        assertLoginNameAvailable(loginName);

        String sysUserName = adminName;
        if (sysUserService.selectUserByUserName(sysUserName) != null)
        {
            sysUserName = adminName + "_m";
        }
        String plainPassword = resolveSysUserPlainPassword(dto);
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(DEFAULT_DEPT_ID);
        sysUser.setUserName(sysUserName);
        sysUser.setNickName(StringUtils.isNotEmpty(member.getNickName()) ? member.getNickName() : memberName);
        sysUser.setPhonenumber(member.getMobile());
        sysUser.setPassword(SecurityUtils.encryptPassword(plainPassword));
        sysUser.setStatus("0");
        sysUser.setCreateBy(operator);
        Long roleId = resolveMerchantAdminRoleId();
        sysUser.setRoleIds(new Long[] { roleId });
        if (!sysUserService.checkUserNameUnique(sysUser))
        {
            throw new ServiceException("同步创建平台账号失败，登录名已存在");
        }
        if (StringUtils.isNotEmpty(sysUser.getPhonenumber()) && !sysUserService.checkPhoneUnique(sysUser))
        {
            throw new ServiceException("同步创建平台账号失败，手机号已被占用");
        }
        sysUserService.insertUser(sysUser);

        BizMerchantAccount account = new BizMerchantAccount();
        account.setMerchantId(merchantId);
        account.setLoginName(loginName);
        account.setAdminName(adminName);
        account.setPassword(StringUtils.isNotEmpty(member.getPassword()) ? member.getPassword()
                : SecurityUtils.encryptPassword(plainPassword));
        account.setDelFlag(ShopConstants.DEL_NORMAL);
        account.setCreateBy(operator);
        merchantAccountMapper.insert(account);
    }

    private void validateBindRequest(MerchantCreateDTO dto)
    {
        if (dto == null || StringUtils.isEmpty(dto.getBindType()))
        {
            throw new ServiceException(MerchantBindConstants.MSG_BIND_REQUIRED);
        }
    }

    private void assertLoginNameAvailable(String loginName)
    {
        if (merchantAccountMapper.countByLoginName(loginName, null) > 0)
        {
            throw new ServiceException(MerchantBindConstants.MSG_LOGIN_EXISTS);
        }
    }

    private String resolveMerchantAccountPassword(String sysUserPasswordHash, String operator)
    {
        if (StringUtils.isNotEmpty(sysUserPasswordHash))
        {
            return sysUserPasswordHash;
        }
        String init = configService.selectConfigByKey("sys.user.initPassword");
        if (StringUtils.isEmpty(init))
        {
            init = "123456";
        }
        return SecurityUtils.encryptPassword(init);
    }

    private String resolveSysUserPlainPassword(MerchantCreateDTO dto)
    {
        if (StringUtils.isNotEmpty(dto.getSysUserInitPassword()))
        {
            return dto.getSysUserInitPassword();
        }
        String init = configService.selectConfigByKey("sys.user.initPassword");
        return StringUtils.isNotEmpty(init) ? init : "123456";
    }

    private Long resolveMerchantAdminRoleId()
    {
        SysRole query = new SysRole();
        query.setRoleKey(MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY);
        for (SysRole role : roleMapper.selectRoleList(query))
        {
            if (MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY.equals(role.getRoleKey()))
            {
                return role.getRoleId();
            }
        }
        try
        {
            Long roleId = Long.valueOf(MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY);
            if (roleMapper.selectRoleById(roleId) != null)
            {
                return roleId;
            }
        }
        catch (NumberFormatException ignored)
        {
            // not numeric role id
        }
        throw new ServiceException("未配置商户经营角色（role_key=" + MerchantBindConstants.MERCHANT_ADMIN_ROLE_KEY + "）");
    }
}
