package com.ghy.order.service;

import com.ghy.common.enums.OrderStatus;
import com.ghy.order.domain.*;
import com.ghy.order.pojo.dto.OrderDetailStatisticsDTO;
import com.ghy.payment.domain.FinancialChangeRecord;
import com.huifu.adapay.core.exception.BaseAdaPayException;

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

/**
 * 详细订单接口
 *
 * @author HH 2022/4/25
 */
public interface OrderDetailService {

    /**
     * @param orderDetail 详细订单属性
     * @return 成功条数
     */
    int insertOrderDetail(OrderDetail orderDetail);

    /**
     * @param orderDetail 详细订单属性
     * @return 成功条数
     */
    int updateOrderDetail(OrderDetail orderDetail);

    /**
     * @param orderDetail 详细订单入参
     * @return 详细订单集合
     */
    List<OrderDetail> selectOrderDetailList(OrderDetail orderDetail);

    /**
     * @param orderDetailId 详细订单id
     * @return 详细订单
     */
    OrderDetail selectById(Long orderDetailId);

    /**
     * @param orderMasterId 主订单id
     * @return 详细订单
     */
    List<OrderDetail> selectByOrderMasterId(Long orderMasterId);

    /**
     * 根据主订单ID集合批量查询详细订单
     * @param orderMasterIds 主订单ID集合
     * @return 详细订单集合
     */
    List<OrderDetail> selectByOrderMasterIds(List<Long> orderMasterIds);

    /**
     * @param ids 详细订单ids
     * @return 删除结果
     */
    int deleteOrderDetailByIds(String ids);

    /**
     * 校验详细订单编码是否重复
     *
     * @param orderDetail 详细订单属性
     * @return 校验结果 1存在 0不存在
     */
    String checkOrderDetailCodeUnique(OrderDetail orderDetail);

    /**
     * 创建code
     */
    String createCode(String orderMasterCode);

    /**
     * 根据订单id集合信息进行查询封装成为map数据，
     *
     * @param orderIdList 订单Id集合信息数据
     * @return 键值队列数据， key-> 订单Id value-> 订单实体集合信息
     */
    Map<Long, List<OrderDetail>> byOrderIdInMap(List<Long> orderIdList);

    /**
     * 消费者申请取消子订单
     *
     * @param orderDetailId 子订单ID
     */
    void applyForCancel(Long orderDetailId) throws BaseAdaPayException;

    /**
     * 师傅审核取消子订单申请
     *
     * @param orderDetailId 子订单ID
     * @param agree         0=不同意 1=同意
     */
    void cancelAgree(Long orderDetailId, Integer agree) throws BaseAdaPayException;

    /**
     * 通过主订单ID批量更新子订单
     * 可更新字段: orderStatus
     *
     * @param orderDetail 子订单
     */
    void updateByOrderMasterId(OrderDetail orderDetail);

    /**
     * 查询指定状态的订单
     */
    List<OrderDetail> selectByStatus(List<Integer> status);

    /**
     * 子订单确认完成
     * 1.修改子订单状态为 OrderStatus.FINISH.code
     * 2.将子订单对应的子财务单确认分账
     * 3.异步提现至银行卡
     *
     * @param orderDetailId 子订单ID
     */
    void finish(Long orderDetailId) throws BaseAdaPayException;

    /**
     * 统计符合条件的子单数量
     *
     * @param orderDetail
     * @return 数量
     */
    Long countOrderDetailList(OrderDetail orderDetail);

    /**
     * 查询符合条件的子单总数（用于分页）
     *
     * @param orderDetail 查询条件
     * @return 总数
     */
    Long selectOrderDetailCount(OrderDetail orderDetail);

    /**
     * 子单改价接口
     *
     * @param orderDetailId 子单id
     * @param changeMoney   改价金额
     * @param type          报价类型
     * @param remark        备注
     * @return 成功/失败
     */
    int changePrice(Long orderDetailId, BigDecimal changeMoney, Integer type, String remark,String urls ,String fileNames,String reason) throws Exception;

    int sureChange(Long financialChangeRecordId);

    FinancialChangeRecord getChangedPriceRecord(Long orderDetailId);

    List<OrderStatusCount> statusCount();

    /**
     * 用提现ID更新订单的提现状态
     *
     * @param drawCashId     发起提现后Adapay返回的对象ID
     * @param drawCashStatus 提现状态见{@link OrderDetail#getDrawCashStatus()}
     * @param drawCashTime   发起提现时间
     * @param arrivalTime    提现到账时间
     * @return 1
     */
    int updateDrawCashStatus(String drawCashId, int drawCashStatus, Date drawCashTime, Date arrivalTime);

    /**
     * 退款成功时 退款回调接口里会调用这个方法
     *
     * @param reverseId 退款ID
     */
    void refundSucceeded(String reverseId);

    /**
     * 更新子订单状态
     *
     * @param id     子订单id
     * @param status 状态码 {@link OrderStatus}
     * @return
     */
    int updateStatus(Long id, int status);

    /**
     * 更新子订单超时状态
     *
     * @param id               子订单ID
     * @param timeout          是否超时
     * @param timeoutFineTimes 超时罚款次数
     * @return 1
     */
    int updateTimeout(Long id, int timeout, int timeoutFineTimes);

    int updateAfterTimeout(Long id, int timeout, int timeoutFineTimes);

    int deleteByMaster(Long masterId);

    /**
     * 保存一条子订单的追加扣减记录
     * 并且更新子订单对应的财务单的金额
     *
     * @param body 追加扣减记录
     * @return 1
     */
    int insertOrderAddSubtract(OrderAddSubtract body);

    OrderDetailCount differentStatusOrderCount(OrderDetail orderDetail);

    Long afterDetailOrderCount(OrderDetail orderDetail);

    // 订单详情数据统计返回 每次都统计全表  数据量比较小
    OrderDetailStatisticsDTO orderStatisticsReturn();

    // 订单详情数据统计返回 每次都统计全表  数据量比较小
    OrderDetailStatisticsDTO orderStatisticsDispose();

    // 订单详情数据统计返回 根据时间统计当前日期天
    OrderDetailStatisticsDTO orderStatisticsReturnByNow();

    // 订单详情数据统计返回 根据时间统计当前日期天
    OrderDetailStatisticsDTO orderStatisticsDisposeByNow();

    /**
     * 延期到货
     * 如果是待确认状态则变为服务中，其他状态不变
     * 将confirm_start_time增加3天
     * 延期次数最多2次
     *
     * @param orderMasterId 主订单ID
     * @return 成功条数
     */
    int delayOrder(Long orderMasterId);

    /**
     * 子订单退回
     * 如果订单为服务类型(orderType=0)则退回到服务中状态
     * 如果订单为商品类型(orderType=1)则退回到待排期状态
     *
     * @param orderDetailId 子订单ID
     * @return 成功条数
     */
    int returnOrder(Long orderDetailId);

    int updateOrderDetailAddressById(OrderDetail orderDetail);

    /**
     * 保存子单师傅备注
     *
     * @param orderDetailId 子订单ID
     * @param workerRemark 师傅备注
     * @return 成功条数
     */
    int saveDetailWorkerRemark(Long orderDetailId, String workerRemark);
}
