package com.liquidnet.service.adam.controller.web.administration;

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.common.exception.constant.ErrorCode;
import com.liquidnet.common.swagger.config.SwaggerApiVersion;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.ResponseDto;
import com.liquidnet.service.adam.common.AdamErrorCode;
import com.liquidnet.service.adam.config.swagger.AdamSwaggerApiVersionConstant;
import com.liquidnet.service.adam.constant.AdamAdminisConstants;
import com.liquidnet.service.adam.constant.AdamRedisConstants;
import com.liquidnet.service.adam.dto.AdamMyProfileParam;
import com.liquidnet.service.adam.dto.base.AdamCurrentUser;
import com.liquidnet.service.adam.entity.AdamUser;
import com.liquidnet.service.adam.interceptor.annotation.RequiresPermissions;
import com.liquidnet.service.adam.service.IAdamAdminisProcessHisService;
import com.liquidnet.service.adam.service.IAdamUserService;
import com.liquidnet.service.adam.service.sys.IAdamSysMessageService;
import com.liquidnet.service.adam.service.sys.IAdamSystemService;
import com.liquidnet.service.adam.util.CurrentUserUtil;
import com.liquidnet.service.adam.vo.AdamUserProfileVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

@Slf4j
@Api(tags = "My Profile")
@RestController
@RequestMapping("adam-user-profile")
public class AdamUserProfileController {
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IAdamUserService adamUserService;

    @Autowired
    private IAdamSysMessageService adamSysMessageService;

    @Autowired
    private IAdamSystemService adamSystemService;

    @Autowired
    private IAdamAdminisProcessHisService adamAdminisProcessHisService;

    @RequiresPermissions("FE3FC5E2")
    @ApiOperation(value = "Details for my profile")
    @SwaggerApiVersion(group = AdamSwaggerApiVersionConstant.WEB_1_2)
    @GetMapping("details")
    public ResponseDto<AdamUserProfileVo> details(HttpServletRequest request) {
        AdamUserProfileVo vo = new AdamUserProfileVo();
        try {
            AdamCurrentUser currentUser = CurrentUserUtil.getCurrentUser(request);

            vo = adamUserService.queryByUserId(currentUser.getId(), AdamAdminisConstants.ProcessHisTagEnum.MY_PROFILE.val, 1, 5);
        } catch (Exception e) {
            log.error("err:adam-user-profile/details", e);
        }
        return ResponseDto.success(vo);
    }

    @RequiresPermissions("FE3FC5E2")
    @ApiOperation(value = "Send phone verification code")
    @SwaggerApiVersion(group = AdamSwaggerApiVersionConstant.WEB_1_2)
    @PostMapping("send_p_vc")
    public ResponseDto<?> sendPVC(HttpServletRequest request) {
        try {
            AdamCurrentUser currentUser = CurrentUserUtil.getCurrentUser(request);

            String redisKey = AdamRedisConstants.USER_CONFIRM_SMS_CODE_KEY.concat(currentUser.getId())
                    .concat(":").concat(currentUser.getPhoneCode()).concat(":").concat(currentUser.getPhoneNumber());
            if (StringUtils.isEmpty(redisUtil.get(redisKey))) {
                return ResponseDto.failure(AdamErrorCode.ADAM001_VERIFYCODE_SENT.getCode(), AdamErrorCode.ADAM001_VERIFYCODE_SENT.getVal());
            }

            String verifyCode = adamSystemService.generateVerifyCode();
            String msgByTemplate = "Verification code: ".concat(verifyCode);
            log.info("Change phone number to send:[{}]", msgByTemplate);

            redisUtil.set(redisKey, verifyCode, TimeUnit.MINUTES.toSeconds(2));

            // TODO: 2020/12/3 zhanggb:by template
            adamSysMessageService.asyncSendMessage(msgByTemplate, currentUser.getPhoneCode().concat(currentUser.getPhoneNumber()));
        } catch (BeansException e) {
            log.error("err:adam-user-profile/send_p_vc", e);
            return ResponseDto.failure(ErrorCode.RESPONSE_ERROE_SYSTEM);
        }
        return ResponseDto.success();
    }

    @RequiresPermissions("FE3FC5E2")
    @ApiOperation(value = "Update basic profile")
    @SwaggerApiVersion(group = AdamSwaggerApiVersionConstant.WEB_1_2)
    @PostMapping("basic_up_do")
    public ResponseDto<?> basicUpDo(HttpServletRequest request, @ModelAttribute AdamMyProfileParam parameter) {
        try {
            if (StringUtils.isEmpty(parameter.getFirstName()) || StringUtils.isEmpty(parameter.getLastName())) {
                return ResponseDto.failure(AdamErrorCode.NAME_LOST.getCode(), AdamErrorCode.NAME_LOST.getVal());
            }
            if (StringUtils.isEmpty(parameter.getJobTitle())) {
                return ResponseDto.failure(AdamErrorCode.JOB_TITLE_LOST.getCode(), AdamErrorCode.JOB_TITLE_LOST.getVal());
            }
            if (StringUtils.isEmpty(parameter.getPhoneCode())) {
                return ResponseDto.failure(AdamErrorCode.ADAM001_PARAM_ERROR.getCode(), AdamErrorCode.ADAM001_PARAM_ERROR.getVal().concat(":phone code"));
            }
            if (StringUtils.isEmpty(parameter.getPhoneNumber())) {
                return ResponseDto.failure(AdamErrorCode.ADAM001_PARAM_ERROR.getCode(), AdamErrorCode.ADAM001_PARAM_ERROR.getVal().concat(":phone number"));
            }
            String redisKey = null;
            AdamCurrentUser currentUser = CurrentUserUtil.getCurrentUser(request);
            if (!currentUser.getPhoneCode().equals(parameter.getPhoneCode()) || !currentUser.getPhoneNumber().equals(parameter.getPhoneNumber())) {
                if (StringUtils.isEmpty(parameter.getVerifyCode())) {
                    return ResponseDto.failure(AdamErrorCode.ADAM001_VERIFYCODE_ERROR.getCode(), AdamErrorCode.ADAM001_VERIFYCODE_ERROR.getVal());
                }
                redisKey = AdamRedisConstants.USER_CONFIRM_SMS_CODE_KEY.concat(currentUser.getId())
                        .concat(":").concat(currentUser.getPhoneCode()).concat(":").concat(currentUser.getPhoneNumber());
                Object o = redisUtil.get(redisKey);
                if (StringUtils.isEmpty(o)) {
                    return ResponseDto.failure(AdamErrorCode.ADAM001_VERIFYCODE_EXPIRED.getCode(), AdamErrorCode.ADAM001_VERIFYCODE_EXPIRED.getVal());
                }
                if (!parameter.getVerifyCode().equals(o)) {
                    return ResponseDto.failure(AdamErrorCode.ADAM001_VERIFYCODE_ERROR.getCode(), AdamErrorCode.ADAM001_VERIFYCODE_ERROR.getVal());
                }
            }

            AdamUser updateObj = new AdamUser();
            BeanUtils.copyProperties(parameter, updateObj);
            updateObj.setId(currentUser.getId());
            boolean updateFailed = adamUserService.updateById(updateObj) <= 0;

            if (!updateFailed && !StringUtils.isEmpty(redisKey)) {
                redisUtil.del(redisKey);
            }
            if (!updateFailed) {// Record process history
                adamAdminisProcessHisService.record(AdamAdminisConstants.ProcessHisEnum.MY_PROFILE_CHANGE_BP, null,
                        new String[]{currentUser.getComId(), currentUser.getId(), currentUser.getId(), currentUser.getName()});
            }

            return updateFailed ? ResponseDto.failure(ErrorCode.RESPONSE_ERROE_BIZ) : ResponseDto.success();
        } catch (Exception e) {
            log.error("err:adam-user-profile/basic_up_do:parameter:{}", JsonUtils.toJson(parameter), e);
            return ResponseDto.failure(ErrorCode.RESPONSE_ERROE_SYSTEM);
        }
    }

}
