package cn.newfeifan.mall.module.sale.service.merchantapply;

import cn.hutool.core.lang.Assert;
import cn.newfeifan.mall.framework.common.exception.ErrorCode;
import cn.newfeifan.mall.framework.ip.core.Area;
import cn.newfeifan.mall.framework.ip.core.utils.AreaUtils;
import cn.newfeifan.mall.module.member.api.user.MemberUserApi;
import cn.newfeifan.mall.module.member.api.user.dto.MemberUserRespDTO;
import cn.newfeifan.mall.module.member.enums.DictTypeConstants;
import cn.newfeifan.mall.module.sale.controller.app.merchantapply.vo.MerchantApplyPageReqVO;
import cn.newfeifan.mall.module.sale.controller.app.merchantapply.vo.MerchantApplySaveReqVO;
import cn.newfeifan.mall.module.sale.enums.MerchantApplyCheckPersonStatusEnum;
import cn.newfeifan.mall.module.sale.enums.MerchantApplyCheckStatusEnum;
import cn.newfeifan.mall.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.newfeifan.mall.module.system.service.user.AdminUserService;
import cn.newfeifan.mall.module.trade.api.wechat.WcChatMessageUtilsApi;
import cn.newfeifan.mall.module.trade.enums.wxmessage.WcChatMessageTemplateIdEnum;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import cn.newfeifan.mall.module.sale.dal.dataobject.merchantapply.MerchantApplyDO;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.object.BeanUtils;

import cn.newfeifan.mall.module.sale.dal.mysql.merchantapply.MerchantApplyMapper;


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

import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.newfeifan.mall.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.newfeifan.mall.module.sale.enums.ErrorCodeConstants.*;

/**
 * 商户申请 Service 实现类
 *
 * @author 非繁人
 */
@Service
@Validated
public class MerchantApplyServiceImpl implements MerchantApplyService {

    @Resource
    private MerchantApplyMapper merchantApplyMapper;

    @Resource
    private AdminUserService usersService;

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private WcChatMessageUtilsApi wcChatMessageUtilsApi;

    @Override
    public Long createMerchantApply(MerchantApplySaveReqVO createReqVO) {

        // 校验商户账号是否已经存在
        MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
        List<MemberUserRespDTO> users = memberUserApi.getUsersByMobile(user.getMobile());
        List<MerchantApplyDO> merchantApplyDOS = merchantApplyMapper.selectList(MerchantApplyDO::getApplyMemberUserId, users.stream().map(MemberUserRespDTO::getId).collect(Collectors.toList()));
        if(merchantApplyDOS != null && merchantApplyDOS.size() >= 1){
            ErrorCode ERROR = new ErrorCode(1_002_029_003, "当前手机号已存在商户账号");
            throw exception(ERROR);
        }


        // 校验存在
        if (usersService.getUserByMobile(createReqVO.getContactNumber()) != null) {
            ErrorCode ERROR = new ErrorCode(1_002_029_003, "联络人账户已存在");
            throw exception(ERROR);
        }

        // 插入
        MerchantApplyDO merchantApply = BeanUtils.toBean(createReqVO, MerchantApplyDO.class);
        merchantApply.setApplyMemberUserId(getLoginUserId());
        merchantApply.setCheckPersonStatus(MerchantApplyCheckPersonStatusEnum.ONE.getStatus());

        // 默认log
        if (createReqVO.getLogoUrl() == null || createReqVO.getLogoUrl().isEmpty()) {
            merchantApply.setLogoUrl(DictTypeConstants.DEFAULT_AVATAR);
        }

        merchantApplyMapper.insert(merchantApply);

        // 发送微信信息到系统用户
        sentWxChantMessageToThSystemUser(merchantApply,MerchantApplyCheckPersonStatusEnum.ONE.getUserid());

        // 返回
        return merchantApply.getId();
    }

    /**
     * 发送微信信息到系统用户
     * @param merchantApply 入驻申请
     */
    private void sentWxChantMessageToThSystemUser(MerchantApplyDO merchantApply, Long sentSystemUserId){
        List<String> params = new ArrayList<>();

        params.add(merchantApply.getName());
        params.add(merchantApply.getContact());
        params.add(merchantApply.getContactNumber());
        params.add(merchantApply.getAddress() == null || merchantApply.getAddress().isEmpty() ? "-" : merchantApply.getAddress());
        params.add(getAreaById(merchantApply.getAreaId().intValue()));

        wcChatMessageUtilsApi.sendWcChatMessage(WcChatMessageTemplateIdEnum.MERCHANT_APPLY_CHECK.getTemplateId(),
                params, sentSystemUserId, merchantApply.getId());
    }

    private String getAreaById(Integer id){
        Area area = AreaUtils.getArea(Area.ID_CHINA);
        Assert.notNull(area, "获取不到中国");
        List<AreaNodeRespVO> bean = BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class);

        for (AreaNodeRespVO areaNode : bean) {
            if (areaNode.getChildren() != null) {
                String result = findInSubList(areaNode.getChildren(), id);
                if (result != null) {
                    return result;
                }
            }
        }
        return "未找到对应的省市区";
    }

    private String findInSubList(List<AreaNodeRespVO> subList, long childId) {
        for (AreaNodeRespVO areaNode : subList) {
            if (areaNode.getId() == childId) {
                return areaNode.getName();
            }
            if (areaNode.getChildren() != null) {
                String result = findInSubList(areaNode.getChildren(), childId);
                if (result != null) {
                    // 假设我们想要返回整个路径，例如 "北京市东城区"
                    return areaNode.getName() + result;
                }
            }
        }
        return null;
    }

    @Override
    public void updateMerchantApply(MerchantApplySaveReqVO updateReqVO) {

        MerchantApplyDO merchantApplyDO = merchantApplyMapper.selectById(updateReqVO.getId());

        // 联系人手机号校验
        if (!merchantApplyDO.getContactNumber().equals(updateReqVO.getContactNumber()) && usersService.getUserByMobile(updateReqVO.getContactNumber()) != null) {
            ErrorCode ERROR = new ErrorCode(1_002_029_003, "联络人账户已存在");
            throw exception(ERROR);
        }

        updateReqVO.setApplyMemberUserId(getLoginUserId());
        // 校验存在
        validateMerchantApplyExists(updateReqVO.getId());
        // 更新
        MerchantApplyDO updateObj = BeanUtils.toBean(updateReqVO, MerchantApplyDO.class);

        // 默认log
        if (updateObj.getLogoUrl() == null || updateObj.getLogoUrl().isEmpty()) {
            updateObj.setLogoUrl(DictTypeConstants.DEFAULT_AVATAR);
        }

        // 所有变动都需要重新审核
        updateObj.setCheckStatus(MerchantApplyCheckStatusEnum.WAIT_AUDIT.getType());
        updateObj.setCheckPersonStatus(MerchantApplyCheckPersonStatusEnum.ONE.getStatus());


        merchantApplyMapper.updateById(updateObj);

        // 发送微信信息到系统用户
        sentWxChantMessageToThSystemUser(updateObj,MerchantApplyCheckPersonStatusEnum.ONE.getUserid());
    }

    @Override
    public void deleteMerchantApply(Long id) {
        // 校验存在
        validateMerchantApplyExists(id);
        // 删除
        merchantApplyMapper.deleteById(id);
    }

    private void validateMerchantApplyExists(Long id) {
        if (merchantApplyMapper.selectById(id) == null) {
            throw exception(MERCHANT_APPLY_NOT_EXISTS);
        }
    }

    @Override
    public MerchantApplyDO getMerchantApply(Long id) {
        return merchantApplyMapper.selectById(id);
    }

    @Override
    public PageResult<MerchantApplyDO> getMerchantApplyPage(MerchantApplyPageReqVO pageReqVO) {
        return merchantApplyMapper.selectPage(pageReqVO);
    }

    @Override
    public MerchantApplyDO getMerchantApplyBYUserId(Long loginUserId) {
        return merchantApplyMapper.selectOne(MerchantApplyDO::getApplyMemberUserId, loginUserId);
    }

    @Override
    public Boolean isSystemUserByMobile() {
        // 获取消费者手机号
        MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
        // 获取申请入驻信息
        MerchantApplyDO merchantApplyDO = merchantApplyMapper.selectOne(MerchantApplyDO::getApplyMemberUserId, getLoginUserId());

        // 判断是否有系统用户
        return usersService.getUserByMobile(user.getMobile()) != null && merchantApplyDO == null;
    }

}