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.retail.member.ext.CuMemberRetailRegionExt;
import com.hzs.common.domain.sale.ext.*;
import com.hzs.common.domain.sale.order.SaOrder;
import com.hzs.common.domain.sale.order.SaOrderItems;
import com.hzs.common.domain.system.config.BdGrade;
import com.hzs.common.domain.third.pay.ext.TOnlineRefundExt;
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 orderTypeList 订单类型
     * @param notOrderType  不处理订单类型
     */
    List<SaOrder> querySaleOrderByPkMember(Integer pkCountry, Long pkMember, List<Integer> orderTypeList, List<Integer> notOrderType);

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

    /*
     *  查询网体是否存在推荐人
     **/
    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, CuMember cuMember);

    /**
     * 封装需要保存的销售订单和会员
     *
     * @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);

    /**
     * 支付复购订单
     *
     * @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);

    /**
     * 自助撤单
     **/
    void selfRevokeOrder(Long pkApprove, MyOrderVO myOrderVO);

    /**
     * 根据等级主键查询等级
     *
     * @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);

    /**
     * 验证是否左区必须现有安置才能安置右区
     *
     * @param pkPlaceParent 安置位置
     * @param pkCountry     国家
     */
    boolean validateLeftExistMember(Long pkPlaceParent, Integer pkCountry);

    /**
     * 查询时间范围内的所有订单，按照订单时间排序,只能用于奖金结算
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     */
    List<SaOrderExt> queryRetailSaOrderByDay(Date startDate, Date endDate, String orderCode);

    /**
     * 获取系统参数
     *
     * @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);

    List<TOnlineRefundExt> queryRefundList();

    /**
     * 自助撤单列表
     **/
    List<SaOrderExt> selfRevokeOrderList(MyOrderParam param, Long memberId, Integer pkCountry);

    /**
     * 自助服务-可申请订单列表
     **/
    List<SaOrderExt> selfOrderList(MyOrderParam param, Long memberId, Integer pkCountry);

    /**
     * 查询最新待发货订单
     **/
    String lastOrderList(Long memberId, Integer pkCountry);

    /**
     * 自助服务-修改收货地址订单列表
     **/
    List<SaOrderExt> selfAddressOrderList(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 param
     * @param pkCountry
     * @param systemType
     * @return
     */
    List<OrderBusinessVO> queryOrderBusinessList(OrderBusinessParam param, Integer pkCountry, Integer systemType);

    /**
     * 删除订单以及详情
     *
     * @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 param
     * @return
     */
    List<OrderInvoicingVO> listOrderInvoicing(OrderInvoicingParam param);

    /**
     * 查询订单以及会员信息
     *
     * @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);

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

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

    /**
     * 根据编号查询会员首单
     *
     * @param memberCodeList
     * @return
     */
    List<MemberFirstOrderVo> checkMemberIsFirstOrder(List<String> memberCodeList);

    /**
     * 根据订单ID查询订单信息
     *
     * @param pkOrder   订单ID（与订单编号二选一）
     * @param orderCode 订单编号（与订单ID二选一）
     * @param pkCountry 所属国家（可为空）
     * @return
     */
    SaOrderExt queryByPkIdOrCode(Long pkOrder, String orderCode, Integer pkCountry);

    /**
     * 查询订单单品统计
     *
     * @return
     */
    List<SingleItemStatVo> singleItemStat(SingleItemStatParam singleItemStatParam);

    /**
     * 新零售校验会员账户余额是否足够
     *
     * @param cuMemberAccount
     * @param saOrder
     * @param orderItemList
     * @return
     */
    CuMemberAccountExt queryRetailOrderSpendDetails(CuMemberAccountExt cuMemberAccount, SaOrder saOrder, List<SaOrderItems> orderItemList);

    /**
     * 计算等级（根据盒数）
     *
     * @param specialArea       商品专区
     * @param orderItemsParams  商品明细
     * @param gradeList         等级列表（可为空）
     * @param updateGradeMember 升级会员信息（升级使用）
     * @param systemType        系统类型
     * @return 返回 null 则为不满足升级条件
     */
    BdGrade calculateGrade(Integer specialArea, List<OrderItemsParam> orderItemsParams,
                           List<BdGrade> gradeList, CuMember updateGradeMember,
                           Integer systemType, Integer isPay);

    /**
     * 根据盒数计算等级
     *
     * @param boxTotal     总盒数
     * @param gradeList    等级列表（可为空）
     * @param memberGrade  当前等级 -- 为空则为注册，不为空则为升级
     * @param checkUpgrade 校验升级
     * @return
     */
    BdGrade getGradeByBox(final BigDecimal boxTotal, List<BdGrade> gradeList, BdGrade memberGrade, boolean checkUpgrade);

    /**
     * 处理升级盒数基数
     *
     * @param cuMember       会员信息
     * @param memberGrade    会员等级信息
     * @param gradeList      等级列表
     * @param boxProductList 盒数商品商品
     * @param systemType     所属系统
     * @return
     */
    BigDecimal handleBaseBoxNum(CuMember cuMember, BdGrade memberGrade, List<BdGrade> gradeList, List<String> boxProductList, Integer systemType);

    /**
     * 查询省、市、区绑定次数
     *
     * @param province
     * @param city
     * @param county
     * @return
     */
    CuMemberRetailRegionExt getRegionBindNum(Integer province, Integer city, Integer county);


}
