package com.izouma.dingdong.web;

import cn.hutool.core.util.StrUtil;
import com.izouma.dingdong.domain.OrderInfo;
import com.izouma.dingdong.domain.User;
import com.izouma.dingdong.dto.OrderInfoDTO;
import com.izouma.dingdong.dto.UserOrderDTO;
import com.izouma.dingdong.enums.*;
import com.izouma.dingdong.repo.AppraisalRepo;
import com.izouma.dingdong.repo.UserRepo;
import com.izouma.dingdong.repo.rider.RiderRepo;
import com.izouma.dingdong.service.OrderInfoService;
import com.izouma.dingdong.dto.PageQuery;
import com.izouma.dingdong.exception.BusinessException;
import com.izouma.dingdong.repo.OrderInfoRepo;
import com.izouma.dingdong.service.merchant.MerchantService;
import com.izouma.dingdong.utils.ObjUtils;
import com.izouma.dingdong.utils.SecurityUtils;
import com.izouma.dingdong.utils.excel.ExcelUtils;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/orderInfo")
@AllArgsConstructor
public class OrderInfoController extends BaseController {
    private OrderInfoService orderInfoService;
    private OrderInfoRepo    orderInfoRepo;
    private UserRepo         userRepo;
    private MerchantService  merchantService;
    private RiderRepo        riderRepo;
    private AppraisalRepo    appraisalRepo;


    //@PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/save")
    public OrderInfo save(@RequestBody OrderInfo record) {
        if (record.getId() != null) {
            OrderInfo orig = orderInfoRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
            ObjUtils.merge(orig, record);
            return orderInfoRepo.save(orig);
        }
        return orderInfoRepo.save(record);
    }


    //@PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/all")
    public Page<OrderInfo> all(PageQuery pageQuery) {
        return orderInfoRepo.findAll(toSpecification(pageQuery, OrderInfo.class), toPageRequest(pageQuery));
    }

    @GetMapping("/get/{id}")
    public OrderInfoDTO get(@PathVariable Long id) {
        OrderInfo orderInfo = orderInfoRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        OrderInfoDTO dto = orderInfoService.toDto(orderInfo);

        //评价ID插入
        if (orderInfo.getRated()) {
            appraisalRepo.findByOrderInfoId(orderInfo.getId()).ifPresent(a -> dto.setAppraisalId(a.getId()));
        }
        return dto;
    }

    @PostMapping("/del/{id}")
    public void del(@PathVariable Long id) {
        orderInfoRepo.deleteById(id);
    }

    @GetMapping("/excel")
    @ResponseBody
    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<OrderInfo> data = all(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }


    @PostMapping("/order")
    @ApiOperation("从购物车生成订单")
    public OrderInfo order(UserOrderDTO userOrderDTO) {
        return orderInfoService.userOrder(userOrderDTO);
    }

    @GetMapping("/my")
    @ApiOperation("个人订单")
    public Page<OrderInfoDTO> my(PageQuery pageQuery) {
        //query.status 状态传入
        Map<String, Object> query = pageQuery.getQuery();
        Long id = SecurityUtils.getAuthenticatedUser().getId();
        User user = userRepo.findById(id).orElseThrow(new BusinessException("无用户"));
        if (user.getIdentity() == null) {
            throw new BusinessException("身份错误");
        }
        switch (user.getIdentity()) {
            case USER:
                query.put("userId", id);
                break;
            case MERCHANT:
                Long merchantId = merchantService.findMerchantId(id);
                query.put("merchantId", merchantId);
                //未接单列表只展示已支付的
                if (query.get("merchantStatus") != null && "NOT_RECEIVED".equals(query.get("merchantStatus"))) {
                    query.put("status", "PAID");
                }
                break;
            case RIDER:
                Long riderId = riderRepo.findByUserId(id).orElseThrow(new BusinessException("无骑手")).getId();
                query.put("riderId", riderId);
                break;
        }
        return orderInfoRepo.findAll(toSpecification(pageQuery, OrderInfo.class), toPageRequest(pageQuery))
                .map(orderInfoService::toDto);

/*        List<OrderInfo> collect = orderInfoService.my(SecurityUtils.getAuthenticatedUser().getId());
        return new PageImpl<>(collect, toPageRequest(pageQuery), pageQuery.getSize());*/
    }

    @GetMapping("/received")
    @ApiOperation("商家手动接单")
    public OrderInfo received(Long orderId, Boolean pass) {
        return orderInfoService.merReceiveOrder(orderId, pass);
    }

    @PostMapping("/riderStatus")
    @ApiOperation("骑手改变状态")
    public void riderStatus(Long orderId, RiderStatus status, Double longitude, Double latitude) {
        orderInfoService.riderCarryOut(orderId, status, longitude, latitude);
    }

    @GetMapping("/allAmount")
    @ApiOperation("消费金额")
    public BigDecimal allAmount(Long id) {
        return orderInfoRepo.sumRealAmountByUserId(id);
    }


    @GetMapping("/cancelOrder")
    @ApiOperation("取消订单")
    public OrderInfo cancel(Long id, RefundReason reason, String remark, String img) {
        //如果是骑手取消
        if (Identity.RIDER.equals(SecurityUtils.getAuthenticatedUser().getIdentity())) {
            if (StrUtil.isEmpty(img)) {
                throw new BusinessException("无联系信息截图");
            }
        }

        //订单id  理由  备注  图片
        return orderInfoService.cancel(id, reason, remark, img);
    }

    //@GetMapping("/cancelCancelOrder")

    @GetMapping("/missedOrder")
    @ApiOperation("骑手端，五分钟内未接单的订单")
    public List<OrderInfo> missedOrder() {
        return orderInfoRepo.findAllByStatusAndOrderTimeAfterAndMerchantStatus(OrderStatus.PAID, LocalDateTime.now()
                .plusMinutes(5), MerchantStatus.RECEIVED);
    }

    @GetMapping("/riderReceived")
    @ApiOperation("骑手端，未接单的订单")
    public List<OrderInfoDTO> riderReceived() {
        return orderInfoRepo.findAllByRiderIdIsNullAndMerchantStatusAndStatus(MerchantStatus.RECEIVED,OrderStatus.PAID)
                .stream()
                .map(orderInfoService::toDto)
                .collect(Collectors.toList());
    }

    @GetMapping("/blackAll")
    public Page<OrderInfoDTO> blackAll(PageQuery pageQuery) {
        return orderInfoRepo.findAll(toSpecification(pageQuery, OrderInfo.class), toPageRequest(pageQuery))
                .map(orderInfoService::toDto);
    }

    @GetMapping("/pickupPhotos")
    @ApiOperation("到店拍照取货")
    public void pickupPhotos(Long orderId, RiderStatus status, String img) {
        orderInfoService.pickupPhotos(orderId, status, img);
    }

    /*
    骑手强制已到店，已送达
     */
    @GetMapping("/mandatory")
    @ApiOperation("强制")
    public void mandatory(Long orderId, RiderStatus status) {
        orderInfoService.mandatory(orderId, status);
    }

    @GetMapping("/toCompleted")
    @ApiOperation("跳过支付")
    public void toCompleted(@RequestParam Long orderId) {
        orderInfoService.toCompleted(orderId);
    }

}

