package com.ruoyi.bst.order.service.impl;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.bst.app.domain.AppVO;
import com.ruoyi.bst.app.service.AppService;
import com.ruoyi.bst.area.domain.AreaVO;
import com.ruoyi.bst.area.service.AreaService;
import com.ruoyi.bst.areaJoin.domain.AreaJoinVO;
import com.ruoyi.bst.areaJoin.domain.enums.AreaJoinType;
import com.ruoyi.bst.areaJoin.service.AreaJoinService;
import com.ruoyi.bst.areaSub.domain.AreaSubVO;
import com.ruoyi.bst.areaSub.service.AreaSubService;
import com.ruoyi.bst.channel.domain.ChannelVO;
import com.ruoyi.bst.channel.domain.enums.ChannelApiType;
import com.ruoyi.bst.channel.domain.enums.ChannelBstType;
import com.ruoyi.bst.channel.service.ChannelService;
import com.ruoyi.bst.creditUser.domain.CreditUserVO;
import com.ruoyi.bst.creditUser.service.CreditUserService;
import com.ruoyi.bst.device.domain.DeviceVO;
import com.ruoyi.bst.device.service.DeviceAssembler;
import com.ruoyi.bst.device.service.DeviceService;
import com.ruoyi.bst.locationLog.domain.vo.LocationLogPositionVO;
import com.ruoyi.bst.locationLog.service.LocationLogService;
import com.ruoyi.bst.model.domain.ModelVO;
import com.ruoyi.bst.model.service.ModelAssembler;
import com.ruoyi.bst.model.service.ModelService;
import com.ruoyi.bst.order.domain.Order;
import com.ruoyi.bst.order.domain.OrderVO;
import com.ruoyi.bst.order.domain.bo.OrderChangeBO;
import com.ruoyi.bst.order.domain.bo.OrderCreateBO;
import com.ruoyi.bst.order.domain.bo.OrderDeductBO;
import com.ruoyi.bst.order.domain.bo.OrderEndBO;
import com.ruoyi.bst.order.domain.bo.OrderPayBO;
import com.ruoyi.bst.order.domain.bo.OrderPayRideFeeBO;
import com.ruoyi.bst.order.domain.dto.OrderCalcPrePriceDTO;
import com.ruoyi.bst.order.domain.dto.OrderChangeDeviceDTO;
import com.ruoyi.bst.order.domain.dto.OrderCreateDTO;
import com.ruoyi.bst.order.domain.dto.OrderDeductDTO;
import com.ruoyi.bst.order.domain.dto.OrderEndDTO;
import com.ruoyi.bst.order.domain.dto.OrderPayDTO;
import com.ruoyi.bst.order.domain.dto.OrderPayRideFeeDTO;
import com.ruoyi.bst.order.domain.enums.OrderStatus;
import com.ruoyi.bst.order.domain.vo.OrderCalcRideFeeVO;
import com.ruoyi.bst.order.domain.vo.OrderInParkingVO;
import com.ruoyi.bst.order.domain.vo.OrderPrePriceVO;
import com.ruoyi.bst.order.service.OrderConverter;
import com.ruoyi.bst.order.service.OrderDashboard;
import com.ruoyi.bst.order.service.OrderService;
import com.ruoyi.bst.order.service.OrderValidator;
import com.ruoyi.bst.order.utils.OrderUtil;
import com.ruoyi.bst.orderDevice.domain.OrderDevice;
import com.ruoyi.bst.orderDevice.domain.OrderDeviceVO;
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceStatus;
import com.ruoyi.bst.orderDevice.domain.enums.OrderDeviceType;
import com.ruoyi.bst.orderDevice.service.OrderDeviceService;
import com.ruoyi.bst.orderDevice.utils.OrderDeviceUtil;
import com.ruoyi.bst.suit.domain.SuitVO;
import com.ruoyi.bst.suit.domain.enums.SuitType;
import com.ruoyi.bst.suit.service.SuitService;
import com.ruoyi.bst.userApp.domain.UserAppVO;
import com.ruoyi.bst.userApp.service.UserAppService;
import com.ruoyi.bst.vipUser.domain.VipUserVO;
import com.ruoyi.bst.vipUser.service.VipUserService;
import com.ruoyi.common.core.domain.vo.UserVO;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.user.service.UserService;

@Service
public class OrderConverterImpl implements OrderConverter{

    @Autowired
    private SuitService suitService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private UserService userService;

    @Autowired
    private AreaJoinService areaJoinService;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private AppService appService;

    @Autowired
    private UserAppService userAppService;

    @Autowired
    private AreaService areaService;

    @Autowired
    private AreaSubService areaSubService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private LocationLogService locationLogService;

    @Autowired
    private OrderDeviceService orderDeviceService;

    @Autowired
    private OrderValidator orderValidator;

    @Autowired
    private ModelService modelService;

    @Autowired
    private ModelAssembler modelAssembler;

    @Autowired
    private DeviceAssembler deviceAssembler;

    @Autowired
    private OrderDashboard orderDashboard;

    @Autowired
    private VipUserService vipUserService;

    @Autowired
    private CreditUserService creditUserService;

    @Override
    public OrderPrePriceVO toOrderPrePriceVO(OrderCalcPrePriceDTO dto) {
        if (dto == null) {
            return null;
        }
        // 查询套餐
        SuitVO suit = suitService.selectSuitById(dto.getSuitId());
        // 查询渠道
        ChannelVO channel = channelService.selectChannelByChannelId(dto.getChannelId());
        // 计算价格
        return OrderUtil.calcPrePrice(suit, channel);
    }

    @Override
    public OrderCreateBO toCreateBO(OrderCreateDTO dto) {
        if (dto == null) {
            return null;
        }
        OrderCreateBO bo = new OrderCreateBO();
        bo.setDto(dto);

        // 套餐
        SuitVO suit = suitService.selectSuitById(dto.getSuitId());
        bo.setSuit(suit);

        // 设备
        DeviceVO device = deviceService.selectDeviceById(dto.getDeviceId());
        bo.setDevice(device);

        if (device != null) {
            // 运营区
            AreaVO area = areaService.selectAreaById(device.getAreaId());
            bo.setArea(area);

            // 车型
            ModelVO model = modelService.selectModelById(device.getModelId());
            modelAssembler.assembleSuitIds(Collections.singletonList(model));
            bo.setModel(model);

            // 查询设备所属人的加盟信息
            AreaJoinVO areaJoin = areaJoinService.selectByUserArea(device.getMchId(), device.getAreaId());
            bo.setAreaJoin(areaJoin);

            // 查询运营区的合伙人列表
            List<AreaJoinVO> partners = areaJoinService.selectListByAreaId(device.getAreaId(), AreaJoinType.PARTNER.getCode());
            bo.setPartners(partners);
        }

        // 用户
        UserVO user = userService.selectUserById(dto.getUserId());
        bo.setUser(user);

        // 未支付骑行费的订单
        if (user != null) {
            bo.setUnpaidCount(orderDashboard.selectUnpaidCountByUserId(user.getUserId()));
        }

        // 用户进行中的订单设备
        OrderDeviceVO userOrderDevice = orderDeviceService.selectUsingByUserId(dto.getUserId());
        bo.setUserOrderDevice(userOrderDevice);

        // 查询渠道
        ChannelVO channel = channelService.selectChannelByChannelId(dto.getChannelId());
        bo.setChannel(channel);

        // 价格信息
        OrderPrePriceVO prePrice = OrderUtil.calcPrePrice(bo.getSuit(), bo.getChannel());
        bo.setPrePrice(prePrice);

        // 查询应用
        AppVO app = appService.selectAppById(dto.getAppId());
        bo.setApp(app);

        // 查询用户应用信息
        if (user != null && app != null) {
            UserAppVO userApp = userAppService.selectByUserApp(user.getUserId(), app.getId());
            bo.setUserApp(userApp);
        }

        // 查询挂账
        if (channel != null && ChannelApiType.CREDIT.getType().equals(channel.getApiType())) {
            CreditUserVO creditUser = creditUserService.selectCreditUserById(dto.getCreditUserId());
            bo.setCreditUser(creditUser);
        }

        // 生成订单
        Order order = this.generateOrder(bo);
        bo.setOrder(order);

        // 生成订单设备
        OrderDevice orderDevice = this.generateOrderDevice(bo);
        bo.setOrderDevice(orderDevice);

        // 查询渠道支付列表
        bo.setChannelPayList(channelService.selectPayChannelList(order.getUserId(), order.getAreaId(), dto.getAppId(), ChannelBstType.ORDER_DEPOSIT.getCode()));

        return bo;
    }

    // 生成订单设备
    private OrderDevice generateOrderDevice(OrderCreateBO bo) {
        if (bo == null) {
            return null;
        }
        OrderDevice orderDevice = new OrderDevice();

        // 设备
        DeviceVO device = bo.getDevice();
        orderDevice.setType(OrderDeviceType.ORIGINAL.getCode());
        orderDevice.setStatus(OrderDeviceStatus.WAIT_USE.getCode());
        OrderDeviceUtil.setDeviceInfo(orderDevice, device);
        return orderDevice;
    }

    // 生成订单
    private Order generateOrder(OrderCreateBO bo) {
        if (bo == null) {
            return null;
        }
        Order order = new Order();
        // 基础信息
        order.setPayExpireTime(LocalDateTime.now().plusMinutes(3));
        order.setVersion(2);

        // 用户信息
        UserVO user = bo.getUser();
        if (user != null) {
            order.setUserId(user.getUserId());
        }

        // 运营区
        AreaVO area = bo.getArea();
        if (area != null) {
            order.setAreaId(area.getId());
            order.setAreaReturnVerify(area.getReturnVerify());
            order.setAreaUserId(area.getUserId());
            order.setAreaAgentId(area.getAgentId());
        }

        // 套餐信息
        SuitVO suit = bo.getSuit();
        if (suit != null) {
            order.setSuitId(suit.getId());
            order.setSuitType(suit.getType());
            order.setSuitName(suit.getName());
            order.setSuitFreeRideTime(suit.getFreeRideTime());
            order.setSuitRentalUnit(suit.getRentalUnit());
            order.setSuitRidingRule(suit.getRidingRule());
            order.setSuitStartRule(suit.getStartRule());
            order.setSuitIntervalRule(suit.getIntervalRule());
            order.setSuitSeconds(suit.getSeconds());
            order.setSuitDepositDeduction(suit.getDepositDeduction());
        }

        // 价格信息
        OrderPrePriceVO prePrice = bo.getPrePrice();
        if (prePrice != null) {
            order.setDepositFee(prePrice.getDepositPrice());
            order.setPayAmount(prePrice.getPayAmount());
        }

        // 订单状态
        if (SuitType.SHARE.getCode().equals(order.getSuitType())) {
            order.setStatus(OrderStatus.WAIT_PAY.getCode());
        } else {
            throw new RuntimeException("暂未开放租赁套餐");
        }

        // 挂账信息
        CreditUserVO creditUser = bo.getCreditUser();
        if (creditUser != null) {
            order.setIsCredit(true);
            order.setCreditId(creditUser.getCreditId());
            order.setCreditUserId(creditUser.getId());
            order.setCreditName(creditUser.getCreditName());
            order.setCreditUserName(creditUser.getUserName());
        }

        return order;
    }

    @Override
    public OrderPayBO toPayBO(OrderVO order, OrderPayDTO dto) {
        if (dto == null || order == null) {
            return null;
        }

        Long channelId = dto.getChannelId();
        Long appId = dto.getAppId();

        OrderPayBO bo = new OrderPayBO();
        bo.setDto(dto);
        bo.setOrder(order);

        // 查询渠道
        ChannelVO channel = channelService.selectChannelByChannelId(channelId);
        bo.setChannel(channel);

        // 查询应用
        AppVO app = appService.selectAppById(appId);
        bo.setApp(app);

        if (order != null) {
            // 查询设备
            DeviceVO device = deviceService.selectDeviceById(order.getDeviceId());
            bo.setDevice(device);

            // 查询设备所属人的加盟信息
            if (device != null && device.getMchId() != null) {
                AreaJoinVO areaJoin = areaJoinService.selectByUserArea(device.getMchId(), device.getAreaId());
                bo.setAreaJoin(areaJoin);
            }

            // 查询运营区的合伙人列表
            if (order.getAreaId() != null) {
                List<AreaJoinVO> partners = areaJoinService.selectListByAreaId(order.getAreaId(), AreaJoinType.PARTNER.getCode());
                bo.setPartners(partners);
            }

            // 查询用户
            UserVO user = userService.selectUserById(order.getUserId());
            bo.setUser(user);

            // 查询用户应用信息
            if (user != null && app != null) {
                UserAppVO userApp = userAppService.selectByUserApp(user.getUserId(), app.getId());
                bo.setUserApp(userApp);
            }
        }


        return bo;
    }

    @Override
    public Order toPOByEnd(OrderVO order) {
        if (order == null) {
            return null;
        }
        // 需要更新的字段
        Order data = new Order();
        data.setStatus(order.getStatus());
        data.setManageFee(order.getManageFee());
        data.setDispatchFee(order.getDispatchFee());
        data.setRidingFee(order.getRidingFee());
        data.setTotalFee(order.getTotalFee());
        data.setEndTime(order.getEndTime());
        data.setDuration(order.getDuration());
        data.setDistance(order.getDistance());
        data.setReturnType(order.getReturnType());
        data.setEndAreaSubName(order.getEndAreaSubName());
        data.setEndReason(order.getEndReason());
        return data;
    }

    @Override
    public OrderEndBO toEndBO(OrderEndDTO dto) {
        if (dto == null) {
            return null;
        }

        OrderEndBO bo = new OrderEndBO();
        bo.setDto(dto);

        // 获取订单
        OrderVO order = orderService.selectOrderById(dto.getOrderId());
        bo.setOrder(order);
        if (order != null) {

            // 获取当前订单设备
            OrderDeviceVO orderDevice = orderDeviceService.selectOrderDeviceById(order.getOrderDeviceId());
            bo.setOrderDevice(orderDevice);

            if (orderDevice != null) {
                // 获取当前设备信息
                DeviceVO device = deviceService.selectDeviceById(orderDevice.getDeviceId());
                bo.setDevice(device);
            }

            // 查询运营区
            AreaVO area = areaService.selectAreaById(order.getAreaId());
            bo.setArea(area);

            if (area != null) {
                // 查询运营区的可还车的子区域列表
                List<AreaSubVO> parkingList = areaSubService.selectParkingAreaByAreaId(area.getId());
                bo.setParkingList(parkingList);

                // 查询运营区的禁停区列表
                List<AreaSubVO> noParkingList = areaSubService.selectNoParkingAreaByAreaId(area.getId());
                bo.setNoParkingList(noParkingList);
            }

            // 停车点信息
            OrderInParkingVO inParkingVO = OrderUtil.getInParkingVO(area, bo.getParkingList(), bo.getNoParkingList(), bo.getDevice(), dto.getLon(), dto.getLat());
            bo.setInParkingVO(inParkingVO);

            // 查询订单车辆轨迹列表
            List<LocationLogPositionVO> positionList = locationLogService.selectPositionListByOrderId(order.getId());
            bo.setPositionList(positionList);
        }

        return bo;
    }

    @Override
    public OrderChangeBO toChangeBO(OrderChangeDeviceDTO dto) {
        if (dto == null) {
            return null;
        }

        OrderChangeBO bo = new OrderChangeBO();

        // 查询订单
        OrderVO order = orderService.selectOrderById(dto.getOrderId());
        bo.setOrder(order);
        ServiceUtil.assertion(order == null, "ID为%s的订单不存在", dto.getOrderId());
        ServiceUtil.assertion(!OrderStatus.inUse().contains(order.getStatus()), "ID为%s的订单当前状态并非使用中，无法换车", dto.getOrderId());

        // 查询新的设备
        DeviceVO newDevice = null;
        if (dto.getDeviceId() != null) {
            newDevice = deviceService.selectDeviceById(dto.getDeviceId());
            ServiceUtil.assertion(newDevice == null, "ID为%s的设备不存在", dto.getDeviceId());
        } else if (StringUtils.isNotBlank(dto.getDeviceSn())) {
            newDevice = deviceService.selectDeviceBySn(dto.getDeviceSn());
            ServiceUtil.assertion(newDevice == null, "SN为%s的设备不存在", dto.getDeviceSn());
        } else {
            throw new RuntimeException("参数错误，请选择需要更换的车辆。");
        }
        bo.setNewDevice(newDevice);

        // 校验新的设备能否使用
        orderValidator.canUseDevice(newDevice, order);

        // 查询旧的订单设备
        OrderDeviceVO oldOrderDevice = orderDeviceService.selectOrderDeviceById(order.getOrderDeviceId());
        ServiceUtil.assertion(oldOrderDevice == null, "ID为%s的订单当前没有设备正在使用", dto.getOrderId());
        ServiceUtil.assertion(Objects.equals(oldOrderDevice.getDeviceId(), newDevice.getId()), "新旧车辆相同，无法换车");
        bo.setOldOrderDevice(oldOrderDevice);

        // 校验图片
        orderValidator.checkReturnPicture(order, dto.getFaultPicture());

        // 查询运营区
        AreaVO area = areaService.selectAreaById(order.getAreaId());
        ServiceUtil.assertion(area == null, "ID为%s的运营区不存在", order.getAreaId());
        bo.setArea(area);

        // 查询运营区子区域列表
        List<AreaSubVO> parkingList = areaSubService.selectParkingAreaByAreaId(area.getId());
        bo.setParkingList(parkingList);

        // 查询运营区禁停区列表
        List<AreaSubVO> noParkingList = areaSubService.selectNoParkingAreaByAreaId(area.getId());
        bo.setNoParkingAreaSubList(noParkingList);

        // 查询旧设备
        DeviceVO oldDevice = deviceService.selectDeviceById(oldOrderDevice.getDeviceId());
        ServiceUtil.assertion(oldDevice == null, "ID为%s的旧设备不存在", oldOrderDevice.getDeviceId());
        bo.setOldDevice(oldDevice);

        // 获取旧设备是否在停车点内
        OrderInParkingVO inParkingVO = OrderUtil.getInParkingVO(area, parkingList, noParkingList, oldDevice, dto.getLon(), dto.getLat());
        bo.setInParkingVO(inParkingVO);
        // 校验旧设备是否在停车点内
        orderValidator.checkInParking(area, inParkingVO);

        // 需要创建的新订单设备
        OrderDevice newOrderDevice = new OrderDevice();
        newOrderDevice.setType(OrderDeviceType.REPLACE.getCode());
        newOrderDevice.setStatus(OrderDeviceStatus.WAIT_USE.getCode());
        newOrderDevice.setOrderId(order.getId());
        newOrderDevice.setReason(dto.getReason());
        if (newDevice != null) {
            OrderDeviceUtil.setDeviceInfo(newOrderDevice, newDevice);
        }
        bo.setNewOrderDevice(newOrderDevice);

        return bo;
    }

    @Override
    public OrderPayRideFeeBO toPayRideFeeBO(OrderPayRideFeeDTO dto) {
        if (dto == null) {
            return null;
        }

        OrderPayRideFeeBO bo = new OrderPayRideFeeBO();
        bo.setDto(dto);

        // 查询订单
        OrderVO order = orderService.selectOrderById(dto.getOrderId());
        bo.setOrder(order);

        // 查询渠道
        ChannelVO channel = channelService.selectChannelByChannelId(dto.getChannelId());
        bo.setChannel(channel);

        // 查询应用
        AppVO app = appService.selectAppById(dto.getAppId());
        bo.setApp(app);

        // 查询用户
        UserVO user = userService.selectUserById(dto.getUserId());
        bo.setUser(user);

        // 查询用户应用
        if (app != null && user != null) {
            UserAppVO userApp = userAppService.selectByUserApp(user.getUserId(), app.getId());
            bo.setUserApp(userApp);
        }

        // 查询挂账用户
        if (dto.getCreditUserId() != null) {
            bo.setCreditUser(creditUserService.selectCreditUserById(dto.getCreditUserId()));
        }

        // 查询卡券
        bo.setVipUser(vipUserService.selectVipUserById(dto.getVipUserId()));

        // 计算应付骑行费
        OrderCalcRideFeeVO fee = orderService.calcRideFee(bo.getOrder(), bo.getVipUser());
        bo.setFee(fee);

        // 查询可用渠道数据
        bo.setChannelPayList(channelService.getRideFeePayChannelList(order.getId()));

        return bo;
    }


    @Override
    public OrderDeductBO toDeductBo(OrderDeductDTO dto) {
        if (dto == null) {
            return null;
        }
        OrderDeductBO bo = new OrderDeductBO();
        bo.setDto(dto);

        OrderVO order = orderService.selectOrderById(dto.getId());
        bo.setOrder(order);

        VipUserVO vipUser = vipUserService.selectVipUserById(dto.getVipUserId());
        bo.setVipUser(vipUser);

        OrderCalcRideFeeVO fee = orderService.calcRideFee(order, vipUser);
        bo.setFee(fee);

        if (order != null) {
            // 查询用户
            UserVO user = userService.selectUserById(order.getUserId());
            bo.setUser(user);
        }

        return bo;
    }
}
