package com.hzs.sale.order.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.hzs.common.domain.member.account.CuMemberAccount;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.ext.CuMemberAccountExt;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.domain.sale.ext.SaDeliverItemsExt;
import com.hzs.common.domain.sale.ext.SaOrderExt;
import com.hzs.common.domain.sale.ext.SaOrderItemsExt;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.sale.order.SaOrderItems;
import com.hzs.sale.deliver.param.DeliverSecondParam;
import com.hzs.sale.deliver.vo.DeliverSecondVO;
import com.hzs.sale.index.vo.CuMemberMyMarketVO;
import com.hzs.sale.order.param.*;
import com.hzs.sale.order.vo.*;
import com.hzs.system.config.dto.GradeDTO;
import com.hzs.system.sys.dto.ApprovalBusinessResultDTO;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 订单的service处理类
 */
public interface ISaOrderService extends IService<SaOrder> {

    /**
     * 验证手机号注册次数
     * 根据手机号查询出目前系统所有的会员
     *
     * @param cuMember 会员的各种属性、手机号码必输 国家
     */
    List<CuMemberExt> queryMemberExtByCondition(CuMember cuMember);

    /**
     * 查找安置人伞上
     *
     * @param placeParentId 安置人
     */
    List<CuMemberExt> querySponsorOnUmbrella(Long placeParentId, String phone);

    /**
     * 查找安置人伞下
     *
     * @param memberId 会员编号
     */
    List<CuMemberExt> selectPlaceSponsorUnderUmbrellaByCondition(Long memberId, List<CuMemberExt> cuMemberExtList);

    /**
     * 查找安置人伞下
     *
     * @param memberId 安置人，编号
     */
    List<CuMemberExt> queryPlaceSponsorUnderUmbrella(Long memberId, String placeParent);

    /**
     * 根据会员编号，查找该会员编号极左极下的那个人
     *
     * @param memberId  会员编号
     * @param placeDept 1代表左区极左极下，2代表右区极左极下
     */
    CuMemberExt queryPlaceSponsorLastLeft(Long memberId, Integer placeDept);

    /**
     * 根据订单编号查询订单
     *
     * @param saOrder 订单
     */
    SaOrder querySaleOrderByOrderCode(SaOrder saOrder);

    /**
     * 查询销售订单，携带订单表体
     *
     * @param saOrder    订单
     * @param itemIdList 订单明细主键
     */
    SaOrderExt querySaleOrderExtByOrderCode(SaOrder saOrder, List<Long> itemIdList);

    /**
     * 根据会员编号查找订单关系中订单信息,用于系统内部流转，不跟ui端交互
     *
     * @param pkCountry   国家
     * @param pkMember    会员编号
     * @param pkReference 推荐人编号
     * @param orderType   订单类型
     */
    List<SaOrder> querySaleOrderByPkMember(Integer pkCountry, Long pkMember, Long pkReference, Integer orderType);


    /**
     * 根据会员编号查找订单关系中订单信息,用于系统内部流转，不跟ui端交互
     *
     * @param pkCountry   国家
     * @param pkMember    会员编号
     * @param pkReference 推荐人编号
     */
    Integer querySaleOrderByPkMember(Integer pkCountry, Long pkMember, Long pkReference);

    /*
     *  查询网体是否存在推荐人
     **/
    Integer queryCuMemberByPkMember(Long pkReference);

    /**
     * 跟会员端进行交互的查询订单的方法
     *
     * @param orderQueryParam 交互参数
     */
    List<SaOrderVO> querySaleOrderByCondition(OrderQueryParam orderQueryParam);

    /**
     * 根据key值从redis中获取到会员信息
     *
     * @param pkId 会员主键
     */
    CuMember getCuMemberByKey(Long pkId);

    /**
     * 根据key值从redis中获取到会员信息
     *
     * @param code 会员编号
     */
    CuMember getCuMemberByCode(String code);

    /**
     * 加锁，将键锁定
     *
     * @param key 锁定的键
     */
    Boolean lockKey(String key);

    /**
     * 查询会员账户状态，账户信息
     *
     * @param cuMemberAccount 会员账户条件信息
     */
    List<CuMemberAccountExt> queryMemberAccountByCondition(CuMemberAccount cuMemberAccount);

    /**
     * 验证会员账户余额，是否够支付
     *
     * @param cuMemberAccount 会员账户
     * @param saOrder         订单信息
     */
    CuMemberAccountExt queryOrderSpendDetails(CuMemberAccountExt cuMemberAccount, SaOrder saOrder, List<SaOrderItems> orderItemList);

    /**
     * 点击确认订单按钮
     * 将会员端传递过来的保单信息封装为订单信息,待支付时直接入库，直接保存时先放入redis暂存，待支付时在保存入库
     *
     * @param orderParam 会员端的报单信息
     */
    Boolean confirmRegSaOrderByOrderParam(OrderParam orderParam);

    /*
     *  确认嗨粉订单根据参数
     **/
    Boolean confirmSelfFunOrderByOrderParam(OrderParam orderParam);

    /**
     * 封装需要保存的销售订单和会员
     *
     * @param orderParam 前台参数
     * @param cuMember   会员
     */
    SaOrderExt packageSaOrder(OrderParam orderParam, CuMember cuMember);

    /**
     * 封装需要保存的销售订单和会员
     *
     * @param orderParam 前台参数
     */
    CuMember packageCuMember(OrderParam orderParam);

    /*
     *  这是会员等级
     **/
    Boolean setLastCuMemberGrade(CuMember cuMember, SaOrder saOrderExt);

    /**
     * 点击支付按钮，输入密码，确认下单(注册订单)
     *
     * @param saOrderExt         订单
     * @param newCuMember        新会员信息
     * @param cuMemberAccountExt 支付账户信息
     * @param isHaiFun           是否嗨粉
     */
    Boolean payRegSaOrder(SaOrderExt saOrderExt, CuMember newCuMember,
                          CuMemberAccountExt cuMemberAccountExt, Boolean isHaiFun);

    /**
     * 支付升级订单
     *
     * @param saOrderExt         订单信息
     * @param cuMemberAccountExt 会员账户
     */
    Boolean payUpgradeSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt);

    /**
     * 生成升级待支付订单
     *
     * @param orderParam 参数信息
     */
    Boolean confirmRepurchaseSaOrder(OrderParam orderParam);

    /*
     *  生成新人礼包
     **/
    Boolean confirmNewPeopleGift(OrderParam orderParam);

    /**
     * 支付复购订单
     *
     * @param saOrderExt         订单
     * @param cuMemberAccountExt 会员账户
     */
    Boolean payRepurchaseSaOrder(SaOrderExt saOrderExt, CuMemberAccountExt cuMemberAccountExt);

    /**
     * 订单以及明细入库等处理
     *
     * @param saOrderExt 订单（带明细）
     */
    void processOrder(SaOrderExt saOrderExt);

    /**
     * 是否直接支付
     *
     * @param pkCountry   国家
     * @param specialArea 所属专区
     */
    boolean getIsToBePayByOrderType(Integer pkCountry, Integer specialArea);

    /**
     * 是否直接支付,待支付查询出剩余最大支付时间秒数
     *
     * @param pkCountry   国家
     * @param specialArea 所属专区
     */
    Long getIsToBePayTime(Integer pkCountry, Integer specialArea);

    /**
     * 查询邮费
     *
     * @param orderParam 前台传递的参数
     */
    void queryPostageByParam(OrderParam orderParam);

    /**
     * 计算会员等级
     *
     * @param orderParam 商品列表、专区
     */
    OrderReturn computeLevel(OrderParam orderParam);

    /**
     * 根据订单编号执行订单撤销操作
     *
     * @param pkApprove             审核人
     * @param orderCancelParam      撤单参数
     * @param validateCancelOrderVO 订单
     */
    void revokeSaOrderByOrderCode(Long pkApprove, OrderCancelParam orderCancelParam, ValidateCancelOrderVO validateCancelOrderVO);

    /**
     * 根据等级主键查询等级
     *
     * @param pkCountry 国家
     * @param pkGrade   等级
     */
    GradeDTO queryGradeConfigByCondition(Integer pkCountry, Integer pkGrade);

    /**
     * 根据推荐人获取极左极下最末安置人
     *
     * @param cuMember       会员 需要放(推荐人、国家、新用户姓名、新用户手机号)
     * @param isFirstAchieve 是否验证首购业绩
     */
    CuMember obtainLastResettleByRecommend(CuMember cuMember, Boolean isFirstAchieve, Boolean isFirst);

    /**
     * 生成空单注册
     *
     * @param orderBlankRegParams 参数
     */
    String registerEmptyOrder(OrderBlankRegParams orderBlankRegParams);

    /**
     * 验证是否必须有首单
     * 验证第二部门是否需要验证首单
     *
     * @param pkParent  推荐人主键
     * @param pkCountry 国家
     */
    boolean validateFirstOrder(Long pkParent, Integer pkCountry);

    /**
     * 查询时间范围内的订单，需要查询出del_flag = 1的值
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     */
    List<SaOrderExt> querySaOrderByTime(Date startDate, Date endDate, String orderCode);

    /**
     * 查询有效时间范围内的订单,用于查询个人之前买过的订单用于计算加权积分分红
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     */
    List<SaOrderExt> querySaOrderByEffectiveDay(Date startDate, Date endDate);

    /**
     * 查询有效时间范围内的订单,用于查询个人之前买过的订单用于计算计算店铺收益
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     */
    List<SaOrderExt> queryDeliverySaOrderByDay(Date startDate, Date endDate);

    /**
     * 获取系统参数
     *
     * @param pkCountry 国家
     * @param key       键
     */
    String querySystemConfigByKey(Integer pkCountry, String key);

    /**
     * 查询销售总金额
     *
     * @return
     */
    BigDecimal selectSum();

    /**
     * 根据订单id查询订单
     *
     * @param pkId      订单ID（必传）
     * @param pkCountry 所属国家（非必传）
     * @return
     */
    SaOrderExt queryOrderByPkId(Long pkId, Integer pkCountry);

    /**
     * 根据订单编号查询订单
     *
     * @param orderCode 订单编号（必传）
     * @param pkCountry 所属国家（非必传）
     * @return
     */
    SaOrderExt queryOrderByCode(String orderCode, Integer pkCountry);

    /**
     * 根据订单编号批量查询订单以及详情
     *
     * @param orderCodeList 订单编号列表（必传）
     * @param pkCountry     所属国家（非必传）
     * @return
     */
    List<SaOrderExt> queryOrderListByCodeList(List<String> orderCodeList, Integer pkCountry);

    /**
     * 根据订单ID批量查询订单以及详情
     *
     * @param orderIdList 订单ID列表（必传）
     * @param pkCountry   所属国家（非必传）
     * @return
     */
    List<SaOrderExt> queryOrderListByIdList(List<Long> orderIdList, Integer pkCountry);

    /**
     * 我的订单列表
     *
     * @param param     查询参数
     * @param memberId
     * @param pkCountry
     * @return
     */
    List<SaOrderExt> myOrderList(MyOrderParam param, Long memberId, Integer pkCountry);

    /**
     * 我的订单数量
     *
     * @param statusList 状态列表
     * @param memberId
     * @param pkCountry
     * @return
     */
    int myOrderNum(List<Integer> statusList, Long memberId, Integer pkCountry);

    /**
     * 我的订单确认收货
     *
     * @param pkOrder  订单ID
     * @param memberId 会员ID
     * @return
     */
    boolean myOrderConfirm(Long pkOrder, Long memberId);

    /**
     * 我的订单取消订单
     *
     * @param saOrder  订单
     * @param memberId 会员ID
     * @return
     */
    String myOrderCancel(SaOrder saOrder, Long memberId);

    /**
     * 订单打印（前台）
     *
     * @param orderCode
     * @param memberId
     * @param pkCountry
     * @return
     */
    MyOrderPrintVO orderPrint(String orderCode, Long memberId, Integer pkCountry);

    /**
     * 订单业务列表
     *
     * @param param
     * @param pkCountry
     * @return
     */
    List<OrderBusinessVO> queryOrderBusinessList(OrderBusinessParam param, Integer pkCountry);

    /**
     * 删除订单以及详情
     *
     * @param orderIdList 订单ID列表
     * @param userId      操作用户ID
     * @param pkCountry   所属国家 -- 非必传
     */
    void deleteOrderAndItems(List<Long> orderIdList, Long userId, Integer pkCountry);

    /**
     * 商品订单信息
     *
     * @param waresOrderParam
     * @return
     */
    List<WaresOrderVo> selectByOrderInfoList(WaresOrderParam waresOrderParam);

    /**
     * 查询订单以及会员信息
     *
     * @param orderTypeList 订单类型列表（非必传）
     * @param pkMemberList  会员列表（非必传）
     * @param pkCountry     所属国家（非必传）
     * @return
     */
    List<SaOrderExt> queryOrderMemberInfo(List<Integer> orderTypeList, List<Long> pkMemberList, Integer pkCountry);

    /**
     * 查询选择订单列表
     *
     * @param param     查询参数
     * @param pkCountry 所属国家
     * @return
     */
    List<SaOrderItemsExt> queryOrderSelect(OrderSelectParam param, Integer pkCountry);

    /**
     * 空单注册审核通过
     *
     * @param approvalBusinessResultDTO
     * @return
     */
    Boolean regEmptyOrderApproved(ApprovalBusinessResultDTO approvalBusinessResultDTO);

    /**
     * 空单注册审核驳回
     *
     * @param approvalBusinessResultDTO
     * @return
     */
    Boolean regEmptyOrderReject(ApprovalBusinessResultDTO approvalBusinessResultDTO);

    /**
     * 定时关单  订单三十分钟未支付自动关闭
     */
    void closeOrder();

    /**
     * 统计用户pv
     *
     * @param startPayDate 开始支付时间
     * @param endPayDate   结束支付时间
     * @param memberId     会员id
     * @return
     */
    BigDecimal selectBySumPv(Date startPayDate, Date endPayDate, Long memberId);

    /**
     * 统计用户金额
     *
     * @param startPayDate 开始支付时间
     * @param endPayDate   结束支付时间
     * @param memberId     会员id
     * @return
     */
    BigDecimal selectBySumAmount(Date startPayDate, Date endPayDate, Long memberId);

    /**
     * 查询订单类型
     *
     * @param memberId  会员ID
     * @param pkCountry 所属国家
     * @return
     */
    List<Integer> queryOrderType(Long memberId, Integer pkCountry);

    /**
     * 商品销量累计
     */
    void waresSalesAccrual(List<WaresNumberParam> waresNumberParamList);

    /**
     * 二次发货列表
     *
     * @param param     查询参数
     * @param pkCountry 所属国家
     * @return
     */
    List<DeliverSecondVO> secondList(DeliverSecondParam param, Integer pkCountry);

    /**
     * 会员首页我的市场
     *
     * @param pkMember  用户ID
     * @param pkCountry 国家ID
     * @return
     */
    CuMemberMyMarketVO selectMyMarket(Long pkMember, Integer pkCountry);

    /**
     * 查询当天已支付订单信息
     **/
    List<SaOrder> querySaOrderByOrderType(String payTime);

    /*
     *  根据时间端查询订单累计业绩累计金额
     **/
    SaOrder queryOrderTotalAchieveByTime(Date startDate, Date endDate);

    /**
     * 查询指定数量会员SEQ
     *
     * @param param 数量
     * @return
     */
    List<Long> querySeqList(Integer param);

    /**
     * 批量插入订单数据
     *
     * @param orderList 订单列表
     * @return
     */
    int insertBach(List<SaOrder> orderList, List<SaOrderItems> orderItemsList);

    /**
     * 批量插入虚拟订单数据
     **/
    int insertUnrealOrderBach(List<SaOrder> orderList);

    /**
     * 查询会员店铺订单
     *
     * @param param
     * @param pkStore
     * @param pkCountry
     * @return
     */
    List<SaOrderExt> myStoreOrderList(MyOrderParam param, Integer pkStore, Integer pkCountry);

    /**
     * 保存订单信息返回ID
     *
     * @param saOrder    订单
     * @param orderItems 订单详情
     * @return Long
     */
    Long saveOrderInfo(SaOrder saOrder, SaOrderItems orderItems);

    /**
     * 查询升级金额以及业绩
     *
     * @param pkMember 会员ID
     * @return
     */
    SaOrderExt queryUpgradeAmountAndAchieve(Long pkMember);

    /**
     * 查询会员订单总业绩
     *
     * @param pkMember
     * @return
     */
    BigDecimal getMemberOrderAchieve(Long pkMember);

    /*
     *  根据发货单查询销售订单
     **/
    List<SaOrderExt> querySaOrderByDeliverList(List<SaDeliverItemsExt> deliverItemExtList);

    /**
     * 查询店铺
     *
     * @param statusList
     * @param pkStore
     * @param pkCountry
     * @return
     */
    int getStoreNum(List<Integer> statusList, Integer pkStore, Integer pkCountry);

    /*
     *  查询订单，存在可能已经撤单的
     **/
    SaOrder querySaOrderExtByPkId(Long pkId);

    /*
     *  查询店铺自提、店铺配送未发货订单，用于店铺发货界面
     **/
    List<SaOrderExt> queryStoreSaOrderByParam(OrderQueryParam orderQueryParam);

    /**
     * 校验年包价格
     *
     * @param cuMember 会员
     * @param saOrder  订单
     * @return true=可以购买
     */
    boolean checkRenewalAmount(CuMember cuMember, SaOrderExt saOrder);

}
