package com.liangjian.dataplatform.member.controller;

import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.CustomServiceApi;
import com.jfinal.weixin.sdk.msg.in.InTextMsg;
import com.jfinal.weixin.sdk.msg.in.event.InFollowEvent;
import com.jfinal.weixin.sdk.msg.in.event.InMenuEvent;
import com.jfinal.weixin.sdk.msg.out.News;
import com.jfinal.weixin.sdk.msg.out.OutNewsMsg;
import com.liangjian.dataplatform.member.entity.po.secondary.*;
import com.liangjian.dataplatform.member.entity.po.elasticsearch.UserPointLog;
import com.liangjian.dataplatform.member.entity.po.secondary.WeixinUserInfo;
import com.liangjian.dataplatform.member.entity.po.tertiary.OrderProducts;
import com.liangjian.dataplatform.member.entity.po.tertiary.Orders;
import com.liangjian.dataplatform.member.entity.response.ResultObject;
import com.liangjian.dataplatform.member.entity.token.JwtTokenObject;
import com.liangjian.dataplatform.member.entity.token.WeixinJwtTokenGetter;
import com.liangjian.dataplatform.member.entity.vo.TransportTrace;
import com.liangjian.dataplatform.member.entity.vo.request.WeixinMessageInfo;
import com.liangjian.dataplatform.member.entity.vo.response.LevelAndGrowth;
import com.liangjian.dataplatform.member.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.dreamlu.weixin.annotation.WxMsgController;
import net.dreamlu.weixin.properties.DreamWeixinProperties;
import net.dreamlu.weixin.spring.DreamMsgControllerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * @Author: 黄子奇
 * @Date: 2019/11/12
 */
@WxMsgController("/weixin")
@RestController
@Api(value = "微信接口的控制器", tags = "Wechat", description = "微信接口的控制器")
public class WeixinController extends DreamMsgControllerAdapter {

    @Autowired
    private DreamWeixinProperties weixinProperties;
    @Autowired
    private IWeixinUserInfoService iWeixinUserInfoService;
    @Autowired
    private IMemIngProductService iMemIngProductService;
    @Autowired
    private IUserPointLogService iUserPointLogService;
    @Autowired
    private IUserGrowthLogService iUserGrowthLogService;
    @Autowired
    private IUserLevelService iUserLevelService;
    @Autowired
    private IQueryOrdersService iQueryOrdersService;
    @Autowired
    private ITransportQueryService iTransportQueryService;
    @Autowired
    private IOrderProductService iOrderProductService;

    @Autowired
    private IUserIngOrdersService iUserIngOrdersService;

    @Override
    protected void processInFollowEvent(InFollowEvent inFollowEvent) {
        String openid = inFollowEvent.getFromUserName();
        if(inFollowEvent.getEvent().equals(InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE)) {
            //取消关注的
            Optional<WeixinUserInfo> opt = iWeixinUserInfoService.findByOpenid(openid);
            opt.ifPresent(info -> {
                    info.setUnsubscribeTime( (int)(System.currentTimeMillis() / 1000) );
                    iWeixinUserInfoService.save(info);
            });
        } else {
            //关注的
            Optional<WeixinUserInfo> opt = iWeixinUserInfoService.findByOpenid(openid);
            opt.ifPresent(info -> {
                    info.setUnsubscribeTime(null);
                    info.setSubscribeTime((int)(System.currentTimeMillis() / 1000));
                    iWeixinUserInfoService.save(info);
            });
        }
    }

    @Override
    protected void processInTextMsg(InTextMsg inTextMsg) {
    }

    @Override
    protected void processInMenuEvent(InMenuEvent inMenuEvent) {
        String key = inMenuEvent.getEventKey();
        if("test_click".equals(key)) {
            String openid = inMenuEvent.getFromUserName();
            String url = "https://mem.360lj.com/weixin/index?openid="+openid;
            OutNewsMsg outNewsMsg = new OutNewsMsg(inMenuEvent);
            outNewsMsg.addNews(new News("测试链接", "测试链接-描述","https://image.360lj.com/portal/image/logo-png.png", url));
            render(outNewsMsg);
        }
    }

    @GetMapping("/index")
    @ApiOperation(value = "登陆首页", notes = "跳转就会去检查是否绑定，若绑定则返回用户信息，否则仅返回openid（用于后面绑定）")
    public ResultObject<String> indexAction(@RequestParam(required = false) String code, @RequestParam(required = false) String openid) {
        if(openid == null || openid.isEmpty() || openid.equals("null")) {
            openid = code;
        }
        if(openid == null || openid.isEmpty() || openid.equals("null")) {
            return ResultObject.error("openid/code未传递");
        }
        String oid = openid;


        Optional<WeixinUserInfo> opt = iWeixinUserInfoService.findByOpenid(oid);

        return opt.flatMap(weixinUserInfo ->
                iWeixinUserInfoService.encodeJwt(weixinUserInfo,IWeixinUserInfoService.WECHAT)
                        .map(i -> ResultObject.success("登陆成功", i))
        ).orElseGet(() -> {
            ResultObject<String> result = ResultObject.error("未绑定手机");
            result.setData(oid);
            return result;
        });
    }

    @GetMapping("/user")
    @ApiOperation("获取登陆用户的信息")
    public ResultObject<WeixinUserInfo> getUserInfo() {
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        } else {
            return ResultObject.success(jwtTokenObject.getObject());
        }
    }

    @PostMapping("/sendMsg")
    @ApiOperation(value = "微信发送消息")
    public ResultObject<ApiResult> sendMsg(@ApiParam(value = "要推送的消息", required = true) @RequestBody WeixinMessageInfo messageInfo) {
        String openid = messageInfo.getOpenid();
        String message = messageInfo.getMessage();
        ApiResult result = CustomServiceApi.sendText(openid, message);
        return ResultObject.success(result);
    }

    @GetMapping("/products")
    @ApiOperation("获取积分商品")
    public ResultObject<Page<MemIngProduct>> getProducts(@ApiParam(value = "页数", required = true) @RequestParam Integer page,
                                           @ApiParam(value = "每页数量", required = true) @RequestParam Integer size) {
        String openid = null;
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject != null) {
            openid = jwtTokenObject.getObject().getOpenid();
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
        }

        if(openid != null && !openid.isEmpty()) {
            return ResultObject.success(iMemIngProductService.queryProduct(openid,page - 1,size));
        } else if(secretPhone != null && !secretPhone.isEmpty()) {
            return ResultObject.success(iMemIngProductService.queryProductByPhone(secretPhone, page - 1, size));
        } else {
            return ResultObject.success("未登录",iMemIngProductService.queryProduct(page - 1, size));
        }
    }

    @GetMapping("/points")
    @ApiOperation("获取积分记录")
    public ResultObject<Page<UserPointLog>> getUserPoints(@ApiParam(value = "页数", required = true) @RequestParam Integer page,
                                                          @ApiParam(value = "每页数量", required = true) @RequestParam Integer size) {
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject != null) {
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
            return ResultObject.success(iUserPointLogService.queryBySecretPhone(secretPhone, page - 1, size));
        } else {
            return ResultObject.error("未登陆");
        }
    }

    @GetMapping("/point/desc")
    @ApiOperation("获取积分说明")
    public ResultObject<UserPointDesc> getUserPointDesc() {
        UserPointDesc desc = iUserPointLogService.getUserPointDesc();
        return ResultObject.success(desc);
    }

    @GetMapping("/growth")
    @ApiOperation("获取会员成长（等级信息)")
    public ResultObject<LevelAndGrowth> getLevelAndGrowth() {
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
             return ResultObject.error("未登录");
        } else {
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
        }

        Integer growthBalance = iUserGrowthLogService.getPointBalance(secretPhone);
        Optional<UserLevelUnit> levelUnit = iUserLevelService.getLevelIn(growthBalance);
        if(!levelUnit.isPresent()) {
            return ResultObject.error("发送错误，未获取到等级信息");
        } else {
            LevelAndGrowth res = new LevelAndGrowth();
            res.setBalance(growthBalance);
            res.setLevel(levelUnit.get());
            return ResultObject.success(res);
        }
    }

    @GetMapping("/levels")
    @ApiOperation("获取所有会员等级（会员权益里，通过先获取等级，在通过等级获取对应的商品）")
    public List<UserLevelUnit> getAllLevels() {
        return iUserLevelService.getAllLevelUnit();
    }

    @GetMapping("/products/by/level")
    @ApiOperation("根据会员等级获取商品")
    public Page<MemIngProduct> getProductByLevel(@ApiParam(value = "页数", required = true) @RequestParam Integer page,
                                                 @ApiParam(value = "每页数量", required = true) @RequestParam Integer size,
                                                 @ApiParam(value = "等级序号", required = true) @RequestParam String levelId) {
        return iMemIngProductService.queryByLevel(levelId, page - 1, size);
    }

    @GetMapping("/games/points/last")
    @ApiOperation("获取积分收取游戏的昨天数值")
    public ResultObject<UserPointLog> getGamesPointsLast() {
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        } else {
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
        }

        return Optional.ofNullable(iUserPointLogService.getLastDayLog(secretPhone))
                .map(i -> ResultObject.success(i))
                .orElseGet(() -> ResultObject.error("没有数据"));
    }

    @GetMapping("/games/points/list")
    @ApiOperation("获取积分收取游戏的昨天的产生值，列表")
    public ResultObject<List<UserPointLog>> getGamesPoints() {
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        } else {
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
        }

        return ResultObject.success(iUserPointLogService.getLastDayLogList(secretPhone));
    }

    @GetMapping("/orders")
    @ApiOperation("获取用户的订单信息(根据电话号码查得，实物订单等)")
    public ResultObject<Page<Orders>> getOrders(@ApiParam(value = "页数", required = true) @RequestParam Integer page,
                                  @ApiParam(value = "每页数量", required = true) @RequestParam Integer size,
                                  @ApiParam(value = "订单类型(全部：不传，待发货：1，待收货：2，已完成：3，其他可根据订单表orderStatus字段描述)") @RequestParam(required = false) Integer orderStatus) {
        String secretPhone = null;
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        } else {
            secretPhone = jwtTokenObject.getObject().getSecretPhone();
        }

        return ResultObject.success(iQueryOrdersService.queryBySecretPhoneAndStatus(secretPhone, orderStatus,page -1, size));
    }

    @GetMapping("/orders/transport")
    @ApiOperation("获取订单物流信息")
    public List<TransportTrace> getTransports(@ApiParam(value = "订单物流类型码", required = true) @RequestParam Integer deliveryType,
                                              @ApiParam(value = "订单快递编号", required = true) @RequestParam String shippingNo) {
        return iTransportQueryService.getTransportTrace(deliveryType, shippingNo);
    }

    @GetMapping("/orders/info")
    @ApiOperation("获取订单详细信息")
    public ResultObject<List<OrderProducts>> getOrdersInfo(@ApiParam(value = "订单编号", required = true) @RequestParam String orderCode) {
        //从ThreadLocal中获取登陆信息
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        } else {
            return ResultObject.success(iOrderProductService.queryByOrderCode(orderCode));
        }
    }

    @PostMapping("/decode")
    @ApiOperation("密文解密接口（需登陆）")
    public ResultObject<String> decode(@ApiParam(value = "密文字符串（放body）", required = true) @RequestBody String ciphertext) {
        JwtTokenObject<WeixinUserInfo> jwtTokenObject = WeixinJwtTokenGetter.UserInfo.get();
        if(jwtTokenObject == null) {
            return ResultObject.error("未登录");
        }

        String res = iWeixinUserInfoService.decodeStr(ciphertext);
        return ResultObject.success(res);
    }
}
