package com.izouma.nineth.repo;

import com.izouma.nineth.domain.Order;
import com.izouma.nineth.enums.OrderStatus;
import org.springframework.data.jpa.repository.*;

import javax.persistence.LockModeType;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public interface OrderRepo extends JpaRepository<Order, Long>, JpaSpecificationExecutor<Order> {
    @Query("update Order t set t.del = true where t.id = ?1")
    @Modifying
    @Transactional
    void softDelete(Long id);

    Optional<Order> findByIdAndDelFalse(Long id);

    /**
     * 锁定记录，不能缓存
     *
     * @param id
     * @return
     */
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("select o from Order o where o.id = ?1")
    Optional<Order> findByIdForUpdate(Long id);


    @Query("select o.id from Order o where o.status = ?1 and o.createdAt < ?2 and o.del = false")
    List<Long> findWaitingCancelList(OrderStatus status, LocalDateTime time);

    List<Order> findByCollectionId(Long collectionId);

    List<Order> findByCollectionIdIn(Iterable<Long> collectionId);

    List<Order> findByAssetIdInAndStatusIn(Iterable<Long> assetId,Iterable<OrderStatus> orderStatuses);

    int countByCollectionIdAndStatusIn(Long collectionId, Iterable<OrderStatus> orderStatuses);

    List<Order> findByStatus(OrderStatus orderStatus);

    @Query("select count(o) from Order o join Collection c on o.collectionId = c.id " +
            "where c.minterId = ?1 and c.source = 'OFFICIAL' and o.status <> 'NOT_PAID' and o.status <> 'CANCELLED'")
    Integer countSales(Long userId);

    Order findByTransactionId(String txId);

    List<Order> findByAssetIdAndStatusIn(Long assetId, Iterable<OrderStatus> statuses);

    /**
     * 更新实际支付的订单编号
     *
     * @param orderId
     * @param orderNo
     */
    @Modifying
    @Query("update Order t set t.orderNo = ?2, t.transactionId = ?3 where t.id = ?1")
    void updateOrderNo(Long orderId, String orderNo, String transactionId);

    /**
     * 统计有效订单数量
     *
     * @param userId
     * @param collectionId
     * @return
     */
    @Query("select count(o) from Order o where o.del = false and o.status <> com.izouma.nineth.enums.OrderStatus.CANCELLED" +
            " and o.userWareHouseId is null and o.userWareHouseList is null and o.userId = ?1 and o.collectionId = ?2")
    Integer countValidOrder(Long userId, Long collectionId);


//    /**
//     * 指定时间内成交量排行榜
//     *
//     * @param status
//     * @return
//     */
//    @Query("SELECT new OrderRanking (o.userId ,count(o)) FROM Order o WHERE o.status = ?1  and o.createdAt >=?2 and o.createdAt <?3  GROUP  BY o.userId  ORDER BY count(o) DESC")
//    List<OrderRanking> salesStatistics1(OrderStatus status, LocalDateTime startTime, LocalDateTime endTime, PageRequest pageable);
//
//    /**
//     * 总成交量排行榜
//     *
//     * @param status
//     * @return
//     */
//    @Query("SELECT new OrderRanking (o.userId ,count(o)) FROM Order o WHERE o.status = ?1  GROUP BY o.userId ORDER BY count(o) DESC")
//    List<Map<Long, Long>> salesStatistics2(OrderStatus status, PageRequest pageable);


    /**
     * 总成交量排行榜
     *
     * @param status
     * @return
     */
    @Query(nativeQuery = true, value = "SELECT o.user_id ,sum(o.total_price) as count FROM order_info o WHERE o.status = ?1  GROUP BY o.user_id ORDER BY sum(o.total_price) DESC limit 30")
    List<Map<String, BigDecimal>> salesStatistics2(String status);

    /**
     * 指定时间内成交量排行榜
     *
     * @param status
     * @return
     */
    @Query(nativeQuery = true, value = "SELECT o.user_id ,sum(o.total_price) as count FROM order_info o WHERE o.status = ?1  and o.created_at >=?2 and o.created_at <?3  GROUP  BY o.user_id  ORDER BY sum(o.total_price) DESC limit 30")
    List<Map<String, BigDecimal>> salesStatistics1(String status, LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 指定时间内藏品成交量
     *
     * @param status
     * @return
     */
    @Query(nativeQuery = true, value = "SELECT o.name name,sum(o.total_price) as count, min(o.pic) pic FROM order_info o WHERE o.status = ?1  and o.created_at >=?2 and o.created_at < ?3  GROUP  BY o.name  ORDER BY sum(o.total_price) DESC limit 30")
    List<Map<String, BigDecimal>> salesStatistics3(String status, LocalDateTime startTime, LocalDateTime endTime);

}