package cn.quantgroup.xyqb.controller.internal.user.center;

import cn.quantgroup.user.enums.*;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.limit.PasswordFreeAccessValidator;
import cn.quantgroup.xyqb.aspect.lock.RedisLock;
import cn.quantgroup.xyqb.entity.*;
import cn.quantgroup.xyqb.event.UserExtInfoSaveEvent;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.service.user.*;
import cn.quantgroup.xyqb.util.TenantUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by 11 on 2017/3/22.
 */
@Slf4j
@RestController
@RequestMapping("/user/center")
public class UserCenterController {

    @Autowired
    private UserCenterService userCenterService;
    @Autowired
    private IUserDetailService userDetailService;
    @Autowired
    private IUserExtInfoService userExtInfoService;
    @Autowired
    private IContactService contactService;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @GetMapping("/attach")
    public JsonResult queryUserAttach(Long userId) {
        if (userId == null) {
            return JsonResult.buildErrorStateResult("用户 ID 不能为空", null);
        }
        UserAttached userAttached = userCenterService.searchUserAttachedByUserId(userId);
        return JsonResult.buildSuccessResultGeneric(userAttached);
    }

    /**
     * @yapi http://yapi.quantgroups.com/project/17/interface/api/17291
     * @param userIds
     * @return
     */
    @PostMapping("/attach/list")
    public JsonResult queryUserAttachList(@RequestBody List<Long> userIds, @RequestParam(required = false) Integer tenantId) {
        //默认羊小咩租户
        if (TenantUtil.validationTenantIdIsNullOrZero(tenantId)) {
            tenantId = TenantUtil.TENANT_DEFAULT;
        }
        if (CollectionUtils.isEmpty(userIds)) {
            return JsonResult.buildErrorStateResult("用户 ID 不能为空", null);
        }
        int size = 500;
        if (userIds.size() > size) {
            return JsonResult.buildErrorStateResult("超出最大条数限制" + size, null);
        }
        List<UserAttached> userAttachedList = userCenterService.searchUserAttachedListByUserId(userIds, tenantId);
        return JsonResult.buildSuccessResultGeneric(userAttachedList);
    }


    /**
     * 根据用户手机号查询昵称.
     *
     * @param phoneNo
     * @return
     */
    @RequestMapping("/queryNick")
    @ApiOperation(value = "查询昵称", notes = "查询用户昵称", httpMethod = "POST")
    public JsonResult queryUserNick(String phoneNo) {
        if (StringUtils.isEmpty(phoneNo)) {
            log.error("手机号为空,phoneNo:{}", phoneNo);
            return JsonResult.buildErrorStateResult("参数不合法", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        UserAttached userAttached = userCenterService.searchUserAttachedByUserId(userId);
        if (null != userAttached) {
            log.info("获取用户昵称:{}", userAttached.getNick());
            return JsonResult.buildSuccessResult(null, userAttached.getNick());
        }
        return JsonResult.buildSuccessResult(null, null);
    }

    /**
     * 修改用户的昵称
     *
     * @param phoneNo
     * @param nick
     * @return
     */
    @RequestMapping("/saveNick")
    @ApiOperation(value = "保存昵称", notes = "保存用户昵称", httpMethod = "POST")
    public JsonResult saveUserNick(String phoneNo, String nick) {
        if (StringUtils.isEmpty(phoneNo)) {
            log.error("手机号为空,phoneNo:{}", phoneNo);
            return JsonResult.buildErrorStateResult("参数不合法", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        UserAttached userAttached = userCenterService.saveUserNick(userId, nick);
        return JsonResult.buildSuccessResult(null, userAttached.getNick());
    }

    /**
     * 上传后调用该接口保存用户头像
     *
     * @param phoneNo   用户手机号
     * @param avatarUrl 上传后生成的头像地址
     * @return
     */
    @RequestMapping("/save/avatar")
    @ApiOperation(value = "保存头像", notes = "保存用户头像", httpMethod = "POST")
    public JsonResult SaveUserAvatarAddr(String phoneNo, String avatarUrl) {
        if (StringUtils.isBlank(avatarUrl) || StringUtils.isBlank(phoneNo)) {
            log.error("参数不合法:avatarUrl:{}, phoneNo:{}", avatarUrl, phoneNo);
            return JsonResult.buildErrorStateResult("参数不合法", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        if (StringUtils.isBlank(avatarUrl)) {
            avatarUrl = Constants.UserAvatar.AVATAR_DEFAULT;
        }
        UserAttached userAttached = userCenterService.saveUserAvatar(userId, avatarUrl);
        if (null == userAttached) {
            log.error("保存用户头像昵称失败.");
            return JsonResult.buildErrorStateResult("信息保存失败,请稍后再试.", null);
        }
        return JsonResult.buildSuccessResult("保存成功", userAttached);
    }

    /**
     * 查询用户是否实名认证.
     *
     * @param phoneNo
     * @return
     */
    @RequestMapping("/query/verified")
    @ApiOperation(value = "查询用户是否实名认证", notes = "查询用户是否实名认证", httpMethod = "POST")
    public JsonResult queryVerified(String phoneNo) {
        if (StringUtils.isEmpty(phoneNo)) {
            log.error("手机号为空,phoneNo:{}", phoneNo);
            return JsonResult.buildErrorStateResult("参数不合法", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        UserDetail userDetail = userDetailService.findByUserId(userId);
        if (null != userDetail) {
            return JsonResult.buildSuccessResult(null, userDetail);
        }
        return JsonResult.buildSuccessResult(null, null);
    }


    /**
     * 个人资料信息
     *
     * @param phoneNo
     * @return
     */
    @PasswordFreeAccessValidator
    @RequestMapping("/personalData")
    @ApiOperation(value = "查询个人资料信息", notes = "查询个人资料信息", httpMethod = "POST")
    public JsonResult personalData(String phoneNo) {
        if (StringUtils.isBlank(phoneNo)) {
            log.error("手机号为空,phoneNo:{}", phoneNo);
            return JsonResult.buildErrorStateResult("参数不合法", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        UserExtInfo userExtInfo = userExtInfoService.findByUserId(userId);
        List<Contact> contacts = contactService.findByUserIdAndBizType(userId, BizType.CASH, true);
        Map<String, Object> result = new HashMap<>();
        if (null != userExtInfo) {
            result.put("contacts", null != contacts && contacts.size() > 0);
            result.put("occupation", userExtInfo.getOccupationEnum() == null ? "" : userExtInfo.getOccupationEnum().ordinal());
            result.put("education", userExtInfo.getEducationEnum() == null ? "" : userExtInfo.getEducationEnum().ordinal());
            result.put("income", userExtInfo.getIncomeRangeEnum() == null ? "" : userExtInfo.getIncomeRangeEnum().ordinal());
            result.put("marryStatus", userExtInfo.getMarryStatus() == null ? "" : userExtInfo.getMarryStatus().ordinal());
        }
        Address address = addressService.findByUserId(userId);
        if (null != address) {
            //用户住址信息,返回二级信息:
            result.put("address", address.getAddress());
            result.put("provinceCode", address.getProvinceCode());
            result.put("province", address.getProvince());
            result.put("cityCode", address.getCityCode());
            result.put("city", address.getCity());
            result.put("districtCode", address.getDistrictCode());
            result.put("district", address.getDistrict());
        }
        return JsonResult.buildSuccessResult(null, result);
    }

    /**
     * 保存用户联系人,
     *
     * @param phoneNo     用户手机号
     * @param contactJson 要保存的联系人json串
     * @return
     */
    @RequestMapping("/contacts/save")
    @ApiOperation(value = "保存用户联系人", notes = "保存用户联系人", httpMethod = "POST")
    public JsonResult saveUserContact(String phoneNo, String contactJson) {
        if (StringUtils.isEmpty(phoneNo)) {
            log.error("保存联系人,参数错误. phoneNo:{}", phoneNo);
            return JsonResult.buildErrorStateResult("参数有误.", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            log.error("保存联系人,未获取到用户id. userId:{}", userId);
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        if (StringUtils.isEmpty(contactJson)) {
            log.error("保存联系人,联系人参数为空.contactJson:{}", contactJson);
            return JsonResult.buildErrorStateResult(null, null);
        }
        List<Contact> contacts = JSONObject.parseObject(contactJson, new TypeReference<List<Contact>>() {
        });
        if (CollectionUtils.isEmpty(contacts)) {
            log.info("联系人不能空");
            return JsonResult.buildErrorStateResult(null, null);
        }
        for (Contact contact : contacts) {
            if (!contact.valid()) {
                log.info("用户手机号或姓名错误, phoneNo:{},name:{}", contact.getPhoneNo(), contact.getName());
                return JsonResult.buildErrorStateResult(null, null);
            }
        }
        List<Contact> result = contactService.save(userId, contacts);
        return JsonResult.buildSuccessResult(null, result);
    }

    /**
     * 保存用户住址信息
     *
     * @param province
     * @param provinceCode
     * @param city
     * @param cityCode
     * @param address
     * @return
     */
    @RequestMapping("/address/save")
    @ApiOperation(value = "保存用户地址", notes = "保存用户地址", httpMethod = "POST")
    public JsonResult saveUserAddress(String phoneNo, String province, Long provinceCode, String city, Long cityCode, String address,
                                      Long districtCode, String district) {
        log.info("保存用户地址信息, phoneNo:{}, province:{}, provinceCode:{}, city:{}, cityCode:{},district:{}, address:{}", phoneNo, province, provinceCode, city, cityCode, district, address);
        if (StringUtils.isEmpty(phoneNo) || provinceCode == null || cityCode == null || StringUtils.isBlank(address)) {
            return JsonResult.buildErrorStateResult("参数错误", null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            log.error("保存联系人,未获取到用户id. userId:{}", userId);
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        //查询用户是否有保存地址信息
        Address addressInfo = addressService.findByUserId(userId);
        if (null == addressInfo) {
            addressInfo = new Address();
        }
        addressInfo.setUserId(userId);
        addressInfo.setProvince(province);
        addressInfo.setProvinceCode(provinceCode);
        addressInfo.setCity(city);
        addressInfo.setCityCode(cityCode);
        addressInfo.setDistrictCode(districtCode);
        addressInfo.setDistrict(district);
        addressInfo.setAddress(address);
        addressService.save(addressInfo);
        return JsonResult.buildSuccessResult(null, addressInfo);
    }

    /**
     * 查询用户住址信息
     *
     * @param phoneNo
     * @return
     */
    @RequestMapping("/searchAddress/phoneNo")
    @ApiOperation(value = "查询用户地址", notes = "查询用户地址", httpMethod = "POST")
    public JsonResult searchUserAddress(String phoneNo) {
        if (StringUtils.isEmpty(phoneNo)) {
            return JsonResult.buildErrorStateResult(null, null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            log.error("保存联系人,未获取到用户id. userId:{}", userId);
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        Address address = addressService.findByUserId(userId);
        return JsonResult.buildSuccessResult(null, address);
    }

    /**
     * 查询用户联系人
     *
     * @param phoneNo
     * @return
     */
    @RequestMapping("/searchContacts/phoneNo")
    @ApiOperation(value = "查询用户联系人", notes = "查询用户联系人", httpMethod = "POST")
    public JsonResult searchUserContacts(String phoneNo) {
        if (StringUtils.isEmpty(phoneNo)) {
            return JsonResult.buildErrorStateResult(null, null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            log.error("保存联系人,未获取到用户id. userId:{}", userId);
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        List<Contact> contacts = contactService.findByUserIdAndBizType(userId, BizType.CASH, true);
        return JsonResult.buildSuccessResult(null, contacts);
    }

    /**
     * 保存用户经济信息
     *
     * @param educationEnum   学历
     * @param occupationEnum  职业
     * @param incomeRangeEnum 月收入范围
     * @param maritalStatus   婚姻状态
     * @return
     */
    @RequestMapping("/save/userExtInfo")
    @RedisLock(prefix = "lock:user:ext:", key = "#this[0]")
    @ApiOperation(value = "保存用户经济学历等信息", notes = "保存用户经济学历等信息", httpMethod = "POST")
    public JsonResult saveUserExtInfo(String phoneNo, EducationEnum educationEnum, MaritalStatus maritalStatus, IncomeRangeEnum incomeRangeEnum, OccupationEnum occupationEnum) {
        if (StringUtils.isEmpty(phoneNo)) {
            return JsonResult.buildErrorStateResult(null, null);
        }
        Long userId = queryUserId(phoneNo);
        if (null == userId || userId == 0L) {
            log.error("保存用户经济信息,未获取到用户id. userId:{}", userId);
            return JsonResult.buildErrorStateResult("该用户不存在", null);
        }
        //查询用户是否保存过.
        UserExtInfo userExtInfo = userExtInfoService.findByUserId(userId);
        if (null == userExtInfo) {
            userExtInfo = new UserExtInfo();
            userExtInfo.setUserId(userId);
        }
        if(null != educationEnum){
            userExtInfo.setEducationEnum(educationEnum);

        }
        if(null != maritalStatus){
            userExtInfo.setMarryStatus(maritalStatus);
        }
        //如果是学生那么转成其他
        if (null != occupationEnum) {
            if (OccupationEnum.STUDENT == occupationEnum) {
                occupationEnum = OccupationEnum.OTHER;
            }
        }
        if(null !=occupationEnum){
            userExtInfo.setOccupationEnum(occupationEnum);

        }if(null !=incomeRangeEnum){
            userExtInfo.setIncomeRangeEnum(incomeRangeEnum);
        }

        userExtInfo = userExtInfoService.save(userExtInfo);

        applicationEventPublisher.publishEvent(new UserExtInfoSaveEvent(this, userExtInfo));

        return JsonResult.buildSuccessResult(null, userExtInfo);
    }

    /**
     * 根据手机号查询用户id, nodejs调用接口无法获取到userId.
     * 所以增加该接口来查询用户id
     *
     * @param phoneNo
     * @return
     */
    private Long queryUserId(String phoneNo) {
        User user = userService.findByPhoneInDb(phoneNo);
        return null == user ? null : user.getId();
    }

    @GetMapping("/attach/listLimit/{id}")
    public JsonResult queryUserAttachListLimit(@PathVariable Long id) {
        //默认羊小咩租户
        List<UserAttached> userAttachedList = userCenterService.queryUserAttachListLimit(id);
        return JsonResult.buildSuccessResultGeneric(userAttachedList);
    }

}
