package com.xingxi.api.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.xingxi.api.data.mapper.WxApiUserAddressMapper;
import com.xingxi.api.model.*;
import com.xingxi.business.UserAddress.domain.UserAddress;
import com.xingxi.business.UserAddress.mapper.UserAddressMapper;
import com.xingxi.common.aliyun.oss.AliyunOSSClient;
import com.xingxi.common.annotation.Excel;
import com.xingxi.common.core.domain.entity.SysUser;
import com.xingxi.common.enums.EDelFlag;
import com.xingxi.common.enums.EYesNo;
import com.xingxi.common.utils.StringUtils;
import com.xingxi.common.utils.spring.SpringUtils;
import com.xingxi.common.utils.uuid.IdUtils;
import com.xingxi.api.common.UserContext;
import com.xingxi.api.data.domain.UserProfileDTO;
import com.xingxi.api.service.UserProfileServiceI;
import com.xingxi.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import sun.misc.BASE64Decoder;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
@Validated
class UserProfileServiceImpl implements UserProfileServiceI {
    private final WxApiUserAddressMapper userAddressMapper;
    @NotBlank
    @Value("${aliyun.oss.customDomain}")
    private String customDomain;
    @NotBlank
    @Value("${wx.qrCode.scene}")
    private String scene;
    @NotBlank
    @Value("${wx.qrCode.page}")
    private String page;
    @NotNull
    @Value("${wx.qrCode.width}")
    private Integer width;
    @NotNull
    @Value("${wx.qrCode.checkPath}")
    private Boolean checkPath;
    @NotBlank
    @Value("${wx.qrCode.envVersion}")
    private String envVersion;

    private final SysUserMapper sysUserMapper;
    private final WxMaService wxMaService;
    private final AliyunOSSClient client;
    private static final String base64_pre = "data:image/png;base64,";

    @Transactional
    @Override
    public UserProfileUpdateResponse updateUserNickName(UserContext userContext, UserProfileUpdateRequest request) {
        SysUser currentUser = userContext.getCurrentUser();
        Long userId = currentUser.getUserId();
        String phoneNum = currentUser.getPhonenumber();
        String userType = currentUser.getUserType();
        String avatar = currentUser.getAvatar();

        SysUser wxUser = new SysUser();
        wxUser.setUserId(userId);
        wxUser.setUserName(request.getNickName());
        wxUser.setUpdateUser(userId + "");
        wxUser.setUpdateTime(new Date());
        sysUserMapper.updateUser(wxUser);

        UserProfileDTO userProfileDTO = new UserProfileDTO();
        userProfileDTO.setUserType(userType);
        userProfileDTO.setUserId(userId + "");
        userProfileDTO.setPhoneNumber(phoneNum);
        userProfileDTO.setNickName(wxUser.getUserName());
        userProfileDTO.setAvatarUrl(avatar);
        userProfileDTO.setGender(wxUser.getSex());

        return new UserProfileUpdateResponse(
                userProfileDTO
        );
    }

    @Transactional
    @Override
    public UserProfileUpdateResponse updateUserAvatar(UserContext userContext, UserProfileUpdateRequest request) {
        SysUser currentUser = userContext.getCurrentUser();
        Long userId = currentUser.getUserId();
        String phoneNum = currentUser.getPhonenumber();
        String userType = currentUser.getUserType();
        String nickName = currentUser.getUserName();

        String base64 = request.getAvatarBase64().replace(base64_pre, "");
        // base64转存到OSS，然后将地址更新到头像中。
        AliyunOSSClient client = SpringUtils.getBean(AliyunOSSClient.class);

        String avatarUrl = "";
        try {
            String fileName = "OSS/public/avatar/" + IdUtils.fastUUID() + ".png";

            // 填写Byte数组。
            byte[] content = new BASE64Decoder().decodeBuffer(request.getAvatarBase64());
            // 创建PutObject请求。
            avatarUrl = client.putObject(fileName, new ByteArrayInputStream(content));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        SysUser wxUser = new SysUser();
        wxUser.setUserId(userId);
        wxUser.setAvatar(avatarUrl);
        wxUser.setUpdateUser(userId + "");
        wxUser.setUpdateTime(new Date());
        sysUserMapper.updateUser(wxUser);

        UserProfileDTO userProfileDTO = new UserProfileDTO();
        userProfileDTO.setUserType(userType);
        userProfileDTO.setUserId(userId + "");
        userProfileDTO.setPhoneNumber(phoneNum);
        userProfileDTO.setNickName(nickName);
        userProfileDTO.setAvatarUrl(wxUser.getAvatar());
        userProfileDTO.setGender(wxUser.getSex());

        return new UserProfileUpdateResponse(
                userProfileDTO
        );
    }

    @Transactional
    @Override
    public UserProfileUpdateResponse updateUserProfile(UserContext userContext, UserProfileUpdateRequest request) {
        SysUser currentUser = userContext.getCurrentUser();
        Long userId = currentUser.getUserId();
        String phoneNum = currentUser.getPhonenumber();
        String sessionKey = currentUser.getWxSessionKey();
        String ueerType = currentUser.getUserType();

        String iv = request.getIv();
        String encryptedData = request.getEncryptedData();

        WxMaUserService userService = wxMaService.getUserService();
        WxMaUserInfo wxUserInfo = userService.getUserInfo(sessionKey, encryptedData, iv);

        SysUser wxUser = new SysUser();
        wxUser.setUserId(userId);
        wxUser.setUserName(wxUserInfo.getNickName());
        wxUser.setSex(wxUserInfo.getGender());
        wxUser.setAvatar(wxUserInfo.getAvatarUrl());
        wxUser.setUpdateUser(userId + "");
        wxUser.setUpdateTime(new Date());
        sysUserMapper.updateUser(wxUser);

        UserProfileDTO userProfileDTO = new UserProfileDTO();
        userProfileDTO.setUserType(ueerType);
        userProfileDTO.setUserId(userId + "");
        userProfileDTO.setPhoneNumber(phoneNum);
        userProfileDTO.setNickName(wxUser.getUserName());
        userProfileDTO.setAvatarUrl(wxUser.getAvatar());
        userProfileDTO.setGender(wxUser.getSex());

        return new UserProfileUpdateResponse(
                userProfileDTO
        );
    }

    @Override
    public UserProfileResponse getUserProfile(UserContext userContext, UserProfileRequest request) {
        SysUser currentUser = userContext.getCurrentUser();
        String ueerType = currentUser.getUserType();
        String username = currentUser.getUserName();
        Long userId = currentUser.getUserId();
        String avatar = currentUser.getAvatar();
        String sex = currentUser.getSex();
        String phonenumber = currentUser.getPhonenumber();


        UserProfileDTO userProfileDTO = new UserProfileDTO();
        userProfileDTO.setUserType(ueerType);
        userProfileDTO.setUserId(userId + "");
        userProfileDTO.setPhoneNumber(phonenumber);
        userProfileDTO.setNickName(username);
        userProfileDTO.setAvatarUrl(avatar);
        userProfileDTO.setGender(sex);

        return new UserProfileResponse(userProfileDTO);
    }

    @Override
    public UserAddressListResponse getUserAddressList(UserContext userContext, UserAddressRequest request) {

        UserAddress condAddress = new UserAddress();
        condAddress.setUserId(userContext.getCurrentUser().getUserId());
        condAddress.setUserAddressId(request.getUserAddressId());
        condAddress.setDelFlag(EDelFlag.NO.getVal());

        List<UserAddress> userAddressList = userAddressMapper.selectUserAddressList(condAddress);

        return new UserAddressListResponse(userAddressList);
    }

    @Override
    public UserAddressListResponse saveAddress(UserContext userContext, UserAddressRequest request) {

        if (EYesNo.YES.getVal().equals(request.getDefaultFlag())) {
            userAddressMapper.clearDefaultFlag(request.getUserId());
        }

        UserAddress userAddress = new UserAddress();

        userAddress.setUserAddressId(request.getUserAddressId());
        userAddress.setUserId(request.getUserId());
        userAddress.setMobile(request.getMobile());
        userAddress.setRecipient(request.getRecipient());
        userAddress.setProvince(request.getProvince());
        userAddress.setCity(request.getCity());
        userAddress.setDistrict(request.getDistrict());
        userAddress.setAddress(request.getAddress());
        userAddress.setDelFlag(request.getDefaultFlag());
        userAddress.setDelFlag(EDelFlag.NO.getVal());
        if (request.getUserAddressId() == null || request.getUserAddressId() == 0L) {
            userAddressMapper.insertUserAddress(userAddress);
        } else {
            userAddressMapper.updateUserAddress(userAddress);
        }

        UserAddress condAddress = new UserAddress();
        condAddress.setUserId(userContext.getCurrentUser().getUserId());
        condAddress.setDelFlag(EDelFlag.NO.getVal());

        List<UserAddress> userAddressList = userAddressMapper.selectUserAddressList(condAddress);

        return new UserAddressListResponse(userAddressList);
    }

}
