package com.ai.da.service.impl;


import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.CreditsEventsEnum;
import com.ai.da.common.enums.OrderStatusEnum;
import com.ai.da.common.enums.ProductEnum;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.utils.OrderNoUtils;
import com.ai.da.common.utils.RequestInfoUtil;
import com.ai.da.mapper.primary.OrderInfoMapper;
import com.ai.da.mapper.primary.PaymentInfoMapper;
import com.ai.da.mapper.primary.ProductMapper;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.mapper.primary.entity.PaymentInfo;
import com.ai.da.model.dto.QueryPageByTimeDTO;
import com.ai.da.model.vo.AuthPrincipalVo;
import com.ai.da.service.OrderInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Resource
    private ProductMapper productMapper;

    @Resource
    private PaymentInfoMapper paymentInfoMapper;

    @Override
    public OrderInfo createOrderByProductId(Integer amount, String paymentType, HttpServletRequest request) {


        //查找已存在但未支付的订单
        /*OrderInfo orderInfo = this.getNoPayOrderByProductId(amount, paymentType);
        if( orderInfo != null){
            return orderInfo;
        }*/

        //获取商品信息
//        Product product = productMapper.selectById(amount);
        AuthPrincipalVo userHolder = UserContext.getUserHolder();
        Long accountId = userHolder.getId();

        //生成订单
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setAccountId(accountId);
        orderInfo.setTitle("积分购买 X" + amount);
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //订单号 ??
//        orderInfo.setProductId(amount);
//        orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
        orderInfo.setTotalFee(Float.parseFloat(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
        setIPLocation(paymentType, request, orderInfo);
        baseMapper.insert(orderInfo);
        return orderInfo;
    }

    private void setIPLocation(String paymentType, HttpServletRequest request, OrderInfo orderInfo) {
        orderInfo.setOrderStatus(OrderStatusEnum.NOT_PAY.getType()); //未支付
        orderInfo.setPaymentType(paymentType);
        if (!Objects.isNull(request)){
            String ipAddress = RequestInfoUtil.getIpAddress(request);
            if (!StringUtil.isNullOrEmpty(ipAddress)) {
                Map ipLocation = RequestInfoUtil.getIPLocation(ipAddress);
                if (ipLocation != null && !ipLocation.get("status").equals("fail")) {
                    orderInfo.setCountry(ipLocation.get("country").toString());
                    orderInfo.setCity(ipLocation.get("city").toString());
                    orderInfo.setIpAddress(ipLocation.get("query").toString());
                }
            }
        }
    }

    public OrderInfo createOrderByProductId(Integer amount, String paymentType, ProductEnum product,
                                            HttpServletRequest request, byte autoRenewal) {

        //获取商品信息
//        Product product = productMapper.selectById(amount);
        String title;
        if (product.equals(ProductEnum.CreditsProduct)) {
            title = "积分购买 X" + amount;
        } else {
            title = product.getName();
        }
        AuthPrincipalVo userHolder = UserContext.getUserHolder();
        Long accountId = userHolder.getId();

        //生成订单
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setAccountId(accountId);
        orderInfo.setTitle(title);
        orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); // 自定义订单号
//        orderInfo.setProductId(amount);
//        orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
        orderInfo.setTotalFee((float) (product.getPrice() * amount)); // 元 HKD
        setIPLocation(paymentType, request, orderInfo);
        baseMapper.insert(orderInfo);
        return orderInfo;
    }

    /**
     * 存储订单二维码
     *
     * @param orderNo
     * @param codeUrl
     */
    @Override
    public void saveCodeUrl(String orderNo, String codeUrl) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setCodeUrl(codeUrl);

        baseMapper.update(orderInfo, queryWrapper);
    }

    /**
     * 查询订单列表，并倒序查询
     *
     * @return
     */
    @Override
    public List<OrderInfo> listOrderByCreateTimeDesc() {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<OrderInfo>().orderByDesc("create_time");
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 根据订单号更新订单状态
     *
     * @param orderNo
     * @param orderStatus
     */
    @Override
    public void updateStatusByOrderNo(String orderNo, OrderStatusEnum orderStatus) {

        log.info("更新订单状态 ===> {}", orderStatus.getType());

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderStatus(orderStatus.getType());

        baseMapper.update(orderInfo, queryWrapper);
    }

    /**
     * 根据订单号获取订单状态
     *
     * @param orderNo
     * @return
     */
    @Override
    public String getOrderStatus(String orderNo) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
        if (orderInfo == null) {
            return null;
        }
        return orderInfo.getOrderStatus();
    }

    /**
     * 查询创建超过minutes分钟并且未支付的订单
     *
     * @param minutes
     * @return
     */
    @Override
    public List<OrderInfo> getNoPayOrderByDuration(int minutes, String paymentType) {

        Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_status", OrderStatusEnum.NOT_PAY.getType());
        queryWrapper.le("create_time", instant);
        queryWrapper.eq("payment_type", paymentType);

        List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);

        return orderInfoList;
    }

    /**
     * 根据订单号获取订单
     *
     * @param orderNo
     * @return
     */
    @Override
    public OrderInfo getOrderByOrderNo(String orderNo) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);

        return orderInfo;
    }


    /**
     * 根据商品id查询未支付订单
     * 防止重复创建订单对象
     *
     * @param productId
     * @return
     */
    private OrderInfo getNoPayOrderByProductId(Long productId, String paymentType) {

        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", productId);
        queryWrapper.eq("order_status", OrderStatusEnum.NOT_PAY.getType());
        queryWrapper.eq("payment_type", paymentType);
//        queryWrapper.eq("user_id", userId);
        OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
        return orderInfo;
    }

    @Override
    public PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO) {
        QueryWrapper<OrderInfo> qw = new QueryWrapper<>();
        qw.eq("account_id", UserContext.getUserHolder().getId());

        String startTime = queryPageByTimeDTO.getStartTime();
        String endTime = queryPageByTimeDTO.getEndTime();
        if (StringUtil.isNullOrEmpty(startTime)) {
            startTime = "2024-02-01 00:00:00";
        }
        if (StringUtil.isNullOrEmpty(endTime)) {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            endTime = now.format(dateTimeFormatter);
        }
        qw.between("create_time", startTime, endTime);
        qw.orderByDesc("create_time");
        Page<OrderInfo> pageInfo = new Page<>(queryPageByTimeDTO.getPage(), queryPageByTimeDTO.getSize());
        Page<OrderInfo> orderInfo = baseMapper.selectPage(pageInfo, qw);
        if (CollectionUtils.isEmpty(orderInfo.getRecords())) {
            return PageBaseResponse.success(new Page<>());
        }

        return PageBaseResponse.success(orderInfo);
    }

    public void updateOrderNoById(Long id, String orderNo) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(id);
        orderInfo.setOrderNo(orderNo);

        baseMapper.updateById(orderInfo);
    }

    public void updateTotalFeeByOrderNo(String orderNo) {
        QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
        qw.eq("order_no", orderNo);
        List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qw);
        Float sum = paymentInfos.stream()
                .map(PaymentInfo::getPayerTotal)
                .reduce(0f, Float::sum);

        baseMapper.update(
                new OrderInfo(),
                new UpdateWrapper<OrderInfo>()
                        .eq("order_no", orderNo)
                        .set("total_fee", sum)
        );
    }

}
