package com.crm.custom.controller;

import com.crm.custom.service.CustomInfoService;
import com.crm.login.rely.backend.controller.BaseLoginController;
import com.crm.rely.backend.core.constant.*;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.model.dto.custom.InfoDto;
import com.crm.rely.backend.model.dto.custom.login.CustomInfoAmountDto;
import com.crm.rely.backend.model.dto.user.info.UserInfoDto;
import com.crm.rely.backend.model.entity.custom.info.*;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.SysCountryService;
import com.crm.rely.backend.util.GetIpAndMac;
import com.crm.rely.backend.util.MD5Util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Locale;

/**
 * @author: houn
 */
@RestController
@RequestMapping("/custom")
public class CustomController extends BaseLoginController {


    @Autowired
    private CustomInfoService customInfoService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private SysCountryService sysCountryService;

    /**
     * 注册用户 发送短信验证码
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/register/send/code")
    public BaseResultDto registerSendCode(@RequestBody @Validated CustomInfoRegisterSendEmailCodeEntity entity, HttpServletRequest req) throws Exception {

        entity.setIp(GetIpAndMac.getIp(req));
        entity.setTime(new Date());
        customInfoService.registerSendEmailCode(entity);

        return BaseResultDto.success(Constants.SEND_SUCCESS);
    }

    /**
     * 注册用户
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/register")
    public BaseResultDto add(@RequestBody @Validated CustomInfoRegisterEntity entity) throws Exception {

        entity.setEmail(entity.getEmail().toLowerCase());

        //密码
        entity.setPassword(MD5Util.getMD5(entity.getPassword()));

        entity.setValid(1);
        entity.setStatus(StatusConstants.PASSED_STATUS);
        //entity.setPosition(CustomConstants.POSITION1);
        customInfoService.add(entity);

        return BaseResultDto.success(Constants.REGISTER_SUCCESS);
    }

    @PostMapping("/apply/real")
    public BaseResultDto applyReal(CustomInfoEntity infoEntity, HttpServletRequest httpServletRequest) throws Exception {
        Runnable runnable = () -> {

            CustomApplyRealEntity customApplyRealEntity = new CustomApplyRealEntity();
            customApplyRealEntity.setCustomId(infoEntity.getId());
            customApplyRealEntity.setApplyRealTime(new Date());
            CustomInfoTable customInfoTable = customInfoService.applyReal(customApplyRealEntity);

            infoEntity.setApplyRealStatus(customInfoTable.getApplyRealStatus());
            infoEntity.setStatus(customInfoTable.getStatus());
            infoEntity.setApplyRealTime(customInfoTable.getApplyRealTime());
            try {
                super.saveLoginInfo(infoEntity);
            } catch (Exception e) {
                e.printStackTrace();
            }
        };

        redisService.tryLock(infoEntity, httpServletRequest, runnable, "no_repeat_submit_error");

        return BaseResultDto.success();
    }

    /**
     * 修改邮件发送验证码
     *
     * @param entity
     * @param req
     * @return
     * @throws Exception
     */
    @PostMapping("/update/email/send/code")
    public BaseResultDto registerSendCode(@RequestBody @Validated CustomInfoUpdateEmailSendEmailCodeEntity entity, HttpServletRequest req, CustomInfoEntity infoEntity) throws Exception {

        if (!entity.getOldEmail().equals(infoEntity.getEmail())) {
            return BaseResultDto.error(Constants.LOGIN_EMAIL_ERROR);
        }

        entity.setCountry(infoEntity.getCountry());
        entity.setIp(GetIpAndMac.getIp(req));
        entity.setTime(new Date());

        customInfoService.updateEmailSendEmailCode(entity);

        return BaseResultDto.success(Constants.SEND_SUCCESS);
    }

    @PostMapping("/update/email")
    public BaseResultDto updateEmail(@RequestBody @Validated CustomInfoUpdateEmailEntity entity, HttpServletRequest req, CustomInfoEntity infoEntity) throws Exception {
        entity.setEmail(entity.getEmail().toLowerCase());
        entity.setOldEmail(entity.getOldEmail().toLowerCase());
        if (!entity.getOldEmail().equals(infoEntity.getEmail())) {
            return BaseResultDto.error(Constants.LOGIN_EMAIL_ERROR);
        }

        entity.setCustomId(infoEntity.getId());
        entity.setModifyIp(GetIpAndMac.getIp(req));
        entity.setModifyTime(new Date());
        entity.setModifyUser(infoEntity.getId());
        customInfoService.updateEmail(entity);

        //更新缓存上的信息
        infoEntity.setEmail(entity.getEmail());
        if (infoEntity.getIbInfo() != null) {
            infoEntity.getIbInfo().setEmail(entity.getEmail());
        }

        super.saveLoginInfo(infoEntity);
        return BaseResultDto.success(Constants.REGISTER_SUCCESS);
    }

    /**
     * 登录信息
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/login")
    public BaseResultDto login(@RequestBody @Validated CustomInfoLoginEntity entity, HttpServletRequest request, HttpServletResponse response) throws Exception {
        entity.setLoginName(entity.getLoginName().toLowerCase());
        //密码处理为
        entity.setPassword(MD5Util.getMD5(entity.getPassword()));

        /**
         * 处理登录时间 登录ip 登录地区
         */
        entity.setIp(sysCountryService.getAdderByIp(request));

        entity.setAddress(entity.getIp());
        entity.setTime(new Date());

        CustomInfoEntity infoEntity = customInfoService.login(entity);

        infoEntity.setPrefix(PrefixEnum.PREFIX_CUSTOM);

        String accessToken = super.login(infoEntity, entity.getSource());
        setLocaleResolver(infoEntity.getLang(), request, response);

        return BaseResultDto.success(Constants.LOGIN_SUCCESS, accessToken);
    }

    @PostMapping("/get/language")
    public BaseResultDto getLanguage(HttpServletRequest request) throws Exception {
        String language = request.getHeader("accept-language");
        return BaseResultDto.success(language);
    }

    /**
     * 退出登录
     *
     * @param httpServletRequest
     * @throws Exception
     */
    @Override
    @PostMapping("/logout")
    public BaseResultDto logout(HttpServletRequest httpServletRequest) throws Exception {

        return super.logout(httpServletRequest);
    }

    /**
     * 获取登录信息
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/info")
    public BaseResultDto info(CustomInfoEntity entity) throws Exception {

        InfoDto infoDto = new InfoDto();

        BeanUtils.copyProperties(entity, infoDto);

        if (entity.getIbInfo() != null) {
            UserInfoDto ibInfoDto = new UserInfoDto();
            BeanUtils.copyProperties(entity.getIbInfo(), ibInfoDto);
            infoDto.setIbInfo(ibInfoDto);
        } else {
            infoDto.setIbInfo(null);
        }
        //infoDto.setPosition(customInfoService.getPosition(entity.getId()));
        return BaseResultDto.success(infoDto);
    }

    @PostMapping("/get/amount")
    public BaseResultDto getAmount(CustomInfoEntity entity) throws Exception {

        CustomInfoAmountDto customInfoAmountDto = new CustomInfoAmountDto();

        CustomInfoTable customInfoTable = customInfoService.getById(entity.getId());
        BeanUtils.copyProperties(customInfoTable, customInfoAmountDto);
        return BaseResultDto.success(customInfoAmountDto);
    }

    /**
     * 修改用户信息,
     *
     * @param entity
     * @return
     * @throws Exception
     */
    @PostMapping("/update/info")
    public BaseResultDto update(@RequestBody @Validated CustomInfoUpdateEntity entity, HttpServletRequest req, CustomInfoEntity infoEntity) throws Exception {

        entity.setId(infoEntity.getId());
        entity.setModifyIp(sysCountryService.getAdderByIp(req));
        entity.setModifyTime(new Date());
        entity.setValid(1);
        customInfoService.update(entity);

        infoEntity.setValid(entity.getValid());
        //更新redis数据
        BeanUtils.copyProperties(entity, infoEntity);
        saveLoginInfo(infoEntity);

        return BaseResultDto.success();
    }

    @PostMapping("/manage/update/info")
    @FeignClientAnnotation
    public BaseResultDto manageUpdate(@RequestBody @Validated CustomInfoUpdateEntity entity, HttpServletRequest req) throws Exception {

        entity.setModifyIp(sysCountryService.getAdderByIp(req));
        entity.setModifyTime(new Date());
        entity.setValid(1);

        customInfoService.update(entity);

        CustomInfoEntity customInfoEntity =
                redisService.getEntity(PrefixEnum.PREFIX_CUSTOM.getCode() + entity.getId(), CustomInfoEntity.class);
        if (customInfoEntity != null) {
            BeanUtils.copyProperties(entity, customInfoEntity);
            saveLoginInfo(customInfoEntity);
        }

        return BaseResultDto.success();
    }

    /**
     * 登录修改密码
     *
     * @param entity
     * @param req
     * @param infoEntity
     * @return
     */
    @PostMapping("/update/login/password")
    public BaseResultDto updatePassword(@RequestBody @Validated CustomUpdateLoginPasswordEntity entity, HttpServletRequest req, CustomInfoEntity infoEntity) throws Exception {

        entity.setId(infoEntity.getId());
        if (entity.getNewPassword().equals(entity.getOldPassword())) {
            return BaseResultDto.error(Constants.PASSWORD_NEW_AND_OLD_IDENTICAL_ERROR);
        }

        entity.setModifyIp(sysCountryService.getAdderByIp(GetIpAndMac.getIp(req)));
        entity.setModifyTime(new Date());
        entity.setModifyUser(infoEntity.getId());
        entity.setNewPassword(MD5Util.getMD5(entity.getNewPassword()));
        entity.setOldPassword(MD5Util.getMD5(entity.getOldPassword()));

        customInfoService.updatePassword(entity);
        return BaseResultDto.success(Constants.UPDATE_SUCCESS);
    }

    /**
     * 未登录修改密码发送邮件
     *
     * @param entity
     * @param req
     * @return
     */
    @PostMapping("/update/password/send/email")
    public BaseResultDto updatePasswordSendEmail(@RequestBody @Validated CustomUpdatePasswordSendEmailEntity entity, HttpServletRequest req) throws Exception {
        String ip = GetIpAndMac.getIp(req);
        emailService.validate(ip, EmailSendEnum.FORGET_PASSWORD.getCode(), ip);

        entity.setIp(ip);
        entity.setTime(new Date());
        customInfoService.updatePasswordSendEmail(entity);

        return BaseResultDto.success(Constants.SEND_SUCCESS);
    }

    /**
     * 未登录根据邮件修改密码
     *
     * @param entity
     * @param req
     * @return
     */
    @PostMapping("/update/email/password")
    public BaseResultDto updatePassword(@RequestBody @Validated CustomUpdateEmailPasswordEntity entity, HttpServletRequest req) throws Exception {

        entity.setModifyIp(GetIpAndMac.getIp(req));
        entity.setModifyTime(new Date());
        entity.setPassword(MD5Util.getMD5(entity.getPassword()));

        customInfoService.updatePassword(entity);

        return BaseResultDto.success(Constants.SUCCESS);
    }

    @PostMapping("/manage/update/agent")
    @FeignClientAnnotation
    public BaseResultDto manageUpdateAgentId(@RequestBody @Validated CustomInfoUpdateAgentEntity entity) throws Exception {

        customInfoService.updateAgentId(entity);

        return BaseResultDto.success();
    }

    private void setLocaleResolver(String lang, HttpServletRequest request, HttpServletResponse response) {
        LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
        try {
            if ("cn".equals(lang)) {

                localeResolver.setLocale(request, response, new Locale("zh", "CN"));
            } else {
                localeResolver.setLocale(request, response, new Locale("en", "US"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/get/balance")
    public BaseResultDto balance(CustomInfoEntity infoEntity) throws Exception {

        BigDecimal balance = customInfoService.getBalance(infoEntity.getId());

        return BaseResultDto.success(balance);
    }

}
