package com.wzj.soopin.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.goods.domain.entity.Product;
import com.wzj.soopin.goods.domain.entity.Sku;
import com.wzj.soopin.goods.mapper.ProductMapper;
import com.wzj.soopin.goods.mapper.SkuMapper;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.order.domain.bo.OrderBo;
import com.wzj.soopin.order.domain.bo.RefundBO;
import com.wzj.soopin.order.domain.bo.SaveOrderBO;
import com.wzj.soopin.order.domain.bo.SaveOrderSkuItemBO;
import com.wzj.soopin.order.domain.entity.*;
import com.wzj.soopin.order.domain.form.ManagerOrderQueryForm;
import com.wzj.soopin.order.domain.vo.*;
import com.wzj.soopin.order.emum.AftersaleStatus;
import com.wzj.soopin.order.emum.OrderStatusEnum;
import com.wzj.soopin.order.mapper.*;
import com.wzj.soopin.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.event.Constants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysTenant;
import org.dromara.system.mapper.SysTenantMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 订单表Service业务层处理
 *
 * @author zcc
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    private final OrderMapper orderMapper;

    private final OrderItemMapper orderItemMapper;

    private final SkuMapper skuMapper;

    private final ProductMapper productMapper;

    private final OrderOperateHistoryMapper orderOperateHistoryMapper;

    private final MemberMapper memberMapper;

    private final OrderDeliveryHistoryMapper orderDeliveryHistoryMapper;

    private final SysTenantMapper sysTenantMapper;

    private final AftersaleMapper aftersaleMapper;

    private final AftersaleItemMapper aftersaleItemMapper;

    /**
     * 订单前缀
     */
    private final static String ORDER_SN_PREFIX = "WZJ";


    /**
     * 查询订单表
     *
     * @param id 订单表主键
     * @return 订单表
     */
    @Override
    public ManagerOrderDetailVO selectById(Long id) {

        Order order = orderMapper.selectById(id);
        Assert.notNull(order, () -> new ServiceException("无该订单信息"));


        ManagerOrderDetailVO managerOrderDetailVO = new ManagerOrderDetailVO();
        //封装订单信息
        managerOrderDetailVO.setOrderId(id);
        managerOrderDetailVO.setCouponAmount(order.getCouponAmount());
        managerOrderDetailVO.setOrderSn(order.getOrderSn());
        managerOrderDetailVO.setOrderStatus(order.getStatus());
        managerOrderDetailVO.setCreateTime(order.getCreateTime());
        managerOrderDetailVO.setPayAmount(order.getPayAmount());
        managerOrderDetailVO.setPayTime(order.getPaymentTime());
        managerOrderDetailVO.setPayType(order.getPayType());
        managerOrderDetailVO.setTotalAmount(order.getTotalAmount());
        managerOrderDetailVO.setPayAmount(order.getPayAmount());

        //封装订单地址信息
        ManagerOrderAddressVo managerOrderAddressVo = new ManagerOrderAddressVo();
        managerOrderAddressVo.setAddress(order.getReceiverDetailAddress());
        managerOrderAddressVo.setArea(
            order.getReceiverProvince() +
                order.getReceiverCity() +
                order.getReceiverDistrict());
        managerOrderDetailVO.setAddressInfo(managerOrderAddressVo);

        Member member = memberMapper.selectById(order.getMemberId());
        managerOrderDetailVO.setUserName(member.getNickname());
        managerOrderDetailVO.setUserPhone(member.getPhoneHidden());

        if (order.getTenantId() != null) {
            SysTenant tenant = sysTenantMapper.selectOne(
                new QueryWrapper<SysTenant>()
                    .eq("tenant_id", order.getTenantId())
                    .select("contact_user_name", "contact_phone")
            );
            if (tenant != null) {
                managerOrderDetailVO.setContactUserName(tenant.getContactUserName());
                managerOrderDetailVO.setContactPhone(tenant.getContactPhone());
            }
        }

        QueryWrapper<OrderItem> qw = new QueryWrapper<>();
        qw.eq("order_id", order.getId());
        List<OrderItem> orderItemList = orderItemMapper.selectList(qw);
        List<ManagerOrderProductVO> productList = new ArrayList<>();
        orderItemList.forEach(item -> {
            ManagerOrderProductVO productVO = new ManagerOrderProductVO();
            productVO.setProductId(item.getProductId());
            productVO.setBuyNum(item.getQuantity());
            productVO.setPic(item.getPic());
            productVO.setProductName(item.getProductName());
            productVO.setSalePrice(item.getSalePrice());
            productVO.setSpData(item.getSpData());
            productList.add(productVO);
        });
        managerOrderDetailVO.setProductInfo(productList);

        return managerOrderDetailVO;
    }

    /**
     * 查询订单表列表
     *
     * @param query 查询条件
     * @param page  分页条件
     * @return 订单表
     */
    public PageImpl<ManagerOrderVO> selectList(ManagerOrderQueryForm query, Pageable page) {
//        if (page != null) {
////            PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize());
//        }
//        if (!StringUtils.isEmpty(query.getUserPhone())){
////            query.setUserPhone(AesCryptoUtils.encrypt(aesKey, query.getUserPhone()));
//        }
        List<ManagerOrderVO> managerOrderVOList = orderMapper.selectManagerOrderPage(query);
        if (CollectionUtil.isEmpty(managerOrderVOList)) {
            return new PageImpl<>(managerOrderVOList, page, 0);
        }
        long total = managerOrderVOList.size();
        Map<Long, ManagerOrderVO> orderMap = managerOrderVOList.stream().collect(Collectors.toMap(ManagerOrderVO::getId, it -> it, (v1, v2) -> v2, LinkedHashMap::new));
        //查orderItem
        QueryWrapper<OrderItem> qw = new QueryWrapper<>();
        qw.in("order_id", orderMap.keySet());
        Map<Long, List<OrderItem>> groupedOrderItemMap = orderItemMapper.selectList(qw)
            .stream().collect(Collectors.groupingBy(OrderItem::getOrderId));
        groupedOrderItemMap.keySet().forEach(key -> {
            ManagerOrderVO managerOrderVO = orderMap.get(key);
            managerOrderVO.setBuyNum(0);
            List<OrderItem> orderItemList = groupedOrderItemMap.get(key);
            List<ManagerOrderProductVO> addProductList = new ArrayList<>();
            orderItemList.forEach(item -> {
                ManagerOrderProductVO vo = new ManagerOrderProductVO();
                vo.setProductName(item.getProductName());
                vo.setSalePrice(item.getSalePrice());
                vo.setPic(item.getPic());
                vo.setBuyNum(item.getQuantity());
                vo.setProductId(item.getProductId());
                vo.setSpData(item.getSpData());
                addProductList.add(vo);
                managerOrderVO.setBuyNum(managerOrderVO.getBuyNum() + item.getQuantity());
            });
            managerOrderVO.setProductList(addProductList);
        });
        return new PageImpl<>(new ArrayList<>(orderMap.values()), page, total);
    }

    /**
     * 新增订单表
     *
     * @param saveOrderBO 订单表
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderVO saveOrder(SaveOrderBO saveOrderBO) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<SaveOrderSkuItemBO> skuItemBOList = saveOrderBO.getSkuItemBOList();
        Map<Long, Integer> map = skuItemBOList.stream().collect(Collectors.toMap(SaveOrderSkuItemBO::getSkuId, SaveOrderSkuItemBO::getQuantity));
        BigDecimal totalAmount = new BigDecimal(0);
        List<Sku> skus = skuMapper.selectByIds(map.keySet());
        Assert.isTrue(skus.size() == skuItemBOList.size(), () -> new ServiceException("下单商品不存在"));
        LinkedHashMap<Long, Product> productMap = productMapper.selectByIds(skus.stream().map(Sku::getProductId).collect(Collectors.toList()))
            .stream().collect(Collectors.toMap(Product::getId, it -> it, (v1, v2) -> v2, LinkedHashMap::new));
        for (Sku sku : skus) {
            Integer quantity = map.get(sku.getId());
            Assert.isTrue(quantity < sku.getStock(), () -> new ServiceException("下单商品库存不足"));
            skuMapper.updateStockById(sku.getId(), LocalDateTime.now(), quantity);
            BigDecimal multiply = sku.getPrice().multiply(new BigDecimal(quantity));
            totalAmount = totalAmount.add(multiply);
        }
        Order order = Order.builder()
            .memberId(loginUser.getUserId())
            .memberUsername(loginUser.getUsername())
            .totalAmount(totalAmount)
            .tenantId(loginUser.getReferenceTenantId())
            .orderSn(generateOrderSn())
            .type(saveOrderBO.getType())
            .payType(Constants.PayType.NO_PAY)
            .status(OrderStatusEnum.UNPAID.getValue())
            .distribution(saveOrderBO.getDistribution())
            .build();
        orderMapper.insert(order);
        List<OrderItem> orderItemList = skus.stream().map(sku -> {
            Product product = productMap.get(sku.getProductId());
            return OrderItem.builder()
                .orderId(order.getId())
                .productId(sku.getProductId())
                .skuId(sku.getId())
                .productName(product != null ? product.getName() : "")
                .pic(sku.getPic())
                .salePrice(sku.getPrice())
                .quantity(map.get(sku.getId()))
                .tenantId(sku.getTenantId())
                .build();
        }).toList();
        orderItemMapper.insert(orderItemList);
        return BeanUtil.copyProperties(order, OrderVO.class);
    }

    @Override
    public void cancel(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        LoginUser loginUser = LoginHelper.getLoginUser();
        Assert.isTrue(Objects.equals(loginUser.getUserId(), order.getMemberId()), () -> new ServiceException("无权限取消非本人订单"));
        Assert.isTrue(OrderStatusEnum.UNPAID.getValue().equals(order.getStatus()), () -> new ServiceException("订单已支付，不能取消"));
        orderMapper.updateById(Order.builder().id(orderId).status(OrderStatusEnum.CANCELLED.getValue()).build());
    }

    @Override
    public void refund(RefundBO refundBO) {
        Long orderId = refundBO.getOrderId();
        String refundReason = refundBO.getRefundReason();
        List<RefundBO.RefundItemBO> refundItemBoList = refundBO.getRefundItemBoList();
        Order order = refundBO.getOrder();
        // 修改订单状态
        orderMapper.updateById(Order.builder()
            .id(orderId)
            .aftersale(false)
            .payAmount(order.getPayAmount().subtract(refundBO.getTotalRefundAmount()))
            .status(OrderStatusEnum.REFUNDED_SUCCESS.getValue())
            .build());
        // 更新售后记录
        Aftersale aftersale = aftersaleMapper.selectOne(Wrappers.lambdaQuery(Aftersale.class)
            .eq(Aftersale::getOrderId, orderId).last("limit 1"));
        if(aftersale == null){
            aftersale = new Aftersale();
            aftersale.setMemberId(order.getMemberId());
            aftersale.setOrderId(orderId);
            aftersale.setOrgTrace(refundBO.getOrgTrace());
            aftersale.setReturnAmount(refundBO.getTotalRefundAmount());
            aftersale.setQuantity(refundItemBoList.size());
            aftersale.setType(1);
            aftersale.setStatus(AftersaleStatus.PAID.getCode());
            aftersale.setReason(refundReason);
            aftersale.setAuthFlag(2);
            aftersaleMapper.insert(aftersale);
        }else{
            aftersale.setReturnAmount(refundBO.getTotalRefundAmount());
            aftersale.setOrgTrace(refundBO.getOrgTrace());
            aftersale.setStatus(AftersaleStatus.PAID.getCode());
            aftersale.setQuantity(refundItemBoList.size());
            aftersaleMapper.updateById(aftersale);
        }
        Long aftersaleId = aftersale.getId();
        List<AftersaleItem> aftersaleItems = refundItemBoList.stream().map(item -> AftersaleItem.builder()
            .aftersaleId(aftersaleId)
            .memberId(order.getMemberId())
            .orderId(orderId)
            .orderItemId(item.getOrderItemId())
            .returnAmount(item.getRefundAmount())
            .quantity(item.getQuantity())
            .build()).toList();
        aftersaleItemMapper.insert(aftersaleItems);
    }

    /**
     * 生成订单sn
     */
    private String generateOrderSn() {
        String dateFormat = DatePattern.PURE_DATETIME_MS_FORMAT.format(new Date());
        return StrBuilder.create(ORDER_SN_PREFIX)
            .append(dateFormat)
            .append(RandomUtil.randomString(4))
            .toString();
    }

    /**
     * 修改订单表
     *
     * @param order 订单表
     * @return 结果
     */
    public R<Order> update(Order order) {
        int update = orderMapper.updateById(order);
        if (update > 1) {
            return R.fail("订单修改失败");
        } else {
            return R.ok(order);
        }
    }


    @Override
    public R saveMerchantNote(Order order) {
        // 1. 查询现有订单
        Order orderInDb = orderMapper.selectById(order.getId());
        if (orderInDb == null) {
            return R.fail("订单不存在");
        }

        // 2. 更新商家备注
        UpdateWrapper<Order> qw = new UpdateWrapper<>();
        qw.eq("id", order.getId());
        qw.set("merchant_note", order.getMerchantNote());
        int affectedRows = orderMapper.update(null, qw);

        if (affectedRows > 0) {
            orderMapper.selectById(order.getId());
            return R.ok();
        }
        return R.fail("更新失败");
    }


    /**
     * 根据订单id查询订单操作日志
     *
     * @param orderId 订单id
     * @return 结果
     */
    @Override
    public List<OrderOperateHistoryVO> log(Long orderId) {
        // 查询订单操作历史记录
        LambdaQueryWrapper<OrderOperateHistory> historyWrapper = new LambdaQueryWrapper<>();
        historyWrapper.eq(OrderOperateHistory::getOrderId, orderId);
        historyWrapper.orderByDesc(OrderOperateHistory::getCreateTime);
        List<OrderOperateHistory> historyList = orderOperateHistoryMapper.selectList(historyWrapper);

        // 关联查询订单状态
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.select(Order::getId, Order::getStatus);
        orderWrapper.eq(Order::getId, orderId);
        Order order = orderMapper.selectOne(orderWrapper);

        // 转换为VO对象
        List<OrderOperateHistoryVO> voList = new ArrayList<>();
        Integer orderStatus = order != null ? order.getStatus() : null;

        for (OrderOperateHistory history : historyList) {
            OrderOperateHistoryVO vo = new OrderOperateHistoryVO();
            BeanUtils.copyProperties(history, vo);
            vo.setStatus(orderStatus);
            voList.add(vo);
        }

        return voList;
    }

    @Override
    public R decryptPhone(Long orderId) {
        Order order = orderMapper.selectById(orderId);
        String receiverPhoneEncrypted = order.getReceiverPhoneEncrypted();
        if (receiverPhoneEncrypted != null) {
            return R.ok("操作成功", receiverPhoneEncrypted);
        } else {
            return R.fail("获取的电话号码加密字段为空");
        }
    }

    @Override
    public IPage<OrderVO> merchantOrderList(OrderBo query) {
        return null;
    }

    @Override
    public IPage<OrderVO> referenceMemberOrderList(OrderBo query) {
        Assert.isTrue(query.getCurrent() != null  && query.getSize() != null, "分页参数不能为空");
        if(StrUtil.isBlank(query.getTenantId())){
            query.setTenantId(TenantHelper.getTenantId());
        }
        IPage<OrderVO> resultPage = TenantHelper.ignore(() -> orderMapper.getlist(Page.of(query.getCurrent(), query.getSize()), query));
        List<OrderVO> orderVOList = resultPage.getRecords();
        if (orderVOList.isEmpty()) {
            return resultPage;
        }

        // 获取所有订单id
        List<Long> orderIds = orderVOList.stream()
            .map(OrderVO::getId)
            .collect(Collectors.toList());

        // 根据订单id查询订单详情
        QueryWrapper<OrderItem> orderItemQueryWrapper = new QueryWrapper<>();
        orderItemQueryWrapper.in("order_id", orderIds);
        List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQueryWrapper);

        // 按照订单id分组订单详情
        Map<Long, List<OrderItem>> orderItemMapByOrderId = orderItemList.stream()
            .collect(Collectors.groupingBy(OrderItem::getOrderId));

        // 获取所有sku_id
        List<Long> skuIds = orderItemList.stream()
            .map(OrderItem::getSkuId)
            .collect(Collectors.toList());

        // 根据sku_id查询pms_sku表数据
        QueryWrapper<Sku> skuQueryWrapper = new QueryWrapper<>();
        skuQueryWrapper.in("id", skuIds);
        List<Sku> skuList = skuMapper.selectList(skuQueryWrapper);

        Map<Long, Sku> skuMapById = skuList.stream()
            .collect(Collectors.toMap(Sku::getId, sku -> sku));

        for (OrderVO orderVO : orderVOList) {
            List<Map<String, Object>> productList = new ArrayList<>();
            List<OrderItem> orderItems = orderItemMapByOrderId.get(orderVO.getId());
            if (orderItems != null) {
                for (OrderItem orderItem : orderItems) {
                    Sku sku = skuMapById.get(orderItem.getSkuId());
                    if (sku != null) {
                        Map<String, Object> productMap = new HashMap<>();
                        productMap.put("price", sku.getPrice());
                        productMap.put("pic", sku.getPic());
                        productMap.put("stock", sku.getStock());
                        productMap.put("spData", sku.getSpData());
                        productList.add(productMap);
                    }
                }
            }
            orderVO.setProductList(productList);
        }

        return resultPage;
    }


    @Override
    public Order getByNo(String orderNo) {
        return baseMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderSn, orderNo));
    }

//    public void sendMessage(Order order) {
//       Long memberId = order.getMemberId();
//       Long orderId = order.getId();
//        // 订单创建成功模板ID
//        Long templateId =1940586928850100226L;
//        // 查询模板信息
//        SysMessageTemplateVo template = templateService.selectTemplateById(templateId);
//        log.info("模板信息为: {}", template);
//
//        if (template != null) {
//            Map<String, Object> params = new HashMap<>();
//            params.put("orderSn", order.getOrderSn());
//            params.put("productName", orderItemMapper.getName(orderId));
//            SysMessageBo messageBo = new SysMessageBo();
//            messageBo.setTemplateType(org.dromara.system.domain.MessageTemplateType.ORDER_NOTICE);
//            messageBo.setTemplateParams(params);
//            messageBo.setSenderId(memberId);
//            messageBo.setTitle(template.getTitle());
//            sysMessageService.sendMessageToUser(messageBo, memberId);
//        }
//    }

}

