package com.ycwl.basic.biz;

import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.mapper.OrderMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.mobile.order.PriceObj;
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.pc.coupon.entity.CouponEntity;
import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordQueryResp;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
import com.ycwl.basic.model.pc.order.entity.OrderItemEntity;
import com.ycwl.basic.model.pc.order.req.OrderUpdateReq;
import com.ycwl.basic.model.pc.order.resp.OrderAppRespVO;
import com.ycwl.basic.model.pc.order.resp.OrderItemVO;
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.model.pc.video.resp.VideoRespVO;
import com.ycwl.basic.profitsharing.biz.ProfitSharingBiz;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.SourceRepository;
import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.repository.VideoRepository;
import com.ycwl.basic.repository.VideoTaskRepository;
import com.ycwl.basic.service.printer.PrinterService;
import com.ycwl.basic.utils.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Component
public class OrderBiz {

    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private ScenicRepository scenicRepository;
    @Autowired
    private TemplateRepository templateRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private FaceRepository faceRepository;
    @Autowired
    private SourceRepository sourceRepository;
    @Autowired
    private VideoRepository videoRepository;
    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SourceMapper sourceMapper;
    @Autowired
    private ProfitSharingBiz profitSharingBiz;
    @Autowired
    private VideoTaskRepository videoTaskRepository;
    @Autowired
    private BrokerBiz brokerBiz;
    @Autowired
    private CouponBiz couponBiz;
    @Autowired
    @Lazy
    private PrinterService printerService;

    public PriceObj queryPrice(Long scenicId, int goodsType, Long goodsId) {
        PriceObj priceObj = new PriceObj();
        priceObj.setGoodsType(goodsType);
        priceObj.setGoodsId(goodsId);
        ScenicEntity scenic = scenicRepository.getScenic(scenicId);
        ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
        priceObj.setScenicAllPrice(scenic.getPrice());
        if (scenicConfig != null) {
            if (Integer.valueOf(1).equals(scenicConfig.getAllFree())) {
                // 景区全免
                priceObj.setFree(true);
                priceObj.setPrice(BigDecimal.ZERO);
                priceObj.setSlashPrice(BigDecimal.ZERO);
                return priceObj;
            }
        }
        switch (goodsType) {
            case 0: // video
                VideoEntity video = videoRepository.getVideo(goodsId);
                if (video == null) {
                    return null;
                }
                TaskEntity task = videoTaskRepository.getTaskById(video.getTaskId());
                if (task != null) {
                    priceObj.setFaceId(task.getFaceId());
                }
                TemplateRespVO template = templateRepository.getTemplate(video.getTemplateId());
                if (template == null) {
                    return priceObj;
                }
                priceObj.setPrice(template.getPrice());
                BigDecimal slashPrice = template.getSlashPrice();
                if (slashPrice == null) {
                    priceObj.setSlashPrice(priceObj.getPrice());
                } else {
                    priceObj.setSlashPrice(slashPrice);
                }
                priceObj.setScenicId(video.getScenicId());
                break;
            case 1: // source
                priceObj.setPrice(scenic.getSourceVideoPrice());
                priceObj.setSlashPrice(scenic.getSourceVideoPrice());
                priceObj.setFaceId(goodsId);
                break;
            case 2: // source
                priceObj.setPrice(scenic.getSourceImagePrice());
                priceObj.setSlashPrice(scenic.getSourceImagePrice());
                priceObj.setFaceId(goodsId);
                break;
        }
        return priceObj;
    }

    public OrderEntity hasTypeOrder(Long userId, Long scenicId, int orderType, Integer configId) {
        OrderEntity orderEntity = orderMapper.queryTypeOrder(userId, scenicId, orderType, configId);
        if (orderEntity == null) {
            return null;
        }
        if (Integer.valueOf(1).equals(orderEntity.getStatus())) {
            return orderEntity;
        } else {
            return null;
        }
    }

    public IsBuyRespVO isBuy(Long userId, Long scenicId, int goodsType, Long goodsId) {
        IsBuyRespVO respVO = new IsBuyRespVO();
        boolean isBuy = orderRepository.checkUserBuyItem(userId, goodsType, goodsId);
        // 模板购买逻辑
        if (!isBuy) {
            if (goodsType == 0) {
                VideoEntity video = videoRepository.getVideo(goodsId);
                TaskEntity task = videoTaskRepository.getTaskById(video.getTaskId());
                Long templateId = video.getTemplateId();
                // -1为整个模板购买
                OrderEntity orderEntity = orderRepository.getUserBuyItem(userId, -1, templateId);
                if (orderEntity != null && task != null) {
                    respVO.setOrderId(orderEntity.getId());
                    if (orderEntity.getFaceId() != null && task.getFaceId() != null) {
                        isBuy = orderEntity.getFaceId().equals(task.getFaceId());
                    }
                }
            }
        }
        // 免费送逻辑，之前已经赠送了的
        if (!isBuy) {
            isBuy = switch (goodsType) {
                case 0 -> videoRepository.getUserIsBuy(userId, goodsId);
                case 1, 2 -> sourceRepository.getUserIsBuy(userId, goodsType, goodsId);
                default -> false;
            };
        } else {
            OrderEntity orderEntity = orderRepository.getUserBuyItem(userId, goodsType, goodsId);
            if (orderEntity != null) {
                respVO.setOrderId(orderEntity.getId());
            }
        }
        respVO.setBuy(isBuy);
        // 还是没买
        if (!isBuy) {
            PriceObj priceObj = queryPrice(scenicId, goodsType, goodsId);
            if (priceObj == null) {
                return respVO;
            }
            respVO.setFree(priceObj.isFree());
            respVO.setGoodsType(goodsType);
            respVO.setGoodsId(goodsId);
            respVO.setOrigPrice(priceObj.getPrice());
            respVO.setSlashPrice(priceObj.getSlashPrice());
            switch (goodsType) {
                case 0: // vlog
                    VideoEntity video = videoRepository.getVideo(goodsId);
                    TaskEntity taskById = videoTaskRepository.getTaskById(video.getTaskId());
                    if (taskById != null) {
                        CouponRecordQueryResp recordQueryResp = couponBiz.queryUserCouponRecord(scenicId, userId, taskById.getFaceId(), taskById.getTemplateId().toString());
                        if (recordQueryResp.isUsable()) {
                            respVO.setCouponId(recordQueryResp.getCouponId());
                            respVO.setCouponRecordId(recordQueryResp.getId());
                            CouponEntity coupon = recordQueryResp.getCoupon();
                            if (coupon != null) {
                                respVO.setCouponPrice(coupon.calculateDiscountPrice(priceObj.getPrice()));
                            }
                        }
                    }
                    break;
                case 1:
                case 2:
                    CouponRecordQueryResp recordQueryResp = couponBiz.queryUserCouponRecord(scenicId, userId, goodsId, String.valueOf(goodsType));
                    if (recordQueryResp.isUsable()) {
                        respVO.setCouponId(recordQueryResp.getCouponId());
                        respVO.setCouponRecordId(recordQueryResp.getId());
                        CouponEntity coupon = recordQueryResp.getCoupon();
                        if (coupon != null) {
                            respVO.setCouponPrice(coupon.calculateDiscountPrice(priceObj.getPrice()));
                        }
                    }
                    break;

            }
        }
        return respVO;
    }

    public void paidOrder(Long orderId) {
        orderRepository.clearOrderCache(orderId); // 检查支付呢，还缓存
        OrderEntity order = orderRepository.getOrder(orderId);
        List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
        OrderEntity orderUpdate = new OrderEntity();
        orderUpdate.setPayAt(new Date());
        orderUpdate.setStatus(1);
        orderRepository.updateOrder(orderId, orderUpdate);
        orderItems.forEach(item -> {
            switch (item.getGoodsType()) {
                case 0: // vlog视频
                    videoRepository.setUserIsBuyItem(order.getMemberId(), item.getGoodsId(), order.getId());
                case 1: // 视频原素材
                case 2: // 照片原素材
                    sourceRepository.setUserIsBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId(), order.getId());
                case 3:
                    printerService.setUserIsBuyItem(order.getMemberId(), item.getGoodsId(), order.getId());
            }
        });
        orderRepository.clearOrderCache(orderId); // 更新完了，清理下
        if (order.getCouponRecordId() != null) {
            couponBiz.userUseCoupon(order.getMemberId(), order.getFaceId(), order.getCouponRecordId(), orderId);
        }

        //支付时间
        OrderAppRespVO orderDetail = orderMapper.appDetail(orderId);
        Date payAt = orderDetail.getPayAt();
        //商品创建时间
        Date goodsCreateTime = new Date();
        if (!orderDetail.getOrderItemList().isEmpty()) {
            OrderItemVO orderItemVO = orderDetail.getOrderItemList().getFirst();
            switch (orderItemVO.getGoodsType()) {
                case 0:
                    VideoEntity video = videoRepository.getVideo(orderItemVO.getGoodsId());
                    if (video != null) {
                        goodsCreateTime = video.getCreateTime();
                    }
                    break;
                case 1:
                    List<SourceEntity> imageSource = sourceMapper.listImageByFaceRelation(order.getMemberId(), orderItemVO.getGoodsId());
                    Optional<SourceEntity> min = imageSource.stream().min(Comparator.comparing(SourceEntity::getCreateTime));
                    if (min.isPresent()) {
                        goodsCreateTime = min.get().getCreateTime();
                    }
                    break;
                case 2:
                    List<SourceEntity> videoSource = sourceMapper.listImageByFaceRelation(order.getMemberId(), orderItemVO.getGoodsId());
                    Optional<SourceEntity> minTime = videoSource.stream().min(Comparator.comparing(SourceEntity::getCreateTime));
                    if (minTime.isPresent()) {
                        goodsCreateTime = minTime.get().getCreateTime();
                    }
                    break;
            }
        }

        StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
        statisticsRecordAddReq.setMemberId(order.getMemberId());
        Long enterType = statisticsMapper.getUserRecentEnterType(order.getMemberId(), order.getCreateAt());
        if(!Long.valueOf(1014).equals(enterType)){//
            statisticsRecordAddReq.setType(StatisticEnum.ON_SITE_PAYMENT.code);
        }else {
            statisticsRecordAddReq.setType(StatisticEnum.POST_PAYMENT.code);
        }
        statisticsRecordAddReq.setScenicId(order.getScenicId());
        statisticsRecordAddReq.setMorphId(orderId);
        statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
        profitSharingBiz.processProfitSharing(order.getScenicId(), orderId, order.getPayPrice());
        brokerBiz.processOrder(orderId);
    }

    public void cancelOrder(Long orderId) {
        orderRepository.clearOrderCache(orderId); // 检查支付呢，还缓存
        OrderEntity order = orderRepository.getOrder(orderId);
        List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
        OrderEntity orderUpdate = new OrderEntity();
        orderUpdate.setCancelAt(new Date());
        orderUpdate.setStatus(9);
        orderRepository.updateOrder(orderId, orderUpdate);
        orderItems.forEach(item -> {
            switch (item.getGoodsType()) {
                case 0: // vlog视频
                    videoRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsId());
                case 1: // 视频原素材
                case 2: // 照片原素材
                    sourceRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId());
            }
        });
        orderRepository.clearOrderCache(orderId); // 更新完了，清理下
        profitSharingBiz.revokeProfitSharing(order.getScenicId(), orderId, "订单被取消");
    }

    public void refundOrder(Long orderId) {
        orderRepository.clearOrderCache(orderId);
        OrderEntity order = orderRepository.getOrder(orderId);
        List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
        OrderEntity orderUpdate = new OrderEntity();
        orderUpdate.setRefundAt(new Date());
        orderUpdate.setStatus(2);
        orderUpdate.setRefundStatus(1);
        orderRepository.updateOrder(orderId, orderUpdate);
        orderItems.forEach(item -> {
            switch (item.getGoodsType()) {
                case 0: // vlog视频
                    videoRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsId());
                case 1: // 视频原素材
                case 2: // 照片原素材
                    sourceRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId());
            }
        });
        orderRepository.clearOrderCache(orderId); // 更新完了，清理下
        profitSharingBiz.revokeProfitSharing(order.getScenicId(), orderId, "订单已退款");
    }
}
