package com.yc.ship.module.trade.service.orderjzdetail;

import cn.hutool.core.date.DatePattern;
import com.alibaba.excel.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.OrderGiftVisitorPageReqVO;
import com.yc.ship.module.trade.controller.admin.orderjzdetail.vo.*;
import com.yc.ship.module.trade.dal.dataobject.orderjzdetail.OrderGiftVisitorDO;
import com.yc.ship.module.trade.dal.dataobject.orderjzdispatch.OrderJzDispatchDO;
import com.yc.ship.module.trade.dal.mysql.orderjz.OrderGiftVisitorMapper;
import com.yc.ship.module.trade.dal.mysql.orderjzdispatch.OrderJzDispatchMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 蹭送行程游客 Service 实现类
 *
 * @author yc
 */
@Service
@Validated
@Slf4j
public class OrderGiftVisitorServiceImpl implements OrderGiftVisitorService {

    @Resource
    private OrderGiftVisitorMapper orderGiftVisitorMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrderGiftVisitor(OrderGiftVisitorSaveReqVO createReqVO) {
        // 校验唯一性
        OrderGiftVisitorDO existing = orderGiftVisitorMapper.selectByVisitorIdAndVoyageId(
            createReqVO.getVisitorId(), createReqVO.getVoyageId());
        if (existing != null) {
            throw new RuntimeException("该游客已存在蹭送行程记录");
        }

        // 插入
        OrderGiftVisitorDO orderGiftVisitor = OrderGiftVisitorDO.builder()
                .voyageId(createReqVO.getVoyageId())
                .visitorId(createReqVO.getVisitorId())
                .orderId(createReqVO.getOrderId())
                .dispatchId(createReqVO.getDispatchId() != null ? createReqVO.getDispatchId() : 0L)
                .address(createReqVO.getAddress())
                .arriveTime(createReqVO.getArriveTime())
                .signRemark(createReqVO.getSignRemark())
                .signImage(createReqVO.getSignImage())
                .remark(createReqVO.getRemark())
                .build();
        orderGiftVisitorMapper.insert(orderGiftVisitor);
        return orderGiftVisitor.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchCreateOrderGiftVisitor(List<OrderGiftVisitorSaveReqVO> createReqVOList) {
        if (createReqVOList == null || createReqVOList.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        for (OrderGiftVisitorSaveReqVO createReqVO : createReqVOList) {
            try {
                createOrderGiftVisitor(createReqVO);
                successCount++;
            } catch (Exception e) {
                log.warn("批量创建蹭送行程游客失败: visitorId={}, voyageId={}", 
                    createReqVO.getVisitorId(), createReqVO.getVoyageId(), e);
            }
        }
        return successCount;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderGiftVisitor(OrderGiftVisitorSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderGiftVisitorExists(updateReqVO.getId());
        
        // 更新
        OrderGiftVisitorDO updateObj = OrderGiftVisitorDO.builder()
                .id(updateReqVO.getId())
                .voyageId(updateReqVO.getVoyageId())
                .visitorId(updateReqVO.getVisitorId())
                .orderId(updateReqVO.getOrderId())
                .dispatchId(updateReqVO.getDispatchId() != null ? updateReqVO.getDispatchId() : 0L)
                .address(updateReqVO.getAddress())
                .arriveTime(updateReqVO.getArriveTime())
                .signRemark(updateReqVO.getSignRemark())
                .signImage(updateReqVO.getSignImage())
                .remark(updateReqVO.getRemark())
                .build();
        orderGiftVisitorMapper.updateById(updateObj);
    }



    private void validateOrderGiftVisitorExists(Long id) {
        if (orderGiftVisitorMapper.selectById(id) == null) {
            throw new RuntimeException("蹭送行程游客记录不存在");
        }
    }

    @Override
    public OrderGiftVisitorDO getOrderGiftVisitor(Long id) {
        return orderGiftVisitorMapper.selectById(id);
    }

    @Override
    public PageResult<OrderGiftVisitorDO> getOrderGiftVisitorPage(OrderGiftVisitorPageReqVO pageReqVO) {
        IPage<OrderGiftVisitorDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        IPage<OrderGiftVisitorDO> resultPage = orderGiftVisitorMapper.selectPageWithVisitor(page, pageReqVO);
        return new PageResult<>(resultPage.getRecords(), resultPage.getTotal());
    }

    @Override
    public List<OrderGiftVisitorDO> getExportList(OrderGiftVisitorPageReqVO pageReqVO) {
        return orderGiftVisitorMapper.selectExportList(pageReqVO);
    }

    @Override
    public IPage<OrderGiftVisitorDO> getGiftOrderPage(OrderGiftVisitorPageReqVO pageReqVO) {
        // 复用分页查询方法,只用于补登订单查询
        IPage<OrderGiftVisitorDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        return orderGiftVisitorMapper.selectPageWithVisitor(page, pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void signOrderGiftVisitor(OrderGiftVisitorSaveReqVO signReqVO) {
        // 校验存在
        // validateOrderGiftVisitorExists(id);


        if (signReqVO.getId() == null || signReqVO.getId() == 0) {
            OrderGiftVisitorDO insertObj = OrderGiftVisitorDO.builder()
                    .signTime(DateUtils.format(new Date(), DatePattern.NORM_DATETIME_PATTERN))
                    .signRemark(signReqVO.getSignRemark())
                    .signImage(signReqVO.getSignImage())
                    .visitorId(signReqVO.getVisitorId())
                    .voyageId(signReqVO.getVoyageId())
                    .orderId(signReqVO.getOrderId())
                    .build();
            orderGiftVisitorMapper.insert(insertObj);
        } else {
            // 更新签到信息
            OrderGiftVisitorDO updateObj = OrderGiftVisitorDO.builder()
                    .id(signReqVO.getId())
                    .signTime(DateUtils.format(new Date(), DatePattern.NORM_DATETIME_PATTERN))
                    .signRemark(signReqVO.getSignRemark())
                    .signImage(signReqVO.getSignImage())
                    .visitorId(signReqVO.getVisitorId())
                    .voyageId(signReqVO.getVoyageId())
                    .orderId(signReqVO.getOrderId())
                    .build();
            orderGiftVisitorMapper.updateById(updateObj);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cleanSign(Long id) {
        // 校验存在
        validateOrderGiftVisitorExists(id);
        
        // 清除签到信息
        orderGiftVisitorMapper.cleanSignById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchSignOrderGiftVisitor(List<OrderJzDetailBatchSignReqVO.SignItem> items, String signRemark) {
        if (items == null || items.isEmpty()) {
            return 0;
        }

        // 批量查询所有记录ID（只查有id的，即已存在的记录），过滤已核销的
        List<Long> ids = items.stream()
                .filter(item -> item.getId() != null && item.getId() > 0)
                .map(OrderJzDetailBatchSignReqVO.SignItem::getId)
                .collect(Collectors.toList());
        List<Long> alreadySignedIds = Collections.emptyList();
        if (!ids.isEmpty()) {
            List<OrderGiftVisitorDO> visitorList = orderGiftVisitorMapper.selectBatchIds(ids);
            alreadySignedIds = visitorList.stream()
                    .filter(v -> v.getSignTime() != null)
                    .map(OrderGiftVisitorDO::getId)
                    .collect(Collectors.toList());
        }
        // 过滤掉已核销的条目，只处理未核销的
        final List<Long> signedIds = alreadySignedIds;
        List<OrderJzDetailBatchSignReqVO.SignItem> unsignedItems = items.stream()
                .filter(item -> item.getId() == null || item.getId() == 0 || !signedIds.contains(item.getId()))
                .collect(Collectors.toList());
        if (unsignedItems.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        for (OrderJzDetailBatchSignReqVO.SignItem item : unsignedItems) {
            try {
                // 构造单个签到的请求VO，复用单个签到逻辑
                OrderGiftVisitorSaveReqVO signReqVO = new OrderGiftVisitorSaveReqVO();
                signReqVO.setId(item.getId());
                signReqVO.setVisitorId(item.getVisitorId());
                signReqVO.setVoyageId(item.getVoyageId());
                signReqVO.setOrderId(item.getOrderId());
                signReqVO.setSignRemark(signRemark);
                // 执行单个签到
                signOrderGiftVisitor(signReqVO);
                successCount++;
            } catch (Exception e) {
                log.warn("批量签到失败: visitorId={}, orderId={}", item.getVisitorId(), item.getOrderId(), e);
            }
        }
        log.info("批量签到完成: 成功={}, 请求={}", successCount, items.size());
        return successCount;
    }




    @Resource
    private OrderJzDispatchMapper orderJzDispatchMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createGiftDispatch(OrderJzDispatchSaveReqVO createReqVO, Long visitorId) {
        // 创建分车记录（source_type=2）
        OrderJzDispatchDO dispatchDO = OrderJzDispatchDO.builder()
                .voyageId(createReqVO.getVoyageId())
                .dispatchNo(createReqVO.getDispatchNo())
                .groupNo(createReqVO.getGroupNo())
                .busNumber(createReqVO.getBusNumber())
                .driverName(createReqVO.getDriverName())
                .driverPhone(createReqVO.getDriverPhone())
                .receiverName(createReqVO.getReceiverName())
                .receiverPhone(createReqVO.getReceiverPhone())
                .sourceType(2) // 蹭送行程
                .passengerCount(1)
                .remark(createReqVO.getRemark())
                .dispatchTime(LocalDateTime.now())
                .build();
        orderJzDispatchMapper.insert(dispatchDO);

        // 更新蹭送行程游客的分车ID
        OrderGiftVisitorDO visitorDO = orderGiftVisitorMapper.selectByVisitorIdAndVoyageId(
                visitorId, createReqVO.getVoyageId());
        if (visitorDO != null) {
            OrderGiftVisitorDO updateVisitor = OrderGiftVisitorDO.builder()
                    .id(visitorDO.getId())
                    .dispatchId(dispatchDO.getId())
                    .build();
            orderGiftVisitorMapper.updateById(updateVisitor);
        }

        return dispatchDO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchSaveGiftDispatch(OrderJzDispatchBatchReqVO batchReqVO) {
        if (batchReqVO.getOrderItems() == null || batchReqVO.getOrderItems().isEmpty()) {
            return 0;
        }

        OrderJzDispatchBatchReqVO.DispatchInfo dispatchInfo = batchReqVO.getDispatchInfo();
        if (dispatchInfo == null) {
            throw new RuntimeException("分车信息不能为空");
        }

        // 确保source_type=2（蹭送行程）
        dispatchInfo.setSourceType(2);

        // 查找是否已有相同分车号、航次、分车类型的分车记录
        LambdaQueryWrapper<OrderJzDispatchDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderJzDispatchDO::getDispatchNo, dispatchInfo.getDispatchNo())
                .eq(OrderJzDispatchDO::getVoyageId, dispatchInfo.getVoyageId())
                .eq(OrderJzDispatchDO::getSourceType, 2);

        if (dispatchInfo.getGroupNo() != null && !dispatchInfo.getGroupNo().isEmpty()) {
            wrapper.eq(OrderJzDispatchDO::getGroupNo, dispatchInfo.getGroupNo());
        }

        OrderJzDispatchDO existingDispatch = orderJzDispatchMapper.selectOne(wrapper);
        Long dispatchId;

        if (existingDispatch != null) {
            // 更新已有分车记录
            dispatchId = existingDispatch.getId();
            OrderJzDispatchDO updateDispatch = OrderJzDispatchDO.builder()
                    .id(dispatchId)
                    .busNumber(dispatchInfo.getBusNumber())
                    .driverName(dispatchInfo.getDriverName())
                    .driverPhone(dispatchInfo.getDriverPhone())
                    .receiverName(dispatchInfo.getReceiverName())
                    .receiverPhone(dispatchInfo.getReceiverPhone())
                    .passengerCount(existingDispatch.getPassengerCount() + batchReqVO.getOrderItems().size())
                    .remark(dispatchInfo.getRemark())
                    .build();
            orderJzDispatchMapper.updateById(updateDispatch);
        } else {
            // 创建新的分车记录
            OrderJzDispatchDO newDispatch = OrderJzDispatchDO.builder()
                    .voyageId(dispatchInfo.getVoyageId())
                    .dispatchNo(dispatchInfo.getDispatchNo())
                    .groupNo(dispatchInfo.getGroupNo())
                    .busNumber(dispatchInfo.getBusNumber())
                    .driverName(dispatchInfo.getDriverName())
                    .driverPhone(dispatchInfo.getDriverPhone())
                    .receiverName(dispatchInfo.getReceiverName())
                    .receiverPhone(dispatchInfo.getReceiverPhone())
                    .sourceType(2)
                    .passengerCount(batchReqVO.getOrderItems().size())
                    .remark(dispatchInfo.getRemark())
                    .dispatchTime(LocalDateTime.now())
                    .build();
            orderJzDispatchMapper.insert(newDispatch);
            dispatchId = newDispatch.getId();
        }

        // 批量更新蹭送行程游客的分车ID
        int successCount = 0;
        for (OrderJzDispatchBatchReqVO.OrderItem orderItem : batchReqVO.getOrderItems()) {
            try {
                Long visitorRecordId = orderItem.getId();
                // 如果id为空或0，先按visitorId+voyageId查询是否已有记录
                if (visitorRecordId == null || visitorRecordId == 0) {
                    OrderGiftVisitorDO existing = orderGiftVisitorMapper.selectByVisitorIdAndVoyageId(
                            orderItem.getVisitorId(), orderItem.getVoyageId());
                    if (existing != null) {
                        visitorRecordId = existing.getId();
                    } else {
                        // 不存在则新增
                        OrderGiftVisitorSaveReqVO createReqVO = new OrderGiftVisitorSaveReqVO();
                        createReqVO.setVisitorId(orderItem.getVisitorId());
                        createReqVO.setVoyageId(orderItem.getVoyageId());
                        createReqVO.setOrderId(orderItem.getOrderId());
                        visitorRecordId = createOrderGiftVisitor(createReqVO);
                    }
                }

                // 校验是否已分车
                OrderGiftVisitorDO visitorDO = orderGiftVisitorMapper.selectById(visitorRecordId);
                if (visitorDO != null && visitorDO.getDispatchId() != null && visitorDO.getDispatchId() > 0) {
                    log.warn("游客已分车: visitorRecordId={}", visitorRecordId);
                    continue;
                }

                // 更新分车ID
                OrderGiftVisitorDO updateVisitor = OrderGiftVisitorDO.builder()
                        .id(visitorRecordId)
                        .dispatchId(dispatchId)
                        .build();
                orderGiftVisitorMapper.updateById(updateVisitor);
                successCount++;
            } catch (Exception e) {
                log.error("批量分车失败: visitorId={}", orderItem.getVisitorId(), e);
            }
        }

        return successCount;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGiftDispatch(OrderJzDispatchSaveReqVO updateReqVO) {
        // 更新分车记录
        OrderJzDispatchDO updateDispatch = OrderJzDispatchDO.builder()
                .id(updateReqVO.getId())
                .busNumber(updateReqVO.getBusNumber())
                .driverName(updateReqVO.getDriverName())
                .driverPhone(updateReqVO.getDriverPhone())
                .receiverName(updateReqVO.getReceiverName())
                .receiverPhone(updateReqVO.getReceiverPhone())
                .remark(updateReqVO.getRemark())
                .build();
        orderJzDispatchMapper.updateById(updateDispatch);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGiftDispatchByVisitorId(Long id) {
        // 查询游客的分车记录
        OrderGiftVisitorDO visitorDO = orderGiftVisitorMapper.selectById(id);
        if (visitorDO == null || visitorDO.getDispatchId() == null || visitorDO.getDispatchId() == 0) {
            throw new RuntimeException("游客未分车");
        }

        Long dispatchId = visitorDO.getDispatchId();
        // 更新游客的分车ID为0
        OrderGiftVisitorDO updateVisitor = OrderGiftVisitorDO.builder()
                .id(id)
                .dispatchId(0L)
                .build();
        orderGiftVisitorMapper.updateById(updateVisitor);


        // 统计该分车记录还有多少游客
        Integer count = orderGiftVisitorMapper.countByDispatchId(dispatchId);
        if (count == 0) {
            // 如果没有游客了，物理删除分车记录
            orderJzDispatchMapper.deleteById(dispatchId);
        } else {
            // 减少乘客人数
            OrderJzDispatchDO dispatchDO = orderJzDispatchMapper.selectById(dispatchId);
            if (dispatchDO != null) {
                OrderJzDispatchDO updateDispatch = OrderJzDispatchDO.builder()
                        .id(dispatchId)
                        .passengerCount(Math.max(1, count))
                        .build();
                orderJzDispatchMapper.updateById(updateDispatch);
            }
        }
    }

    @Override
    public PageResult<OrderJzDispatchRecordRespVO> getGiftDispatchRecordPage(OrderJzDispatchPageReqVO pageReqVO) {
        // 查询 source_type=2 的分车记录
        LambdaQueryWrapper<OrderJzDispatchDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderJzDispatchDO::getSourceType, 2)
                .eq(OrderJzDispatchDO::getVoyageId, pageReqVO.getVoyageId());

        if (pageReqVO.getDispatchNo() != null && !pageReqVO.getDispatchNo().isEmpty()) {
            wrapper.like(OrderJzDispatchDO::getDispatchNo, pageReqVO.getDispatchNo());
        }

        if (pageReqVO.getGroupNo() != null && !pageReqVO.getGroupNo().isEmpty()) {
            wrapper.eq(OrderJzDispatchDO::getGroupNo, pageReqVO.getGroupNo());
        }

        wrapper.orderByDesc(OrderJzDispatchDO::getDispatchTime);

        List<OrderJzDispatchDO> list = orderJzDispatchMapper.selectList(wrapper);

        // 转换为VO
        List<OrderJzDispatchRecordRespVO> voList = list.stream()
                .map(dispatch -> OrderJzDispatchRecordRespVO.builder()
                        .id(dispatch.getId())
                        .dispatchNo(dispatch.getDispatchNo())
                        .groupNo(dispatch.getGroupNo())
                        .busNumber(dispatch.getBusNumber())
                        .driverName(dispatch.getDriverName())
                        .driverPhone(dispatch.getDriverPhone())
                        .receiverName(dispatch.getReceiverName())
                        .receiverPhone(dispatch.getReceiverPhone())
                        .passengerCount(dispatch.getPassengerCount())
                        .remark(dispatch.getRemark())
                        .build())
                .collect(Collectors.toList());

        return new PageResult<>(voList, (long) voList.size());
    }

    @Override
    public List<OrderJzDispatchRecordRespVO> getExportGiftDispatchList(OrderJzDispatchPageReqVO pageReqVO) {
        PageResult<OrderJzDispatchRecordRespVO> pageResult = getGiftDispatchRecordPage(pageReqVO);
        return pageResult.getList();
    }
}
