package com.aiotagro.cattletrade.business.controller;


import cn.dev33.satoken.annotation.SaCheckPermission;
import com.aiotagro.cattletrade.business.dto.DeliverListDto;
import com.aiotagro.cattletrade.business.dto.DeliveryAddDto;
import com.aiotagro.cattletrade.business.dto.DeliveryCreateDto;
import com.aiotagro.cattletrade.business.dto.DeliveryEditDto;
import com.aiotagro.cattletrade.business.dto.DeliveryQueryDto;
import com.aiotagro.cattletrade.business.dto.DeviceAssignDto;
import com.aiotagro.cattletrade.business.entity.Delivery;
import com.aiotagro.cattletrade.business.entity.DeliveryDevice;
import com.aiotagro.cattletrade.business.entity.JbqClient;
import com.aiotagro.cattletrade.business.entity.XqClient;
import com.aiotagro.cattletrade.business.service.IDeliveryService;
import com.aiotagro.cattletrade.business.service.IDeliveryDeviceService;
import com.aiotagro.cattletrade.business.service.IJbqClientService;
import com.aiotagro.cattletrade.business.service.IXqClientService;
import com.aiotagro.common.core.context.SecurityContextHolder;
import com.aiotagro.common.core.utils.SecurityUtil;
import com.aiotagro.common.core.constant.RoleConstants;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 运送清单表 前端控制器
 *
 * @author admin
 * @since 2024-12-26
 */
@RestController
@RequestMapping("/delivery")
public class DeliveryController {

    @Autowired
    private IDeliveryService deliveryService;

    @Autowired
    private IDeliveryDeviceService deliveryDeviceService;
    
    @Autowired
    private IJbqClientService jbqClientService;
    
    @Autowired
    private IXqClientService xqClientService;
    
    @Autowired
    private com.aiotagro.cattletrade.business.mapper.IotDeviceDataMapper iotDeviceDataMapper;



    /**
     * 小程序运送清单-分页查询
     *
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:list")
    @PostMapping(value = "/pageQuery")
    public PageResultResponse<Delivery> pageQuery(@RequestBody DeliveryQueryDto dto) {
        return deliveryService.pageQuery(dto);
    }

    /**
     * 小程序运送清单-我要装车
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:add")
    @PostMapping(value = "/add")
    public AjaxResult add(@RequestBody DeliveryAddDto dto) {
        try{
           return deliveryService.addDelivery(dto);
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 运送清单-创建（PC端新增接口）
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:add")
    @PostMapping(value = "/create")
    public AjaxResult create(@Validated @RequestBody DeliveryCreateDto dto) {
        try{
           return deliveryService.createDelivery(dto);
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 装车订单-新增（PC端装车订单创建接口）
     * @param params
     * @return
     */
    @SaCheckPermission("delivery:add")
    @PostMapping(value = "/addDeliveryOrder")
    public AjaxResult addDeliveryOrder(@RequestBody Map<String, Object> params) {
        try {
            // 获取参数值
            String deliveryTitle = (String) params.get("deliveryTitle");
            Integer ratedQuantity = null;
            if (params.get("ratedQuantity") != null) {
                Object ratedQuantityObj = params.get("ratedQuantity");
                if (ratedQuantityObj instanceof Integer) {
                    ratedQuantity = (Integer) ratedQuantityObj;
                } else if (ratedQuantityObj instanceof String) {
                    try {
                        ratedQuantity = Integer.parseInt((String) ratedQuantityObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("装车数量格式不正确");
                    }
                }
            }
            
            String supplierId = (String) params.get("supplierId");
            
            Integer fundId = null;
            if (params.get("fundId") != null) {
                Object fundIdObj = params.get("fundId");
                if (fundIdObj instanceof Integer) {
                    fundId = (Integer) fundIdObj;
                } else if (fundIdObj instanceof String) {
                    try {
                        fundId = Integer.parseInt((String) fundIdObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("资金方ID格式不正确");
                    }
                }
            }
            
            Integer driverId = null;
            if (params.get("driverId") != null) {
                Object driverIdObj = params.get("driverId");
                if (driverIdObj instanceof Integer) {
                    driverId = (Integer) driverIdObj;
                } else if (driverIdObj instanceof String) {
                    try {
                        driverId = Integer.parseInt((String) driverIdObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("司机ID格式不正确");
                    }
                }
            }
            
            Integer buyerId = null;
            if (params.get("buyerId") != null) {
                Object buyerIdObj = params.get("buyerId");
                if (buyerIdObj instanceof Integer) {
                    buyerId = (Integer) buyerIdObj;
                } else if (buyerIdObj instanceof String) {
                    try {
                        buyerId = Integer.parseInt((String) buyerIdObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("采购商ID格式不正确");
                    }
                }
            }
            
            Double buyerPrice = null;
            if (params.get("buyerPrice") != null) {
                Object buyerPriceObj = params.get("buyerPrice");
                if (buyerPriceObj instanceof Double) {
                    buyerPrice = (Double) buyerPriceObj;
                } else if (buyerPriceObj instanceof String) {
                    try {
                        buyerPrice = Double.parseDouble((String) buyerPriceObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("采购价格格式不正确");
                    }
                }
            }
            
            Double salePrice = null;
            if (params.get("salePrice") != null) {
                Object salePriceObj = params.get("salePrice");
                if (salePriceObj instanceof Double) {
                    salePrice = (Double) salePriceObj;
                } else if (salePriceObj instanceof String) {
                    try {
                        salePrice = Double.parseDouble((String) salePriceObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("销售价格格式不正确");
                    }
                }
            }
            
            Double firmPrice = null;
            if (params.get("firmPrice") != null) {
                Object firmPriceObj = params.get("firmPrice");
                if (firmPriceObj instanceof Double) {
                    firmPrice = (Double) firmPriceObj;
                } else if (firmPriceObj instanceof String) {
                    try {
                        firmPrice = Double.parseDouble((String) firmPriceObj);
                    } catch (NumberFormatException e) {
                        return AjaxResult.error("约定单价格式不正确");
                    }
                }
            }
            String startLocation = (String) params.get("startLocation");
            
            String startLat = null;
            if (params.get("startLat") != null) {
                Object startLatObj = params.get("startLat");
                if (startLatObj instanceof String) {
                    startLat = (String) startLatObj;
                } else if (startLatObj instanceof Double) {
                    startLat = String.valueOf((Double) startLatObj);
                } else if (startLatObj instanceof Integer) {
                    startLat = String.valueOf((Integer) startLatObj);
                }
            }
            
            String startLon = null;
            if (params.get("startLon") != null) {
                Object startLonObj = params.get("startLon");
                if (startLonObj instanceof String) {
                    startLon = (String) startLonObj;
                } else if (startLonObj instanceof Double) {
                    startLon = String.valueOf((Double) startLonObj);
                } else if (startLonObj instanceof Integer) {
                    startLon = String.valueOf((Integer) startLonObj);
                }
            }
            
            String endLocation = (String) params.get("endLocation");
            
            String endLat = null;
            if (params.get("endLat") != null) {
                Object endLatObj = params.get("endLat");
                if (endLatObj instanceof String) {
                    endLat = (String) endLatObj;
                } else if (endLatObj instanceof Double) {
                    endLat = String.valueOf((Double) endLatObj);
                } else if (endLatObj instanceof Integer) {
                    endLat = String.valueOf((Integer) endLatObj);
                }
            }
            
            String endLon = null;
            if (params.get("endLon") != null) {
                Object endLonObj = params.get("endLon");
                if (endLonObj instanceof String) {
                    endLon = (String) endLonObj;
                } else if (endLonObj instanceof Double) {
                    endLon = String.valueOf((Double) endLonObj);
                } else if (endLonObj instanceof Integer) {
                    endLon = String.valueOf((Integer) endLonObj);
                }
            }

            // 参数验证
            if (deliveryTitle == null || deliveryTitle.trim().isEmpty()) {
                return AjaxResult.error("订单标题不能为空");
            }
            if (ratedQuantity == null || ratedQuantity <= 0) {
                return AjaxResult.error("装车数量必须大于0");
            }
            if (startLocation == null || startLocation.trim().isEmpty()) {
                return AjaxResult.error("起始地不能为空");
            }
            if (endLocation == null || endLocation.trim().isEmpty()) {
                return AjaxResult.error("目的地不能为空");
            }

            // 获取当前登录用户
            Integer userId = SecurityUtil.getCurrentUserId();
            String userName = SecurityContextHolder.getUserName(); // 使用SecurityContextHolder获取用户名
            
            // 生成运输单号
            LocalDateTime now = LocalDateTime.now();
            String deliveryNumber = "ZC" + now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            
            // 创建装车订单
            Delivery delivery = new Delivery();
            delivery.setDeliveryNumber(deliveryNumber);
            delivery.setDeliveryTitle(deliveryTitle);
            delivery.setRatedQuantity(ratedQuantity);
            delivery.setSupplierId(supplierId);
            delivery.setFundId(fundId);
            delivery.setDriverId(driverId);
            delivery.setBuyerId(buyerId);
            delivery.setBuyerPrice(buyerPrice);
            delivery.setSalePrice(salePrice);
            delivery.setFirmPrice(firmPrice);
            delivery.setStartLocation(startLocation);
            delivery.setStartLat(startLat);
            delivery.setStartLon(startLon);
            delivery.setEndLocation(endLocation);
            delivery.setEndLat(endLat);
            delivery.setEndLon(endLon);
            delivery.setStatus(1); // 待装车
            delivery.setCreatedBy(userId);
            delivery.setCreateByName(userName);
            delivery.setCreateTime(new Date());
            
            // 保存装车订单
            boolean saved = deliveryService.save(delivery);
            if (!saved) {
                return AjaxResult.error("创建装车订单失败");
            }
            
            return AjaxResult.success("装车订单创建成功");
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("创建装车订单失败：" + e.getMessage());
        }
    }

    /**
     * 运送清单-编辑（PC端编辑接口）
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:edit")
    @PostMapping(value = "/updateDeliveryInfo")
    public AjaxResult updateDeliveryInfo(@Validated @RequestBody DeliveryEditDto dto) {
        try{
           return deliveryService.updateDeliveryInfo(dto);
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 小程序运送清单-查询详情
     * @param id
     * @return
     */
    @SaCheckPermission("delivery:view")
    @GetMapping(value = "/view")
    public AjaxResult view(@RequestParam Integer id) {
        return deliveryService.viewDelivery(id);
    }


    /**
     * 小程序运送清单-核验提交
     * @param delivery
     * @return
     */
    @SaCheckPermission("delivery:check")
    @PostMapping(value = "/submitCheck")
    public AjaxResult submitCheck(@RequestBody Delivery delivery) {
        try{
            //查询当前的登录用户，即核验人
            delivery.setCheckBy(SecurityUtil.getCurrentUserId());
            delivery.setCheckTime(new Date());
            delivery.setCheckByName(SecurityUtil.getUserName());
            boolean b = deliveryService.updateById(delivery);
            if(b){
                return AjaxResult.success("核验提交成功！");
            }else{
                return AjaxResult.error("核验提交失败！");
            }
        }catch (Exception e){
            return AjaxResult.error("核验提交失败！");
        }
    }

    /**
     * 后台系统运送清单-分页查询
     *
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:list")
    @PostMapping(value = "/pageQueryList")
    public PageResultResponse<Delivery> pageQueryList(@RequestBody DeliveryQueryDto dto) {
        return deliveryService.pageQuery(dto);
    }

    /**
     * 后台系统运送清单-分页查询（别名）
     *
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:list")
    @PostMapping(value = "/pageDeliveryOrderList")
    public PageResultResponse<Delivery> pageDeliveryOrderList(@RequestBody DeliverListDto dto) {
        return deliveryService.pageQueryListLog(dto);
    }

    /**
     * 后台运单详情
     */
    @SaCheckPermission("delivery:view")
    @GetMapping("/detail")
    public AjaxResult detail(@RequestParam Integer id) {
        return deliveryService.detail(id);
    }

    /**
     * 查看运送订单详情（别名）
     */
    @SaCheckPermission("delivery:view")
    @GetMapping("/viewDeliveryOrder")
    public AjaxResult viewDeliveryOrder(@RequestParam Integer deliveryId) {
        return deliveryService.detail(deliveryId);
    }

    /**
     * 测试司机信息查询
     */
    @GetMapping("/testDriverQuery/{deliveryId}")
    public AjaxResult testDriverQuery(@PathVariable("deliveryId") Integer deliveryId) {
        try {
            System.out.println("测试司机信息查询，deliveryId: " + deliveryId);
            AjaxResult result = deliveryService.detail(deliveryId);
            System.out.println("查询结果: " + result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("测试失败: " + e.getMessage());
        }
    }

    /**
     * 调试用户信息接口
     */
    @GetMapping("/debugUserInfo")
    public AjaxResult debugUserInfo() {
        try {
            Map<String, Object> debugInfo = new HashMap<>();
            
            // 获取当前用户信息
            Integer userId = SecurityUtil.getCurrentUserId();
            String userName = SecurityUtil.getUserName();
            String userMobile = SecurityUtil.getUserMobile();
            Integer roleId = SecurityUtil.getRoleId();
            boolean isSuperAdmin = SecurityUtil.isSuperAdmin();
            
            debugInfo.put("userId", userId);
            debugInfo.put("userName", userName);
            debugInfo.put("userMobile", userMobile);
            debugInfo.put("roleId", roleId);
            debugInfo.put("isSuperAdmin", isSuperAdmin);
            debugInfo.put("superAdminRoleId", RoleConstants.SUPER_ADMIN_ROLE_ID);
            
            System.out.println("=== 调试用户信息 ===");
            System.out.println("用户ID: " + userId);
            System.out.println("用户名: " + userName);
            System.out.println("用户手机号: " + userMobile);
            System.out.println("角色ID: " + roleId);
            System.out.println("是否超级管理员: " + isSuperAdmin);
            System.out.println("超级管理员角色ID常量: " + RoleConstants.SUPER_ADMIN_ROLE_ID);
            
            return AjaxResult.success("调试信息获取成功", debugInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("调试失败: " + e.getMessage());
        }
    }

    /**
     * 分配设备（支持智能耳标和智能项圈）
     * @param dto
     * @return
     */
    @SaCheckPermission("delivery:assign")
    @PostMapping(value = "/arrangeJbq")
    public AjaxResult arrangeJbq(@RequestBody DeviceAssignDto dto) {
        try {
            if (dto.getDeviceIds() == null || dto.getDeviceIds().isEmpty()) {
                return AjaxResult.error("请选择要分配的设备");
            }
            
            // 按设备类型分组
            Map<Integer, List<DeviceAssignDto.DeviceInfo>> deviceGroups = dto.getDeviceIds().stream()
                .collect(Collectors.groupingBy(DeviceAssignDto.DeviceInfo::getDeviceTypeId));
            
            // 处理每种设备类型
            for (Map.Entry<Integer, List<DeviceAssignDto.DeviceInfo>> entry : deviceGroups.entrySet()) {
                Integer deviceType = entry.getKey();
                List<DeviceAssignDto.DeviceInfo> devices = entry.getValue();
                
                // 先删除该运单的现有设备分配（按设备类型）
                deliveryDeviceService.lambdaUpdate()
                    .eq(DeliveryDevice::getDeliveryId, dto.getDeliveryId())
                    .eq(DeliveryDevice::getDeviceType, deviceType)
                    .remove();
                
                // 添加新的设备分配
                for (DeviceAssignDto.DeviceInfo deviceInfo : devices) {
                    DeliveryDevice deliveryDevice = new DeliveryDevice();
                    deliveryDevice.setDeliveryId(dto.getDeliveryId());
                    deliveryDevice.setDeviceId(deviceInfo.getDeviceId());
                    deliveryDevice.setDeviceType(deviceType);
                    deliveryDeviceService.save(deliveryDevice);
                    
                    // 更新设备的运单号和车牌号
                    updateDeviceDeliveryInfo(deviceInfo.getDeviceId(), deviceType, dto.getDeliveryId(), dto.getLicensePlate());
                }
            }
            
            return AjaxResult.success("设备分配成功！");
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("设备分配失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新设备的运单号和车牌号
     */
    private void updateDeviceDeliveryInfo(String deviceId, Integer deviceType, Integer deliveryId, String licensePlate) {
        try {
            // 获取运单号
            Delivery delivery = deliveryService.getById(deliveryId);
            String deliveryNumber = delivery != null ? delivery.getDeliveryNumber() : "";
            
            if (deviceType == 2) {
                // 更新智能耳标
                LambdaUpdateWrapper<JbqClient> jbqUpdateWrapper = new LambdaUpdateWrapper<>();
                jbqUpdateWrapper.eq(JbqClient::getDeviceId, deviceId);
                jbqUpdateWrapper.set(JbqClient::getDeliveryNumber, deliveryNumber);
                jbqUpdateWrapper.set(JbqClient::getLicensePlate, licensePlate);
                jbqClientService.update(jbqUpdateWrapper);
            } else if (deviceType == 3) {
                // 更新智能项圈 - 兼容deviceId和sn两种字段
                LambdaUpdateWrapper<XqClient> xqUpdateWrapper = new LambdaUpdateWrapper<>();
                xqUpdateWrapper.and(w -> w.eq(XqClient::getDeviceId, deviceId)
                                          .or()
                                          .eq(XqClient::getSn, Long.parseLong(deviceId)));
                xqUpdateWrapper.set(XqClient::getDeliveryId, deliveryId);
                xqUpdateWrapper.set(XqClient::getDeliveryNumber, deliveryNumber);
                xqUpdateWrapper.set(XqClient::getLicensePlate, licensePlate);
                xqClientService.update(xqUpdateWrapper);
            }
        } catch (Exception e) {
            System.out.println("更新设备运单信息失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 更新运单状态
     */
    @SaCheckPermission("delivery:status")
    @PostMapping("/updateStatus")
    public AjaxResult updateStatus(@RequestBody Map<String, Object> params) {
        try {
            Integer id = (Integer) params.get("id");
            Integer status = (Integer) params.get("status");
            
            if (id == null || status == null) {
                return AjaxResult.error("运单ID和状态不能为空");
            }
            
            Delivery delivery = new Delivery();
            delivery.setId(id);
            delivery.setStatus(status);
            
            boolean success = deliveryService.updateById(delivery);
            
            if (success) {
                return AjaxResult.success("状态更新成功");
            } else {
                return AjaxResult.error("状态更新失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("状态更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除装车订单
     * 删除订单时同时清空关联设备的delivery_id和weight
     */
    @SaCheckPermission("delivery:delete")
    @GetMapping("/deleteDelivery")
    public AjaxResult deleteDelivery(@RequestParam Integer id) {
        try {
            if (id == null) {
                return AjaxResult.error("订单ID不能为空");
            }
            
            // 查询订单是否存在
            Delivery delivery = deliveryService.getById(id);
            if (delivery == null) {
                return AjaxResult.error("订单不存在");
            }
            
            // 权限检查：只有创建者或超级管理员可以删除
            Integer userId = SecurityUtil.getCurrentUserId();
            if (!SecurityUtil.isSuperAdmin() && !userId.equals(delivery.getCreatedBy())) {
                return AjaxResult.error("无权限删除此订单");
            }
            
            // 1. 先清空关联设备的delivery_id和weight
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<com.aiotagro.cattletrade.business.entity.IotDeviceData> queryWrapper = 
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            queryWrapper.eq("delivery_id", id);
            List<com.aiotagro.cattletrade.business.entity.IotDeviceData> devices = iotDeviceDataMapper.selectList(queryWrapper);
            
            int updatedCount = 0;
            for (com.aiotagro.cattletrade.business.entity.IotDeviceData device : devices) {
                device.setDeliveryId(null);
                device.setWeight(null);
                iotDeviceDataMapper.updateById(device);
                updatedCount++;
            }
            
            System.out.println("清空设备数量: " + updatedCount);
            
            // 2. 删除订单记录
            boolean deleted = deliveryService.removeById(id);
            
            if (deleted) {
                return AjaxResult.success("订单删除成功，已清空 " + updatedCount + " 个设备的绑定信息");
            } else {
                return AjaxResult.error("订单删除失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("删除订单失败：" + e.getMessage());
        }
    }

}
