package com.sdtool.webcore.rest;

import com.sdtool.common.api.LoginService;
import com.sdtool.common.api.SystemService;
import com.sdtool.common.api.mall.MallAdminService;
import com.sdtool.common.api.mall.MallFrontService;
import com.sdtool.common.base.BaseService;
import com.sdtool.common.datas.ERPHeader;
import com.sdtool.common.datas.HttpCode;
import com.sdtool.common.datas.TokenUserFrom;
import com.sdtool.common.entity.base.InvokeCallParams;
import com.sdtool.common.entity.base.InvokeCallResult;
import com.sdtool.common.entity.base.ProcessStringItem;
import com.sdtool.common.entity.mall.MallUser;
import com.sdtool.common.entity.site.ERPTokenUser;
import com.sdtool.common.entity.site.LoginRequest;
import com.sdtool.common.entity.site.LoginResult;
import com.sdtool.common.entity.system.AuthCode;
import com.dySweetFishPlugin.sql.RMapUtils;
import com.dySweetFishPlugin.tool.lang.DateUtil;
import com.sweetfish.net.http.*;
import com.sweetfish.service.Local;
import com.sweetfish.service.RetResult;
import com.sweetfish.util.AutoLoad;
import org.apache.commons.lang3.StringUtils;
import org.rex.RMap;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@AutoLoad(false)
@Local
@RestService(name = "mallFront", comment = "商城前端")
@SuppressWarnings({"rawtypes", "unused"})
public class MallFrontRest extends BaseService {

    @Resource
    MallFrontService mallFrontService;

    @Resource
    MallAdminService mallAdminService;

    @Resource
    LoginService loginService;

    @Resource
    SystemService systemService;

    @RestMapping(name = "login", sort = 1, comment = "登录", methods = {"POST"})
    public CompletableFuture<RMap> login(
            @RestParam(name = "user", comment = "登录人员信息，只需要账号和密码") LoginRequest bean,
            @RestParam(name = "supplierId", comment = "工厂id") long supplierId,
            @RestAddress(comment = "用户ip地址，不需传入") String clientIp,
            @RestHeader(name = ERPHeader.HTTPHEADER_USERFROM) String userFrom) {
        return CompletableFuture.supplyAsync(
                () -> {
                    if (bean == null) {
                        return RMapUtils.error(HttpCode.LOGIN_FAIL.value(), "用户账号或密码或三方身份信息错误，登录失败.");
                    }

                    if ((StringUtils.isEmpty(bean.getPassword())) && (StringUtils.isEmpty(bean.getSocialOpenId()))) {
                        //为安全，密码不允许为空
                        return RMapUtils.error(HttpCode.LOGIN_FAIL.value(), "用户账号或密码或三方身份信息错误，登录失败.");
                    }

                    if (StringUtils.isNotEmpty(bean.getSocialOpenId())) {
                        //由于商城小程序使用的是WebView嵌套网页的形式，但网页还是8060的，所以userFrom是失效的
                        bean.setLoginFrom(TokenUserFrom.MINI_MALL.getValue());
                    } else {
                        if (StringUtils.isEmpty(bean.getPassword())) {
                            //为安全，密码不允许为空
                            return RMapUtils.error(HttpCode.LOGIN_FAIL.value(), "用户账号或密码错误，登录失败.");
                        }

                        bean.setLoginFrom(Integer.parseInt(userFrom));
                    }

                    bean.setSupplierId(supplierId);

                    RetResult<LoginResult> loginResult = loginService.login(bean, clientIp);
                    if (!loginResult.isSuccess()) {
                        if (StringUtils.isNotEmpty(bean.getSocialOpenId())) {
                            //503给微信小程序专用
                            return RMapUtils.error(503, loginResult.getRetinfo());
                        } else {
                            return RMapUtils.error(HttpCode.LOGIN_FAIL.value(), loginResult.getRetinfo());
                        }
                    } else {
                        return RMapUtils.successV2(loginResult.getResult(), null, null);
                    }
                }, getExecutor()
        );
    }

    @RestMapping(name = "getCurrentMallUser", sort = 2, comment = "获取当前用户", methods = {"GET", "POST"})
    public CompletableFuture<RMap> getCurrentMallUser(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    Map<String, String> result = new HashMap<>();

                    if (currentUser == null) {
                        result.put("userAccount", "");
                        result.put("userName", "");
                        result.put("bindUserName", "");
                        result.put("balanceMoney", BigDecimal.ZERO.toPlainString());
                        result.put("expireMemo", "");
                        result.put("expireDate", "");
                    } else {
                        result.put("userAccount", currentUser.getAccount());
                        result.put("userName", currentUser.getUserName());
                        result.put("bindUserName", currentUser.getBindUserName());

                        //获取过期时间
                        MallUser mallUser = null;
                        if (currentUser.getUserFrom() == TokenUserFrom.MINI_MALL.getValue()) {
                            mallUser = mallAdminService.getRedisMallUser(currentUser.getIdBindOrg(), Long.parseLong(supplierCode));
                        } else {
                            mallAdminService.getRedisMallUser(currentUser.getId(), Long.parseLong(supplierCode));
                        }

                        if (mallUser == null || mallUser.getLevelExpireDateLong() <= 0L) {
                            result.put("expireMemo", "");
                            result.put("expireDate", "");
                        } else {
                            result.put("expireDate", DateUtil.dateToStr(new Date(mallUser.getLevelExpireDateLong()), "yyyy-MM-dd"));
                            LocalDateTime expiryDate = Instant.ofEpochMilli(mallUser.getLevelExpireDateLong())
                                    .atZone(ZoneId.systemDefault())
                                    .toLocalDate()
                                    .atStartOfDay();
                            LocalDateTime now = LocalDateTime.now().toLocalDate().atStartOfDay();

                            String expireMemo = expiryDate.isBefore(now) ? "已过期"
                                    : (ChronoUnit.DAYS.between(now, expiryDate) <= 30)
                                    ? "还有 " + ChronoUnit.DAYS.between(now, expiryDate) + " 天到期"
                                    : "";
                            result.put("expireMemo", expireMemo);
                        }
                    }
                    return RMapUtils.successV2(result, null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "mallFormToken", auth = true, sort = 10, comment = "请求token", methods = {"POST"})
    @SuppressWarnings("rawtypes")
    public CompletableFuture<RMap> mallFormToken(
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    String token = systemService.requestFormToken("mallFrontForm", Long.parseLong(supplierCode));
                    return RMapUtils.successV2(token, null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "callMall1", sort = 2, comment = "调用商城购物脚本-无需登录", methods = {"GET", "POST"})
    @WebApiFile(fileName = "mallFrontCall1.xml") // 此xml 注释无需登录接口
    public CompletableFuture<InvokeCallResult> callMall1(
            @RestBody(comment = "提交数据") InvokeCallParams callParams,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<InvokeCallResult> infoResult = mallFrontService.callMall(callParams, false, null, dataSourceId, Long.parseLong(supplierCode));
                    if (infoResult.isSuccess()) {
                        return infoResult.getResult();
                    } else {
                        if (infoResult.getRetcode() == HttpCode.UNAUTHORIZED.value()) {
                            return InvokeCallResult.error(HttpCode.UNAUTHORIZED.value(), infoResult.getRetinfo());
                        }
                        return InvokeCallResult.error(HttpCode.BAD_REQUEST.value(), infoResult.getRetinfo());
                    }
                }, getExecutor()
        );
    }

    @RestMapping(name = "callMall2", sort = 3, comment = "调用商城购物脚本-需登录", methods = {"GET", "POST"})
    @WebApiFile(fileName = "mallFrontCall2.xml") //此xml 注释需登录接口
    public CompletableFuture<InvokeCallResult> callMall2(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser,
            @RestBody(comment = "提交数据") InvokeCallParams callParams,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<InvokeCallResult> infoResult = mallFrontService.callMall(callParams, true, currentUser, dataSourceId, Long.parseLong(supplierCode));
                    if (infoResult.isSuccess()) {
                        return infoResult.getResult();
                    }
                    return InvokeCallResult.error(HttpCode.BAD_REQUEST.value(), infoResult.getRetinfo());
                }, getExecutor()
        );
    }

    //region 账号注册

    @RestMapping(name = "registerCaptchaImage", sort = 500, comment = "获取拼图验证码信息", methods = {"GET"})
    @WebApiBean(type = AuthCode.class, result = true)
    public CompletableFuture<RMap> registerCaptchaImage(
            @RestSessionid(create = true) String sessionId,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode,
            @RestHeader(name = ERPHeader.HTTPHEADER_USERFROM) String userFrom) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<AuthCode> authCodeResult = mallFrontService.generateAuthCode(sessionId, "register",
                            TokenUserFrom.getTokenUserFrom(Integer.parseInt(userFrom)), dataSourceId, Long.parseLong(supplierCode));
                    if (!authCodeResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), authCodeResult.getRetinfo());
                    } else {
                        return RMapUtils.successV2(authCodeResult.getResult(), null, null);
                    }
                });
    }

    @RestMapping(name = "registerCheckCaptcha", sort = 501, comment = "检查注册拼图验证码位置是否正确", methods = {"POST"})
    @WebApiBean(type = AuthCode.class, result = true)
    public CompletableFuture<RMap> registerCheckCaptcha(
            @RestSessionid(create = true) String sessionId,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<ProcessStringItem> checkResult = mallFrontService.checkPuzzleX(sessionId, "register", locationX, dataSourceId, Long.parseLong(supplierCode));
                    if (!checkResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), checkResult.getRetinfo());
                    } else {
                        return RMapUtils.success();
                    }
                });
    }

    @RestMapping(name = "registerSendSms", sort = 502, comment = "注册发短信接口", methods = {"POST"})
    public CompletableFuture<RMap> registerSendSms(
            @RestSessionid(create = false) String sessionId,
            @RestParam(name = "phone", comment = "注册的手机号码") String phone,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<ProcessStringItem> checkResult = mallFrontService.regSendSms(sessionId, phone, locationX, dataSourceId, Long.parseLong(supplierCode));
                    if (!checkResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), checkResult.getRetinfo());
                    } else {
                        return RMapUtils.success();
                    }
                });
    }

    @RestMapping(name = "registerMallUser", auth = false, sort = 503, comment = "商城用户注册", methods = {"POST"})
    @WebApiBean(type = MallUser.class, result = true)
    public CompletableFuture<RMap> registerMallUser(
            @RestParam(name = "mallUser", comment = "注册主体信息", required = true) MallUser mallUser,
            @RestSessionid(create = true) String sessionId,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestParam(name = "sms", comment = "短信验证码") String sms,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<MallUser> result = mallFrontService.registerMallUser(mallUser, sessionId, locationX, sms, dataSourceId, Long.parseLong(supplierCode));
                    if (result.isSuccess()) {
                        //注册成功后，直接把token返回回去，方便直接登录(这个注册应该是注册后，需要登录，所以没返回token)
                        return RMapUtils.successV2(result.getResult(), null, null);
                    } else {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), result.getRetinfo());
                    }
                });
    }

    //endregion

    //region 忘记密码
    @RestMapping(name = "fwdCaptchaImage", sort = 505, comment = "获取忘记密码拼图验证码信息", methods = {"GET", "POST"})
    @WebApiBean(type = AuthCode.class, result = true)
    public CompletableFuture<RMap> fwdCaptchaImage(
            @RestSessionid(create = true) String sessionId,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode,
            @RestHeader(name = ERPHeader.HTTPHEADER_USERFROM) String userFrom) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<AuthCode> authCodeResult = mallFrontService.generateAuthCode(sessionId, "fwd", TokenUserFrom.getTokenUserFrom(Integer.parseInt(userFrom)), dataSourceId, Long.parseLong(supplierCode));
                    if (!authCodeResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), authCodeResult.getRetinfo());
                    } else {
                        return RMapUtils.successV2(authCodeResult.getResult(), null, null);
                    }
                }, getExecutor());
    }

    @RestMapping(name = "fwdCheckCaptcha", sort = 506, comment = "检查忘记密码拼图验证码位置是否正确", methods = {"POST"})
    @WebApiBean(type = AuthCode.class, result = true)
    public CompletableFuture<RMap> fwdCheckCaptcha(
            @RestSessionid(create = true) String sessionId,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<ProcessStringItem> checkResult = mallFrontService.checkPuzzleX(sessionId, "fwd", locationX, dataSourceId, Long.parseLong(supplierCode));
                    if (!checkResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), checkResult.getRetinfo());
                    } else {
                        return RMapUtils.success();
                    }
                }, getExecutor());
    }

    @RestMapping(name = "fwdSendSms", sort = 507, comment = "忘记密码发送短信验证码", methods = {"POST"})
    public CompletableFuture<RMap> fwdSendSms(
            @RestSessionid(create = true) String sessionId,
            @RestParam(name = "phone", comment = "手机号码") String phone,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<ProcessStringItem> checkResult = mallFrontService.fwdSendSms(sessionId, phone, locationX, dataSourceId, Long.parseLong(supplierCode));
                    if (!checkResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), checkResult.getRetinfo());
                    } else {
                        return RMapUtils.success();
                    }
                }, getExecutor());
    }


    @RestMapping(name = "fwdPassword", sort = 508, comment = "忘记登录密码操作，返回成功后，密码默认等于账号，可登录后进行修改", methods = {"POST"})
    public CompletableFuture<RMap> fwdPassword(
            @RestParam(name = "account", comment = "手机号") String account,
            @RestSessionid(create = true) String sessionId,
            @RestParam(name = "locationX", comment = "拼图块x位置") int locationX,
            @RestParam(name = "sms", comment = "短信验证码") String sms,
            @RestHeader(name = ERPHeader.HTTPHEADER_DATASOURCE) String dataSourceId,
            @RestHeader(name = ERPHeader.HTTPHEADER_SUPPLIER) String supplierCode) {
        return CompletableFuture.supplyAsync(
                () -> {
                    RetResult<ProcessStringItem> checkResult = mallFrontService.fwdPassword(account, sessionId, locationX, sms, dataSourceId, Long.parseLong(supplierCode));
                    if (!checkResult.isSuccess()) {
                        return RMapUtils.error(HttpCode.BAD_REQUEST.value(), checkResult.getRetinfo());
                    } else {
                        return RMapUtils.successV2(checkResult.getResult().getItemValue(), null, null);
                    }

                }, getExecutor());
    }

    //endregion
}
