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

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.modules.account.constant.AccountManageConstants;
import com.ruoyi.web.modules.account.dto.AccountPasswordUpdateDTO;
import com.ruoyi.web.modules.account.dto.AccountProfileUpdateDTO;
import com.ruoyi.web.modules.account.service.IAccountProfileService;
import com.ruoyi.web.modules.account.support.AccountManageSupport;
import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;

/**
 * 账号资料写操作实现
 */
@Service
public class AccountProfileServiceImpl implements IAccountProfileService
{
    @Autowired
    private AccountManageSupport accountManageSupport;

    @Autowired
    private BizMerchantAccountMapper merchantAccountMapper;

    @Autowired
    private ISysUserService sysUserService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> updateProfile(AccountProfileUpdateDTO dto, String operator)
    {
        accountManageSupport.validateProfileUpdate(dto);
        SysUser user = accountManageSupport.requireSysUser(dto.getUserId());
        BizMerchantAccount binding = accountManageSupport.findMerchantAdminBinding(dto.getUserId());
        boolean merchantAdmin = binding != null;

        String currentMobile = accountManageSupport.resolveMobile(user, merchantAdmin);
        boolean mobileChanged = !currentMobile.equals(dto.getMobile());
        if (merchantAdmin && mobileChanged && !dto.isConfirmed())
        {
            Map<String, Object> data = new HashMap<>();
            data.put("needConfirm", true);
            data.put("confirmMessage", AccountManageConstants.MSG_MOBILE_CHANGE_CONFIRM);
            return data;
        }
        if (mobileChanged)
        {
            assertMobileUnique(dto.getUserId(), dto.getMobile(), merchantAdmin);
        }

        if (merchantAdmin)
        {
            merchantAccountMapper.updateSysUserProfile(
                    dto.getUserId(),
                    mobileChanged ? dto.getMobile() : null,
                    dto.getAccountName(),
                    dto.getEmail(),
                    mobileChanged ? dto.getMobile() : null,
                    null,
                    operator);
            binding.setUpdateBy(operator);
            merchantAccountMapper.update(binding);
        }
        else
        {
            merchantAccountMapper.updateSysUserProfile(
                    dto.getUserId(),
                    null,
                    dto.getAccountName(),
                    dto.getEmail(),
                    mobileChanged ? dto.getMobile() : null,
                    null,
                    operator);
        }

        Map<String, Object> data = new HashMap<>();
        data.put("needConfirm", false);
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(AccountPasswordUpdateDTO dto, String operator)
    {
        accountManageSupport.validatePasswordUpdate(dto);
        accountManageSupport.requireSysUser(dto.getUserId());

        String passwordHash = SecurityUtils.encryptPassword(dto.getPassword());
        merchantAccountMapper.updateSysUserProfile(
                dto.getUserId(),
                null,
                null,
                null,
                null,
                passwordHash,
                operator);

        BizMerchantAccount binding = accountManageSupport.findMerchantAdminBinding(dto.getUserId());
        if (binding != null)
        {
            binding.setUpdateBy(operator);
            merchantAccountMapper.update(binding);
        }
    }

    private void assertMobileUnique(Long userId, String mobile, boolean merchantAdmin)
    {
        if (merchantAdmin)
        {
            SysUser check = new SysUser();
            check.setUserId(userId);
            check.setUserName(mobile);
            if (!sysUserService.checkUserNameUnique(check))
            {
                throw new ServiceException(AccountManageConstants.MSG_MOBILE_EXISTS);
            }
            return;
        }
        SysUser check = new SysUser();
        check.setUserId(userId);
        check.setPhonenumber(mobile);
        if (!sysUserService.checkPhoneUnique(check))
        {
            throw new ServiceException(AccountManageConstants.MSG_MOBILE_EXISTS);
        }
    }
}
