package com.njzscloud.dispose.cst.order.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.njzscloud.common.core.tuple.Tuple2;
import com.njzscloud.common.oss.util.AliOSS;
import com.njzscloud.dispose.cst.order.constant.*;
import com.njzscloud.dispose.cst.order.helper.PaymentRecordHelper;
import com.njzscloud.dispose.cst.order.mapper.OrderMapper;
import com.njzscloud.dispose.cst.order.mapper.OrderTransMapper;
import com.njzscloud.dispose.cst.order.pojo.entity.OrderEntity;
import com.njzscloud.dispose.cst.order.pojo.entity.OrderTransEntity;
import com.njzscloud.dispose.cst.order.pojo.result.OrderTransResult;
import com.njzscloud.dispose.dev.DiscoverTruckMsg;
import com.njzscloud.dispose.dev.ObtainTruckDataResultMsg;
import com.njzscloud.dispose.dev.WbsHandle;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;

/**
 * 车辆称重业务服务
 * 处理磅房称重相关的所有业务逻辑
 *
 * @author ljw
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TruckWeighingBusinessService {

    private final OrderService orderService;
    private final OrderMapper orderMapper;
    private final OrderTransMapper orderTransMapper;
    private final PaymentRecordHelper paymentRecordHelper;

    /**
     * 请求数据 - 处理车辆识别
     */
    public void requestData(Tuple2<DiscoverTruckMsg, WbsHandle> param) {
        DiscoverTruckMsg truckMsg = param.get_0();
        WbsHandle handle = param.get_1();
        // 车牌号
        String licensePlate = truckMsg.getLicensePlate();
        // 是否为前置道闸
        boolean isFront = truckMsg.isFront();
        // 根据车牌号查找运输订单
        OrderTransResult orderTrans = orderTransMapper.getByLicensePlate(licensePlate);
        if (orderTrans == null) {
            log.warn("未找到车牌号 {} 对应的运输订单", licensePlate);
            handle.playVoice(VoiceConstants.VOICE_ORDER_NOT_FOUND);
            return;
        }

        // 验证订单业务状态
        if (!validateOrderBusinessStatus(orderTrans)) {
            handle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
            return;
        }

        // 使用同步锁确保数据一致性
        synchronized (this) {
            try {
                log.info("开始处理车辆 {} 进出场请求，前置道闸: {}", licensePlate, isFront ? "是" : "否");

                // 判断是进场还是出场
                boolean isComing = isTruckComing(orderTrans);
                boolean isLeaving = isTruckLeaving(orderTrans);
                if (isLeaving) {
                    // 出场时检查时间：当前时间必须大于进场时间3分钟
                    if (orderTrans.getInTime() != null) {
                        long minutesSinceEntry = Duration.between(orderTrans.getInTime(), LocalDateTime.now()).toMinutes();
                        if (minutesSinceEntry < 3) {
                            log.warn("车辆 {} 出场时间过早，进场时间: {}, 当前已过 {} 分钟，不满足最少3分钟要求",
                                licensePlate, orderTrans.getInTime(), minutesSinceEntry);
                            return;
                        }
                    } else {
                        return;
                    }

                    // 出场时检查是否已看料
                    if (!CheckStatus.YiKanLiao.equals(orderTrans.getCheckStatus())) {
                        handle.playVoice(licensePlate + VoiceConstants.VOICE_UNCHECKED);
                        return;
                    }
                }
                if (!isComing && !isLeaving) {
                    log.warn("订单 {} 状态不允许进出场操作，当前状态：订单={},运输={}",
                        orderTrans.getId(), orderTrans.getOrderStatus(), orderTrans.getTransStatus());
                    handle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
                    return;
                }

                if (isFront) {
                    // 前置道闸：还未上磅，只负责开门让车辆通过
                    log.info("前置道闸开门，车辆 {} 进入磅区", licensePlate);
                    handle.playVoice(VoiceConstants.VOICE_WELCOME);
                    handle.open();
                } else {
                    // 后置道闸：车辆已过磅，负责称重和算账，但不开门
                    log.info("后置道闸开始称重，车辆 {}，订单ID: {}", licensePlate, orderTrans.getId());
                    handle.playVoice(VoiceConstants.VOICE_WEIGHING);
                    handle.obtainTruckData(orderTrans.getId());
                }
            } catch (Exception e) {
                log.error("处理车辆 {} 识别异常", licensePlate, e);
                handle.playVoice(VoiceConstants.VOICE_SYSTEM_ERROR);
            }
        }
    }

    /**
     * 处理数据 - 处理磅重数据
     */
    public void disposeData(Tuple2<ObtainTruckDataResultMsg, WbsHandle> param) {
        ObtainTruckDataResultMsg dataMsg = param.get_0();
        WbsHandle wbsHandle = param.get_1();

        Long orderTransId = dataMsg.getOrderId();
        String image = dataMsg.getBodyImage();
        Integer weight = dataMsg.getWeight();
        Boolean success = dataMsg.getSuccess();

        // 检查数据获取是否成功
        if (!Boolean.TRUE.equals(success) || weight == null || weight <= 0) {
            log.warn("获取车辆数据失败或重量无效，订单ID: {}, 重量: {}", orderTransId, weight);
            wbsHandle.playVoice(VoiceConstants.VOICE_WEIGH_FAILED);
            return;
        }

        synchronized (this) {
            try {
                log.info("开始处理称重数据，运输ID: {}, 重量: {}kg", orderTransId, weight);

                // 根据运输ID获取订单信息
                OrderTransResult orderTrans = orderTransMapper.getById(orderTransId);
                if (orderTrans == null) {
                    log.warn("未找到运输订单 {}", orderTransId);
                    wbsHandle.playVoice(VoiceConstants.VOICE_ORDER_NOT_FOUND);
                    return;
                }
                if (!CheckStatus.YiKanLiao.equals(orderTrans.getCheckStatus())) {
                    wbsHandle.playVoice(orderTrans.getTruckLicensePlate() + VoiceConstants.VOICE_UNCHECKED);
                    return;
                }

                // 根据当前状态处理称重数据
                processWeighingData(orderTrans, weight, image, wbsHandle);

            } catch (Exception e) {
                log.error("处理车辆称重数据异常，订单ID: {}", orderTransId, e);
                wbsHandle.playVoice(VoiceConstants.VOICE_SYSTEM_ERROR);
            }
        }
    }

    /**
     * 处理称重数据
     */
    private void processWeighingData(OrderTransResult orderTrans, Integer weight, String image, WbsHandle wbsHandle) {
        // 根据当前状态判断是进场还是出场
        if (TransStatus.YunShuZhong.equals(orderTrans.getTransStatus())) {
            // 进场：设置相应重量，完成后开门
            handleTruckComingData(orderTrans, weight, image);
            wbsHandle.playVoice(VoiceConstants.VOICE_PLEASE_PASS);
            wbsHandle.open();
        } else if (TransStatus.YiJinChang.equals(orderTrans.getTransStatus())) {
            // 出场：设置相应重量并计算净重、账目，支付完成后开门
            handleTruckLeavingData(orderTrans, weight, image, wbsHandle);
            wbsHandle.playVoice(VoiceConstants.VOICE_WEIGH_COMPLETE);
        } else {
            log.warn("运输订单 {} 状态 {} 不支持称重操作", orderTrans.getId(), orderTrans.getTransStatus());
            wbsHandle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
        }
    }

    /**
     * 处理进场称重数据
     */
    private void handleTruckComingData(OrderTransResult orderTrans, Integer weight, String bodyPhoto) {
        OrderTransEntity transEntity = new OrderTransEntity();
        transEntity.setId(orderTrans.getId());
        transEntity.setTransStatus(TransStatus.YiJinChang);
        transEntity.setInTime(LocalDateTime.now());

        // 上传车斗照片并设置URL
        if (bodyPhoto != null && !bodyPhoto.trim().isEmpty()) {
            String photoUrl = uploadBase64Image(bodyPhoto, "truck_body_in_" + orderTrans.getId());
            transEntity.setInBodyPhoto(photoUrl);
        }

        // 设置重量（进场）
        setWeightByOrderType(transEntity, orderTrans, weight, true);

        orderTransMapper.updateById(transEntity);
        log.info("车辆进场称重完成，订单ID: {}, 重量: {}kg", orderTrans.getId(), weight);
    }

    /**
     * 处理出场称重数据
     */
    private void handleTruckLeavingData(OrderTransResult orderTrans, Integer weight, String bodyPhoto, WbsHandle wbsHandle) {
        OrderTransEntity transEntity = new OrderTransEntity();
        transEntity.setId(orderTrans.getId());
        transEntity.setTransStatus(TransStatus.YiChuChang);
        transEntity.setOutTime(LocalDateTime.now());

        // 上传车斗照片并设置URL
        if (bodyPhoto != null && !bodyPhoto.trim().isEmpty()) {
            String photoUrl = uploadBase64Image(bodyPhoto, "truck_body_out_" + orderTrans.getId());
            transEntity.setOutBodyPhoto(photoUrl);
        }

        // 设置重量（出场）
        setWeightByOrderType(transEntity, orderTrans, weight, false);

        // 计算净重
        calculateAndSetNetWeight(transEntity, orderTrans);

        orderTransMapper.updateById(transEntity);
        Integer settleWeight = transEntity.getSettleWeight();
        log.info("车辆出场称重完成，订单ID: {}, 重量: {}kg, 净重: {}kg",
            orderTrans.getId(), weight, settleWeight);

        // 更新付费记录的量,计算结算金额并支付
        String orderSn = orderMapper.selectById(orderTrans.getOrderId()).getSn();
        boolean allCompleted = paymentRecordHelper.updatePaymentRecordQuantity(
            orderTrans.getId(), settleWeight, orderTrans.getTransDistance(),
            orderSn, orderTrans.getTrainNum());

        // 如果该运输记录下所有付费记录都已完成，更新运输状态为已完成并开门
        if (allCompleted) {
            OrderTransEntity updateTrans = new OrderTransEntity();
            updateTrans.setId(orderTrans.getId());
            updateTrans.setTransStatus(TransStatus.YiWanCheng);
            updateTrans.setFinishTime(LocalDateTime.now());
            orderTransMapper.updateById(updateTrans);

            // 检查订单下所有运输记录是否都完成
            this.checkAndUpdateOrderStatus(orderTrans.getOrderId());

            // 开门放行
            wbsHandle.playVoice(VoiceConstants.VOICE_PLEASE_PASS);
            wbsHandle.open();
            log.info("运输记录 {} 支付完成，开门放行", orderTrans.getId());
        }
    }

    /**
     * 根据订单类型设置重量
     */
    private void setWeightByOrderType(OrderTransEntity transEntity, OrderTransResult orderTrans, Integer weight, boolean isComing) {
        if (OrderCategory.HuiShouYuYue.equals(orderTrans.getOrderCategory())) {
            // 回收预约单：进场称毛重，出场称皮重
            if (isComing) {
                transEntity.setRoughWeight(weight);
            } else {
                transEntity.setTareWeight(weight);
                // 更新车辆皮重
                orderService.updateTruckHisTareWeight(orderTrans.getTruckId(), weight);
            }
        } else if (OrderCategory.XiaoShouYuYue.equals(orderTrans.getOrderCategory())) {
            // 销售预约单：进场称皮重，出场称毛重
            if (isComing) {
                transEntity.setTareWeight(weight);
                // 更新车辆皮重
                orderService.updateTruckHisTareWeight(orderTrans.getTruckId(), weight);
            } else {
                transEntity.setRoughWeight(weight);
            }
        }
    }

    /**
     * 计算并设置净重
     */
    private void calculateAndSetNetWeight(OrderTransEntity transEntity, OrderTransResult orderTrans) {
        Integer roughWeight = transEntity.getRoughWeight() != null ? transEntity.getRoughWeight() : orderTrans.getRoughWeight();
        Integer tareWeight = transEntity.getTareWeight() != null ? transEntity.getTareWeight() : orderTrans.getTareWeight();

        if (roughWeight != null && tareWeight != null && roughWeight > tareWeight) {
            Integer settleWeight = roughWeight - tareWeight;
            transEntity.setSettleWeight(settleWeight);
            log.debug("计算净重完成，毛重: {}kg, 皮重: {}kg, 净重: {}kg", roughWeight, tareWeight, settleWeight);
        } else {
            log.warn("无法计算净重，毛重: {}, 皮重: {}", roughWeight, tareWeight);
        }
    }

    /**
     * 上传base64编码的图片到阿里云OSS
     */
    private String uploadBase64Image(String base64Image, String fileNamePrefix) {
        if (base64Image == null || base64Image.trim().isEmpty()) {
            return null;
        }

        try {
            // 移除base64前缀（如"data:image/jpeg;base64,"）
            String base64Data;
            if (base64Image.contains(",")) {
                base64Data = base64Image.substring(base64Image.indexOf(",") + 1);
            } else {
                base64Data = base64Image;
            }

            // 解码base64字符串为字节数组
            byte[] imageBytes = Base64.getDecoder().decode(base64Data);

            // 生成文件名
            String fileName = fileNamePrefix + "_" + System.currentTimeMillis() + ".jpg";

            // 创建ByteArrayInputStream并上传到OSS
            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes)) {
                // 使用AliOSS直接上传
                String url = AliOSS.uploadFile(fileName, "image/jpeg", inputStream);

                log.info("车斗照片上传成功: {}", url);
                return url;
            }

        } catch (Exception e) {
            log.error("上传base64车斗照片失败", e);
            // 上传失败时返回原始base64字符串作为降级方案
            return base64Image;
        }
    }

    /**
     * 判断是否为进场操作
     * 订单状态为进行中，运输状态为运输中
     */
    private boolean isTruckComing(OrderTransResult orderTrans) {
        return OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus()) &&
            TransStatus.YunShuZhong.equals(orderTrans.getTransStatus());
    }

    /**
     * 判断是否为出场操作
     * 订单状态为进行中，运输状态为已进场
     */
    private boolean isTruckLeaving(OrderTransResult orderTrans) {
        return OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus()) &&
            TransStatus.YiJinChang.equals(orderTrans.getTransStatus());
    }

    /**
     * 验证订单业务状态
     */
    private boolean validateOrderBusinessStatus(OrderTransResult orderTrans) {
        // 检查订单状态
        if (!OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus())) {
            log.warn("订单状态异常，订单ID: {}, 当前状态: {}", orderTrans.getId(), orderTrans.getOrderStatus());
            return false;
        }

        // 检查运输状态
        TransStatus transStatus = orderTrans.getTransStatus();
        if (!TransStatus.YunShuZhong.equals(transStatus) && !TransStatus.YiJinChang.equals(transStatus)) {
            log.warn("运输状态异常，订单ID: {}, 当前状态: {}", orderTrans.getId(), transStatus);
            return false;
        }

        // 检查订单类型
        if (orderTrans.getOrderCategory() == null) {
            log.warn("订单类型为空，订单ID: {}", orderTrans.getId());
            return false;
        }

        return true;
    }

    /**
     * 检查订单下所有运输记录是否都完成，如果都完成则更新订单状态
     *
     * @param orderId 订单ID
     */
    private void checkAndUpdateOrderStatus(Long orderId) {
        List<OrderTransEntity> transList = orderTransMapper.selectList(
            Wrappers.<OrderTransEntity>lambdaQuery()
                .eq(OrderTransEntity::getOrderId, orderId)
                .ne(OrderTransEntity::getTransStatus, TransStatus.YiQuXiao));

        boolean allCompleted = transList.stream()
            .allMatch(t -> TransStatus.YiWanCheng.equals(t.getTransStatus()));

        if (allCompleted) {
            OrderEntity updateOrder = new OrderEntity();
            updateOrder.setId(orderId);
            updateOrder.setOrderStatus(OrderStatus.YiWanCheng);
            updateOrder.setFinishTime(LocalDateTime.now());
            orderService.updateById(updateOrder);
            log.info("订单 {} 所有运输记录已完成，更新订单状态为已完成", orderId);
        }
    }
}
