package cn.freemud.service.impl;

import cn.freemud.adapter.CollageOrderAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.entities.vo.CollageOrderRequestVo;
import cn.freemud.entities.vo.CollageOrderResponseVo;
import cn.freemud.entities.vo.CustomerInfoVo;
import cn.freemud.enums.ResponseResult;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.CollageOrderService;
import cn.freemud.utils.ResponseUtil;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CollageMemberStateType;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CollageMemberState;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CollageOrder;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CollageOrderDto;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.CollageOrderBaseServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: null.java
 * @Package
 * @Description: (用一句话描述该文件做什么)
 * @author: pegnfei.liu
 * @date: 2020-9-24
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */

@Service
public class CollageOrderServiceImpl implements CollageOrderService {
    @Autowired
    private CollageOrderAdapter collageOrderAdapter;
    @Autowired
    private CollageOrderBaseServiceImpl collageOrderBaseService;
    @Autowired
    private ShoppingCartCollageServiceImpl shoppingCartCollageService;


    /**
     * 查询拼单订单信息（拼单基础信息 拼单参与人列表）
     * @param request(partnerId shopId userId)
     * @return
     */
    @Override
    public BaseResponse queryCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 查询时需传入拼单创建人的userId，若上送字段为空时，默认查询当前登录人自己的拼单信息
        String currentUserId = this.getUserIdBySessionId(request.getSessionId());
        collageOrderDto.setCurrentUserId(currentUserId);
        // 若拼单发起人ID为空，则默认按当前用户查询
        if (StringUtils.isEmpty(request.getCreateCollageUserId())) {
            collageOrderDto.setCreateCollageUserId(currentUserId);
        }
        BaseResponse<CollageOrder> queryCollageOrderResponse = this.collageOrderBaseService.queryCollageOrder(collageOrderDto);
        CollageOrder collageOrder = queryCollageOrderResponse.getResult();

        // SDK查询订单返回非成功code或返回结果订单信息为空时，返回前端异常信息
        Optional.ofNullable(queryCollageOrderResponse).filter(resp -> (ResponseResult.SUCCESS.getCode().equals(resp.getCode()) && !ObjectUtils.isEmpty(collageOrder))).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_EXIST));

        // 现在改为同时可查询自己发起以及参与的拼单所以查询到拼单信息后，后续查询需要使用拼单hash的三要素信息继续查询
        collageOrderDto.setPartnerId(collageOrder.getPartnerId());
        collageOrderDto.setStoreId(collageOrder.getStoreId());
        collageOrderDto.setCreateCollageUserId(collageOrder.getCreateCollageUserId());

        CollageOrderResponseVo collageOrderResponseVo = new CollageOrderResponseVo();
        // 订单基础信息
        collageOrderResponseVo.setOrder(collageOrder);
        // 订单锁定状态
        collageOrderResponseVo.setLocked(this.collageOrderBaseService.isLockedCollageOrder(collageOrderDto).getResult());
        // 订单参与人列表信息 参与人昵称头像等信息放入加购人状态锁redis对象中 userId : MemberState
        List<CollageMemberState> collageMemberStateList = this.collageOrderBaseService.getCollageMemberState(collageOrderDto).getResult();

        if (null != collageMemberStateList && collageMemberStateList.size() > 0 && collageMemberStateList.stream().filter(member -> member.getUserId().equals(currentUserId)).count() > 0) {
            collageOrderResponseVo.setCollageMemberStateList(collageMemberStateList);
            // 未加购完毕人数统计
            collageOrderResponseVo.setShoppingMemberNum(collageMemberStateList.stream().filter(member -> member.getState() == CollageMemberStateType.SHOPPING.getValue()).collect(Collectors.toList()).size());

            return ResponseUtil.success(collageOrderResponseVo);
        } else {
            return ResponseUtil.error(ResponseResult.COLLAGE_MEMBER_NOT_ADD);
        }
    }

    /**
     * 创建拼单订单基础信息
     * @param request(partnerId shopId sessionId)
     * @return
     */
    @Override
    public BaseResponse createCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 根据sessionId查询对应登录用户信息
        CustomerInfoVo userInfo = this.getUserInfo(request.getSessionId());
        collageOrderDto.setCreateCollageUserId(userInfo.getMemberId());
        collageOrderDto.setCurrentUserId(userInfo.getMemberId());
        collageOrderDto.setNickName(userInfo.getNickName());
        collageOrderDto.setPhotoUrl(userInfo.getPhotoUrl());

        // 创建拼单订单基础缓存信息
        BaseResponse<CollageOrder> createCollageOrderResponse = this.collageOrderBaseService.createCollageOrder(collageOrderDto);

        // SDK创建订单返回非成功code时，返回前端异常信息
        Optional.ofNullable(createCollageOrderResponse).filter(resp -> ResponseResult.SUCCESS.getCode().equals(resp.getCode())).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_ALREADY_EXIST));

        CollageOrderResponseVo collageOrderResponseVo = new CollageOrderResponseVo();
        collageOrderResponseVo.setOrder(createCollageOrderResponse.getResult());
        return ResponseUtil.success(collageOrderResponseVo);
    }

    /**
     * 取消拼单订单，删除相关缓存信息
     * @param request
     * @return
     */
    @Override
    public BaseResponse cancelCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 根据sessionId查询对应登录用户信息
        collageOrderDto.setCreateCollageUserId(this.getUserIdBySessionId(request.getSessionId()));
        this.checkCollageOrderOwner(collageOrderDto);
        return this.collageOrderBaseService.clearCollageOrder(collageOrderDto);
    }

    /**
     * 删除拼单相关缓存信息
     * @param request
     * @return
     */
    @Override
    public BaseResponse clearCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 根据sessionId查询对应登录用户信息
        collageOrderDto.setCreateCollageUserId(this.getUserIdBySessionId(request.getSessionId()));
        this.checkCollageOrderOwner(collageOrderDto);
        return this.collageOrderBaseService.clearCollageOrder(collageOrderDto);
    }

    /**
     * 锁定拼单订单
     * @param request
     * @return
     */
    @Override
    public BaseResponse lockCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 根据sessionId查询对应登录用户信息
        collageOrderDto.setCreateCollageUserId(this.getUserIdBySessionId(request.getSessionId()));
        this.checkCollageOrderOwner(collageOrderDto);
        return this.collageOrderBaseService.lockCollageOrder(collageOrderDto);
    }

    /**
     * 解锁拼单订单
     * @param request
     * @return
     */
    @Override
    public BaseResponse unlockCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 根据sessionId查询对应登录用户信息
        collageOrderDto.setCreateCollageUserId(this.getUserIdBySessionId(request.getSessionId()));
        this.checkCollageOrderOwner(collageOrderDto);
        return this.collageOrderBaseService.unlockCollageOrder(collageOrderDto);
    }

    /**
     * 拼单参与人加购完毕
     * @param request
     * @return
     */
    @Override
    public BaseResponse readyCollageMemberState(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        collageOrderDto.setCurrentUserId(this.getUserIdBySessionId(request.getSessionId()));
        return this.collageOrderBaseService.readyCollageMemberState(collageOrderDto);
    }

    /**
     * 拼单参与人继续加购
     * @param request
     * @return
     */
    @Override
    public BaseResponse shoppingCollageMemberState(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        collageOrderDto.setCurrentUserId(this.getUserIdBySessionId(request.getSessionId()));
        return this.collageOrderBaseService.shoppingCollageMemberState(collageOrderDto);
    }

    /**
     * 根据sessionId查询登录用户的userId
     * @param sessionId
     * @return
     */
    private String getUserIdBySessionId(String sessionId) {
        return this.getUserInfo(sessionId).getMemberId();
    }

    /**
     * 根据sessionId查询登录用户信息
     * @param sessionId
     * @return
     */
    private CustomerInfoVo getUserInfo(String sessionId) {
        return this.shoppingCartCollageService.getCustomerInfoVo(sessionId);
    }

    /**
     * 查询当前拼单订单基础信息是否存在
     * @param collageOrderDto
     * @return
     */
    private Boolean isCollageOrderExist(CollageOrderDto collageOrderDto) {
        // 查询当前拼单订单基础信息是否存在
        return !ObjectUtils.isEmpty(this.collageOrderBaseService.queryCollageOrder(collageOrderDto).getResult());
    }

    /**
     * 拼单订单检查
     * @param collageOrderDto
     */
    private void checkCollageOrderOwner(CollageOrderDto collageOrderDto) {
        CollageOrder collageOrder = this.collageOrderBaseService.queryCollageOrderByCreateCollageUserId(collageOrderDto).getResult();
        // 拼单订单信息不存在时，返回错误提示
        Optional.ofNullable(collageOrder).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_EXIST));
        // 若当前操作人并非拼单邀请人时，返回错误提示 当前用户不是拼单发起人，无法操作
        Optional.ofNullable(collageOrder).map(CollageOrder::getCreateCollageUserId).filter(userId -> userId.equals(collageOrderDto.getCreateCollageUserId())).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_OWNER));
    }


    /**
     * 加入拼单订单
     * @param request(partnerId shopId sessionId)
     * @return
     */
    @Override
    public BaseResponse addCollageOrder(CollageOrderRequestVo request) {
        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);

        CustomerInfoVo userInfo = this.getUserInfo(request.getSessionId());

        // 设置当前登陆用户
        collageOrderDto.setCurrentUserId(this.getUserIdBySessionId(request.getSessionId()));

        // 设置拼单发起人
        collageOrderDto.setCreateCollageUserId(request.getCreateCollageUserId());
        collageOrderDto.setNickName(userInfo.getNickName());
        collageOrderDto.setPhotoUrl(userInfo.getPhotoUrl());

        // 校验拼单是否存在
        CollageOrder collageOrder = this.collageOrderBaseService.queryCollageOrderByCreateCollageUserId(collageOrderDto).getResult();
        // 拼单订单信息不存在时，返回错误提示
        Optional.ofNullable(collageOrder).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_EXIST));

        // 判断当前登陆用户是否参加过当前店铺其他的拼团
        // 因为一个用户在一个商户下只能参加一个拼单，所以通过判断用户在商户下的拼单结束时间确认
        Boolean flag = collageOrderBaseService.isInCollagePartnerMemberList(collageOrderDto);
        if(flag){
            throw new ServiceException(ResponseResult.COLLAGE_MEMBER_ALREADY_ADD);
        }

        // 设置用户的点餐位
        collageOrderBaseService.setCollageMember(collageOrderDto);

        // 设置参加拼团人员信息
        String collageMemberStateHashKey = collageOrderBaseService.genCollageMemberStateHashKey(collageOrderDto.getPartnerId(), collageOrderDto.getStoreId(), collageOrderDto.getCreateCollageUserId());
        collageOrderBaseService.addCollageMemberState(collageMemberStateHashKey, collageOrderDto);

        // 设置用户在该商户下拼单参与列表记录
        collageOrderBaseService.setCollagePartnerMember(collageOrderDto);

        return ResponseUtil.success();
    }

    /**
     * 退出拼单订单
     * @param request(partnerId shopId sessionId)
     * @return
     */
    @Override
    public BaseResponse outOfOrder(CollageOrderRequestVo request) {

        // 获取当前登陆用户信息
        CustomerInfoVo currentUserInfoVo = this.shoppingCartCollageService.getCustomerInfoVo(request.getSessionId());
        // 当前用户必须登陆
        if (StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 设置当前登陆用户
        collageOrderDto.setCurrentUserId(currentUserInfoVo.getMemberId());
        // 设置拼单发起人
        collageOrderDto.setCreateCollageUserId(request.getCreateCollageUserId());

        // 校验拼单是否存在
        CollageOrder collageOrder = this.collageOrderBaseService.queryCollageOrderByCreateCollageUserId(collageOrderDto).getResult();
        // 拼单订单信息不存在时，返回错误提示
        Optional.ofNullable(collageOrder).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_EXIST));

        // 拼单发起人不能退出拼单
        if(collageOrder.getCreateCollageUserId().equals(currentUserInfoVo.getMemberId())){
            throw new ServiceException(ResponseResult.COLLAGE_CREATE_NOT_OUT_OF);
        }

        // 非邀请人检查是否参加了该邀请人的订单
        BaseResponse judge = collageOrderBaseService.judgeMemberAddOneCollage(collageOrderDto);
        if(!ResponseResult.SUCCESS.getCode().equals(judge.getCode())){
            throw new ServiceException(ResponseResult.COLLAGE_MEMBER_NOT_ADD);
        }

        try {
            this.removeMemberData(collageOrderDto);
        } catch (Exception e) {
            ResponseUtil.error(ResponseResult.SYSTEM_ERROR);
        }

        return ResponseUtil.success();
    }

    @Override
    public BaseResponse removeMember(CollageOrderRequestVo request) {
        // 获取当前登陆用户信息
        CustomerInfoVo currentUserInfoVo = this.shoppingCartCollageService.getCustomerInfoVo(request.getSessionId());
        // 当前用户必须登陆
        if (StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        // 只有拼单发起者才能移除拼单人员
        if(!currentUserInfoVo.getMemberId().equals(request.getCreateCollageUserId())){
            throw new ServiceException(ResponseResult.COLLAGE_MEMBER_NOT_CREATE);
        }

        // 不能移除自己
        if(currentUserInfoVo.getMemberId().equals(request.getRemoveUserId())){
            throw new ServiceException(ResponseResult.COLLAGE_CAN_NOT_REMOVE_SELF);
        }

        CollageOrderDto collageOrderDto = this.collageOrderAdapter.convert2CollageOrderDto(request);
        // 设置移除拼单用户ID
        collageOrderDto.setCurrentUserId(request.getRemoveUserId());
        // 设置拼单发起人
        collageOrderDto.setCreateCollageUserId(request.getCreateCollageUserId());

        // 校验拼单是否存在
        CollageOrder collageOrder = this.collageOrderBaseService.queryCollageOrderByCreateCollageUserId(collageOrderDto).getResult();
        // 拼单订单信息不存在时，返回错误提示
        Optional.ofNullable(collageOrder).orElseThrow(() -> new ServiceException(ResponseResult.COLLAGE_NOT_EXIST));

        try {
            this.removeMemberData(collageOrderDto);
        } catch (Exception e) {
            ResponseUtil.error(ResponseResult.SYSTEM_ERROR);
        }

        return ResponseUtil.success();

    }

    /**
     * 移除拼单人员的相关数据
     * @param collageOrderDto
     * @throws Exception
     */
    private void removeMemberData(CollageOrderDto collageOrderDto) throws Exception {

        List<String> cartLineIds = collageOrderBaseService.getMemCarLine(collageOrderDto);

        // 删除用户购物车行数据
        if(cartLineIds != null && !cartLineIds.isEmpty()){
            collageOrderDto.setCartLines(cartLineIds);
            collageOrderBaseService.cleanMemberCartLine(collageOrderDto);
        }

        // 删除点餐位
        collageOrderBaseService.cleanMemberSeat(collageOrderDto);

        // 删除用户选好了状态
        collageOrderBaseService.cleanMemberStates(collageOrderDto);

        // 删除用户在该店铺的拼单参与记录
        collageOrderBaseService.cleanCollagePartnerMember(collageOrderDto);
    }



}
