package org.dromara.system.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.TblDzbcCargoItem;
import org.dromara.system.domain.TblDzbcCargoOrder;
import org.dromara.system.domain.TblDzbcDriverTrip;
import org.dromara.system.domain.TblDzbcSitePrice;
import org.dromara.system.domain.bo.CargoItemBo;
import org.dromara.system.domain.bo.CargoOrderSubmitBo;
import org.dromara.system.domain.bo.TblDzbcCargoOrderBo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.domain.vo.TblDzbcCargoItemVo;
import org.dromara.system.domain.vo.TblDzbcCargoOrderVo;
import org.dromara.system.domain.vo.TblDzbcDriverTripVo;
import org.dromara.system.domain.vo.TblDzbcSiteVo;
import org.dromara.system.mapper.TblDzbcCargoItemMapper;
import org.dromara.system.mapper.TblDzbcCargoOrderMapper;
import org.dromara.system.mapper.TblDzbcDriverTripMapper;
import org.dromara.system.mapper.TblDzbcSiteMapper;
import org.dromara.system.mapper.TblDzbcSitePriceMapper;
import org.dromara.system.service.ISysUserService;
import org.dromara.system.service.ITblDzbcCargoOrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 货物订单Service业务层处理
 *
 * @author Claude
 * @date 2026-01-15
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class TblDzbcCargoOrderServiceImpl implements ITblDzbcCargoOrderService {

    private final TblDzbcCargoOrderMapper baseMapper;
    private final TblDzbcCargoItemMapper cargoItemMapper;
    private final TblDzbcDriverTripMapper driverTripMapper;
    private final TblDzbcSitePriceMapper sitePriceMapper;
    private final ISysUserService userService;
    private final TblDzbcSiteMapper siteMapper;

    /**
     * 查询货物订单
     */
    @Override
    public TblDzbcCargoOrderVo queryById(Long id) {
        TblDzbcCargoOrderVo vo = baseMapper.selectVoById(id);
        if (vo != null) {
            fillCargoItems(vo);
            fillSiteNames(vo);
        }
        return vo;
    }

    /**
     * 查询货物订单列表
     */
    @Override
    public TableDataInfo<TblDzbcCargoOrderVo> queryPageList(TblDzbcCargoOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TblDzbcCargoOrder> lqw = buildQueryWrapper(bo);
        Page<TblDzbcCargoOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(this::fillCargoItems);
        result.getRecords().forEach(this::fillSiteNames);
        return TableDataInfo.build(result);
    }

    /**
     * 查询货物订单列表
     */
    @Override
    public List<TblDzbcCargoOrderVo> queryList(TblDzbcCargoOrderBo bo) {
        LambdaQueryWrapper<TblDzbcCargoOrder> lqw = buildQueryWrapper(bo);
        List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(lqw);
        list.forEach(this::fillCargoItems);
        list.forEach(this::fillSiteNames);
        return list;
    }

    /**
     * 根据司机任务ID查询订单列表
     */
    @Override
    public List<TblDzbcCargoOrderVo> queryByTripId(Long tripId) {
        // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByTripId
        List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
            .eq(TblDzbcCargoOrder::getTripId, tripId));
        list.forEach(this::fillCargoItems);
        return list;
    }

    /**
     * 根据用户ID查询订单列表
     */
    @Override
    public List<TblDzbcCargoOrderVo> queryByUserId(Long userId) {
        // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByUserId
        List<TblDzbcCargoOrderVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
            .eq(TblDzbcCargoOrder::getUserId, userId));
        list.forEach(this::fillCargoItems);
        return list;
    }

    /**
     * 提交货物订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TblDzbcCargoOrderVo submitOrder(CargoOrderSubmitBo bo) {
        // 验证司机任务
        TblDzbcDriverTripVo trip = driverTripMapper.selectByTripNo(bo.getTripNo());
        Assert.notNull(trip, "司机任务不存在");
        Assert.isTrue(trip.getStatus() != null && trip.getStatus() == 1, "任务未开始或已结束");

        // 创建订单
        TblDzbcCargoOrder order = new TblDzbcCargoOrder();
        order.setOrderNo(generateOrderNo());
        order.setTripId(trip.getId());
        order.setTripNo(bo.getTripNo());
        order.setUserId(LoginHelper.getUserId());

        SysUserVo user = userService.selectUserById(order.getUserId());
        Assert.notNull(user, "用户不存在");

        // 设置用户信息（这里假设从登录信息获取，实际可能需要查询用户表）
        order.setUserName(user.getUserName());
        order.setUserPhone(user.getPhonenumber());

        order.setSenderName(bo.getSenderName());
        order.setSenderPhone(bo.getSenderPhone());
        order.setReceiverName(bo.getReceiverName());
        order.setReceiverPhone(bo.getReceiverPhone());
        order.setFromSiteId(bo.getFromSiteId());
        order.setToSiteId(bo.getToSiteId());

        // 设置货物信息
        if (bo.getItems() != null && !bo.getItems().isEmpty()) {
            order.setCargoCount(bo.getItems().size());
            // 计算总重量和总价值
            double totalWeight = 0;
            double totalValue = 0;
            for (CargoItemBo item : bo.getItems()) {
                if (item.getWeight() != null) {
                    totalWeight += item.getWeight().doubleValue();
                }
                if (item.getValue() != null) {
                    totalValue += item.getValue().doubleValue();
                }
            }
            order.setCargoWeight(new java.math.BigDecimal(totalWeight));
            order.setCargoValue(new java.math.BigDecimal(totalValue));
        }

        // 计算价格 - 根据起始站点和送达站点从价格表 ext2 获取带货价格
        TblDzbcSitePrice sitePrice = sitePriceMapper.selectOne(new LambdaQueryWrapper<TblDzbcSitePrice>()
            .eq(TblDzbcSitePrice::getPathId, trip.getPathId())
            .eq(TblDzbcSitePrice::getFromSiteId, bo.getFromSiteId())
            .eq(TblDzbcSitePrice::getToSiteId, bo.getToSiteId())
            .last("LIMIT 1"));

        int freightPrice = 0;
        if (sitePrice != null && StrUtil.isNotBlank(sitePrice.getExt2())) {
            try {
                // ext2 是 JSON 格式，需要解析获取 cargoPrice
                cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(sitePrice.getExt2());
                if (jsonObject.containsKey("cargoPrice")) {
                    freightPrice = jsonObject.getInt("cargoPrice", 0);
                }
            } catch (Exception e) {
                log.error("Failed to parse cargoPrice from ext2 JSON for site price id: {}", sitePrice.getId(), e);
            }
        }
        order.setPrice(freightPrice);

        order.setPayStatus(0); // 待支付
        order.setStatus(0); // 待发货
        order.setRemark(bo.getRemark());

        // 保存订单
        baseMapper.insert(order);

        // 保存货物明细
        if (bo.getItems() != null && !bo.getItems().isEmpty()) {
            for (CargoItemBo itemBo : bo.getItems()) {
                TblDzbcCargoItem item = new TblDzbcCargoItem();
                item.setOrderId(order.getId());
                item.setOrderNo(order.getOrderNo());
                item.setCargoName(itemBo.getCargoName());
                item.setCargoType(itemBo.getCargoType());
                item.setQuantity(itemBo.getQuantity());
                item.setUnit(itemBo.getUnit());
                item.setWeight(itemBo.getWeight());
                item.setLength(itemBo.getLength());
                item.setWidth(itemBo.getWidth());
                item.setHeight(itemBo.getHeight());
                item.setValue(itemBo.getValue());
                if (itemBo.getImages() != null && !itemBo.getImages().isEmpty()) {
                    item.setImageUrls(JSONUtil.toJsonStr(itemBo.getImages()));
                }
                item.setRemark(itemBo.getRemark());
                cargoItemMapper.insert(item);
            }
        }

        // 更新司机任务的货物统计
        updateTripCargoStats(trip.getId());

        // 返回完整订单信息
        return queryById(order.getId());
    }

    /**
     * 修改货物订单
     */
    @Override
    public Boolean updateByBo(TblDzbcCargoOrderBo bo) {
        TblDzbcCargoOrder update = MapstructUtils.convert(bo, TblDzbcCargoOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 更新订单状态
     */
    @Override
    public Boolean updateStatus(Long id, Integer status) {
        // 如果是取货操作(status=1)，需要校验是否已支付
        if (status == 1) {
            TblDzbcCargoOrder order = baseMapper.selectById(id);
            if (order == null) {
                throw new ServiceException("订单不存在");
            }
            // 如果价格大于0且未支付
            if (order.getPrice() != null && order.getPrice() > 0 && (order.getPayStatus() == null || order.getPayStatus() != 1)) {
                throw new ServiceException("订单未支付，无法取货");
            }
        }
        TblDzbcCargoOrder order = new TblDzbcCargoOrder();
        order.setId(id);
        order.setStatus(status);
        return baseMapper.updateById(order) > 0;
    }

    /**
     * 批量删除货物订单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<TblDzbcCargoOrder> buildQueryWrapper(TblDzbcCargoOrderBo bo) {
        LambdaQueryWrapper<TblDzbcCargoOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, TblDzbcCargoOrder::getId, bo.getId());
        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), TblDzbcCargoOrder::getOrderNo, bo.getOrderNo());
        lqw.eq(bo.getTripId() != null, TblDzbcCargoOrder::getTripId, bo.getTripId());
        lqw.eq(StringUtils.isNotBlank(bo.getTripNo()), TblDzbcCargoOrder::getTripNo, bo.getTripNo());
        lqw.eq(bo.getUserId() != null, TblDzbcCargoOrder::getUserId, bo.getUserId());
        lqw.eq(bo.getFromSiteId() != null, TblDzbcCargoOrder::getFromSiteId, bo.getFromSiteId());
        lqw.eq(bo.getToSiteId() != null, TblDzbcCargoOrder::getToSiteId, bo.getToSiteId());
        lqw.eq(bo.getPayStatus() != null, TblDzbcCargoOrder::getPayStatus, bo.getPayStatus());
        lqw.eq(bo.getStatus() != null, TblDzbcCargoOrder::getStatus, bo.getStatus());

        if (bo.getParams() != null) {
            // 处理时间范围查询等额外参数
            if (bo.getParams().containsKey("beginTime")) {
                lqw.ge(TblDzbcCargoOrder::getCreateTime, bo.getParams().get("beginTime"));
            }
            if (bo.getParams().containsKey("endTime")) {
                lqw.le(TblDzbcCargoOrder::getCreateTime, bo.getParams().get("endTime"));
            }
        }

        lqw.orderByDesc(TblDzbcCargoOrder::getCreateTime);
        return lqw;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TblDzbcCargoOrder entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    /**
     * 填充货物明细
     */
    private void fillCargoItems(TblDzbcCargoOrderVo vo) {
        if (vo == null) {
            return;
        }
        // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByOrderId
        List<TblDzbcCargoItemVo> items = cargoItemMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoItem>()
            .eq(TblDzbcCargoItem::getOrderId, vo.getId()));
        vo.setItems(items);
    }

    /**
     * 填充站点名称
     */
    private void fillSiteNames(TblDzbcCargoOrderVo vo) {
        if (vo == null) {
            return;
        }
        if (vo.getFromSiteId() != null) {
            TblDzbcSiteVo fromSite = siteMapper.selectVoById(vo.getFromSiteId());
            if (fromSite != null) {
                vo.setFromSiteName(fromSite.getName());
            }
        }
        if (vo.getToSiteId() != null) {
            TblDzbcSiteVo toSite = siteMapper.selectVoById(vo.getToSiteId());
            if (toSite != null) {
                vo.setToSiteName(toSite.getName());
            }
        }
    }

    /**
     * 更新司机任务的货物统计
     */
    private void updateTripCargoStats(Long tripId) {
        // 使用 LambdaQueryWrapper 替代未实现的 XML 方法 selectByTripId
        List<TblDzbcCargoOrderVo> orders = baseMapper.selectVoList(new LambdaQueryWrapper<TblDzbcCargoOrder>()
            .eq(TblDzbcCargoOrder::getTripId, tripId));
        int cargoCount = orders.size();
        int totalPrice = orders.stream()
            .mapToInt(order -> order.getPrice() != null ? order.getPrice() : 0)
            .sum();

        TblDzbcDriverTrip trip = new TblDzbcDriverTrip();
        trip.setId(tripId);
        trip.setCargoCount(cargoCount);
        trip.setCargoTotalPrice(totalPrice);
        driverTripMapper.updateById(trip);
    }

    /**
     * 生成订单编号
     */
    private String generateOrderNo() {
        return "CARGO" + cn.hutool.core.date.DateUtil.format(cn.hutool.core.date.DateUtil.date(), "yyyyMMddHHmmss")
               + IdUtil.getSnowflakeNextIdStr().substring(8);
    }
}
