package com.ozs.web.controller.accountmanagment;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ozs.common.annotation.Log;
import com.ozs.common.core.controller.BaseController;
import com.ozs.common.core.domain.AjaxResult;
import com.ozs.common.core.domain.entity.SysDictData;
import com.ozs.common.core.redis.RedisCache;
import com.ozs.common.enums.BusinessType;
import com.ozs.common.utils.ChineseToPingyin;
import com.ozs.common.utils.HeartbeatUtils;
import com.ozs.common.utils.StringUtils;
import com.ozs.common.utils.file.FileUtils;
import com.ozs.common.utils.poi.ExcelUtil;
import com.ozs.entity.*;
import com.ozs.entity.vo.BaseRailwayManagementVo;
import com.ozs.entity.vo.BaseVehicleTerminalDto;
import com.ozs.entity.vo.BaseVehicleTerminalVo;
import com.ozs.entity.vo.BaseVehicleVo;
import com.ozs.entity.vo.VehicleTreeVo;
import com.ozs.service.BaseCameraManagementService;
import com.ozs.service.BaseDeviceDynamicManagementService;
import com.ozs.service.BaseRailwayManagementService;
import com.ozs.service.BaseVehicleService;
import com.ozs.system.service.DataScoreUtil;
import com.ozs.system.service.ISysDictTypeService;
import com.ozs.utils.CameraUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 机车信息表 前端控制器
 * </p>
 *
 * @author ozs
 * @since 2023-04-11
 */
@RestController
@RequestMapping("/baseVehicle")
@Slf4j
public class BaseVehicleController extends BaseController {
    @Resource
    BaseRailwayManagementService baseRailwayManagementService;
    @Resource
    BaseCameraManagementService cameraManagementService;
    @Autowired
    private DataScoreUtil dataScoreUtil;
    @Autowired
    private BaseCameraManagementService baseCameraManagementService;
    @Autowired
    private BaseVehicleService baseVehicleService;
    @Autowired
    private ISysDictTypeService dictTypeService;
    @Resource
    BaseDeviceDynamicManagementService baseDeviceDynamicManagementService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private HeartbeatUtils heartbeatUtils;

    /**
     * 车载终端挂载列表
     *
     * @param baseVehicleVo
     * @return
     */
    @PostMapping("/vehicleTerminal")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult vehicleTerminal(@RequestBody BaseVehicleVo baseVehicleVo) {
        if (StringUtils.isEmptySunhh(baseVehicleVo) || StringUtils.isEmptySunhh(baseVehicleVo.getVehicleCode())) {
            return AjaxResult.error("机车号不能为空！");
        }
        IPage<BaseVehicleTerminalVo> baseVehicleTerminalVoIPage = baseVehicleService.vehicleTerminal(baseVehicleVo);
        return AjaxResult.success(baseVehicleTerminalVoIPage);
    }

    /**
     * 机车是否挂载终端
     *
     * @param baseVehicleVo
     * @return
     */
    @PostMapping("/isMount")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult isMount(@RequestBody BaseVehicleVo baseVehicleVo) {
        if (StringUtils.isEmptySunhh(baseVehicleVo) || StringUtils.isEmptySunhh(baseVehicleVo.getVehicleCode())) {
            return AjaxResult.error("机车号不能为空！");
        }
        Boolean isMount = baseVehicleService.isMount(baseVehicleVo);
        return AjaxResult.success(isMount);
    }

    /**
     * 车载终端挂载 取消挂载
     *
     * @param baseTerminal
     * @return
     */
    @PostMapping("/vehicleTerminalUnmount")
    @Log(title = "机车信息管理", businessType = BusinessType.INSERT)
    public AjaxResult vehicleTerminalUnmount(@RequestBody BaseVehicleTerminal baseTerminal) {
        if (StringUtils.isEmptySunhh(baseTerminal) || StringUtils.isEmptySunhh(baseTerminal.getVehicleCode())) {
            return AjaxResult.error("机车号、终端编码不能为空！");
        }
        return baseVehicleService.vehicleTerminalUnmount(baseTerminal);
    }

    /**
     * 车载终端挂载 保存
     *
     * @param baseTerminal
     * @return
     */
    @PostMapping("/vehicleTerminalAdd")
    @Log(title = "机车信息管理", businessType = BusinessType.INSERT)
    public AjaxResult vehicleTerminalAdd(@RequestBody BaseVehicleTerminal baseTerminal) {
        if (StringUtils.isEmptySunhh(baseTerminal) || StringUtils.isEmptySunhh(baseTerminal.getVehicleCode())
                || StringUtils.isEmptySunhh(baseTerminal.getTerminalCode())) {
            return AjaxResult.error("机车号、终端编码不能为空！");
        }
        return baseVehicleService.vehicleTerminalAdd(baseTerminal, getUserId());
    }

    /**
     * 机车信息表 分页查询
     *
     * @param baseVehicle
     * @return
     */
    @PostMapping("/vehicleList")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult vehicleList(@RequestBody BaseVehicleVo baseVehicle) {
        IPage<BaseVehicle> baseVehicleList = baseVehicleService.vehicleList(baseVehicle);
        return AjaxResult.success(baseVehicleList);
    }

    /**
     * 未解除报警的相机
     *
     * @param 
     * @return
     */
    @GetMapping("/vehicleList/nonContactAlarmCamera")
    @Log(title = "相机信息管理", businessType = BusinessType.SELECT)
    public AjaxResult nonContactAlarmCamera(String cameraCode) {
        return baseCameraManagementService.nonContactAlarmCamera(cameraCode);
    }

    /**
     * 机车信息表 详情
     *
     * @param baseVehicle
     * @return
     */
    @PostMapping("/vehicleDetails")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult vehicleDetails(@RequestBody BaseVehicle baseVehicle) {
        if (StringUtils.isEmptySunhh(baseVehicle) || StringUtils.isEmptySunhh(baseVehicle.getId())) {
            return AjaxResult.error("机车id不能为空！");
        }
        return baseVehicleService.vehicleDetails(baseVehicle);
    }

    /**
     * 机车信息表 新增
     *
     * @param baseVehicle
     * @return
     */
    @PostMapping("/vehicleAdd")
    @Log(title = "机车信息管理", businessType = BusinessType.INSERT)
    public AjaxResult vehicleAdd(@RequestBody BaseVehicle baseVehicle) {
        if (StringUtils.isEmptySunhh(baseVehicle) || StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
            return AjaxResult.error("机车号不能为空！");
        }
        return baseVehicleService.vehicleAdd(baseVehicle, getUserId());
    }

    /**
     * 机车信息表 修改
     *
     * @param baseVehicle
     * @return
     */
    @PostMapping("/vehicleUpdate")
    @Log(title = "机车信息管理", businessType = BusinessType.UPDATE)
    public AjaxResult vehicleUpdate(@RequestBody BaseVehicle baseVehicle) {
        if (StringUtils.isEmptySunhh(baseVehicle) || StringUtils.isEmptySunhh(baseVehicle.getId())) {
            return AjaxResult.error("修改ID不能为空！");
        }
        if ( StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
            return AjaxResult.error("机车号不能为空！");
        }
        return baseVehicleService.vehicleUpdate(baseVehicle, getUserId());
    }

    /**
     * 机车信息表 删除
     *
     * @param ids
     * @return
     */
    @RequestMapping("/vehicleDelete/{ids}")
    @Log(title = "机车信息管理", businessType = BusinessType.DELETE)
    public AjaxResult vehicleDelete(@PathVariable List<Long> ids) {
        if (StringUtils.isEmptySunhh(ids)) {
            return AjaxResult.error("删除ID不能为空！");
        }
        return baseVehicleService.removeByIdList(ids);
    }

    /**
     * 机车信息导入
     *
     * @param file
     * @param updateSupport
     * @return
     * @throws Exception
     */
    @PostMapping("/importBaseVehicle")
    @Log(title = "机车信息管理", businessType = BusinessType.IMPORT)
    public AjaxResult importBaseVehicle(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<BaseVehicle> util = new ExcelUtil<BaseVehicle>(BaseVehicle.class);
        List<BaseVehicle> accountManageList = util.importExcel(file.getInputStream());
        String message = baseVehicleService.importBaseVehicle(accountManageList, updateSupport, getUserId());
        return AjaxResult.success(message);
    }

    /**
     * 机车信息导出
     *
     * @param response
     */
    @PostMapping("/exportBaseVehicle")
    @Log(title = "机车信息管理", businessType = BusinessType.EXPORT)
    public void exportBaseVehicle(HttpServletResponse response, @RequestBody BaseVehicle baseVehicle) {
        List<BaseVehicle> baseVehicleList = baseVehicleService.exportBaseVehicle(baseVehicle);
        ExcelUtil<BaseVehicle> util = new ExcelUtil<>(BaseVehicle.class);
        util.exportExcel(response, baseVehicleList, "机车信息台账数据");
    }

    /**
     * 机车信息模板下载
     *
     * @param response
     */
    @GetMapping("/downloaExcel")
    @Log(title = "机车信息管理", businessType = BusinessType.OTHER)
    public void downloadZip(HttpServletResponse response) {
        try {
            InputStream resourceAsStream = this.getClass().getResourceAsStream("/template/BaseVehicle.xlsx");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, "机车信息模板.xlsx");
            FileUtils.writeBytesByInput(resourceAsStream, response.getOutputStream());
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 首页--机车树结构
     * 机车行驶日志中有线路编码
     * 根据机车在行驶日志中记录的最后时间
     * <p>
     * 获取机车列表和线路编码,组成树结构
     */
    @PostMapping("/vehicleTree")
    @Log(title = "首页机车列表", businessType = BusinessType.SELECT)
    public AjaxResult vehicleTree(@RequestBody VehicleTreeVo vehicleTreeVo) {
        if (!ObjectUtils.isEmpty(vehicleTreeVo.getMils())) {
            vehicleTreeVo.setMils(new BigDecimal(vehicleTreeVo.getMils()).multiply(new BigDecimal(1000)).setScale(0, BigDecimal.ROUND_DOWN).toString());
        }
        VehicleTree vehicleTree = baseDeviceDynamicManagementService.vehicleTree(vehicleTreeVo);
        List<VehicleTree> children = vehicleTree.getChildren();
        children.sort(new Comparator<VehicleTree>() {
            @Override
            public int compare(VehicleTree o1, VehicleTree o2) {
                String name1 = ChineseToPingyin.convertHanziToPinyin(o1.getName());
                String substring1 = name1.substring(0, 1);
                String name2 = ChineseToPingyin.convertHanziToPinyin(o2.getName());
                String substring2 = name2.substring(0, 1);
                return substring1.compareTo(substring2);
            }
        });
        return success(vehicleTree);
    }

    @GetMapping("/getDate/{terminalCode}")
    @Log(title = "相机台账管理", businessType = BusinessType.OTHER)
    public AjaxResult getDate(@PathVariable String terminalCode) {

        return AjaxResult.success(baseDeviceDynamicManagementService.getPlayInfoByTerminalCode(terminalCode));
    }

    /**
     * 前端传终端码
     * 1、根据终端码  查询  行驶记录表  获取最新的机车位置  \ 司机的目视距离；
     * 2、根据 机车的位置  和线路 查询  机车前方1路视频 （ 10KM  是否有报警 ）
     */
    @PostMapping("/vehicleCurrentStream")
    @Log(title = "通过终端编码获取流", businessType = BusinessType.SELECT)
    public AjaxResult vehicleCurrentStream(BaseVehicleTerminalDto vehicleTerminalDto) {
        LambdaQueryWrapper<BaseCameraManagement> camera = new LambdaQueryWrapper<BaseCameraManagement>();
        camera.ge(BaseCameraManagement::getInstallMile, vehicleTerminalDto.getTravelMile()+1000);
        camera.eq(BaseCameraManagement::getLineDir, vehicleTerminalDto.getLineDir());
        camera.eq(BaseCameraManagement::getRailwayCode, vehicleTerminalDto.getRailwayCode());
        camera.eq(BaseCameraManagement::getOnline,2);
        camera.eq(BaseCameraManagement::getEnableOrNot,1);
        camera.orderByAsc(BaseCameraManagement::getInstallMile);
        camera.last("limit 4");
        List<BaseCameraManagement> baseCameraManagementList = baseCameraManagementService.list(camera);
        if (!ObjectUtils.isEmpty(baseCameraManagementList)) {
            List<String> list=new ArrayList<>();
            for (BaseCameraManagement baseCameraManagement : baseCameraManagementList) {
                String flv = CameraUtil.getPlayFlv(baseCameraManagement.getCameraCode(), baseCameraManagement.getChannel());
                list.add(flv);
            }
            return AjaxResult.success(list);
        }else {
            return AjaxResult.error("前方没有可用的相机");
        }
//        String heartbeat = heartbeatUtils.getHeartbeat(Constant.HERTBEA_KEY + zdCode);
//        Map<String, Object> cacheMap = JSON.parseObject(heartbeat);
//        if (!ObjectUtils.isEmpty(cacheMap)) {
//            Map<String, String> ccMap = new HashMap<>();
//            Object cameraCode = cacheMap.get("cameraCode");
//            //Object stream = cacheMap.get("currentStream");
//            if (!ObjectUtils.isEmpty(cameraCode)) {
//                LambdaQueryWrapper<BaseCameraManagement> bcWrapper = new LambdaQueryWrapper<>();
//                bcWrapper.eq(BaseCameraManagement::getCameraCode, cameraCode.toString());
//                BaseCameraManagement one = cameraManagementService.getOne(bcWrapper);
//                if (!ObjectUtils.isEmpty(one)) {
//                    //相机编码和实时流
//                    ccMap.put("cameraCode", cameraCode.toString());
//                    ccMap.put("currentStream", CameraUtil.getPlayFlv(cameraCode.toString(), one.getChannel()));
//                    //行别
//                    String lineDirStr = one.getLineDir() == 1 ? "上行" : "下行";
//                    ccMap.put("lineDir", lineDirStr);
//                    //安装里程位置
//                    String mils = AppendUtils.stringAppend(one.getInstallMile());
//                    ccMap.put("installMile", mils);
//                    //线路名称
//                    LambdaQueryWrapper<BaseRailwayManagement> queryWrapper = new LambdaQueryWrapper<BaseRailwayManagement>();
//                    if (!ObjectUtils.isEmpty(one.getRailwayCode())) {
//                        queryWrapper.eq(BaseRailwayManagement::getRailwayCode, one.getRailwayCode());
//                    }
//                    BaseRailwayManagement baseRailwayManagement = baseRailwayManagementService.getOne(queryWrapper);
//                    ccMap.put("railwayName", baseRailwayManagement.getRailwayName());
//                    return AjaxResult.success(ccMap);
//                }
//                return AjaxResult.error("当前机车未绑定终端");
//            }
//        }
//        return AjaxResult.error("当前机车无实时流");
    }

    /**
     * 机车信息表 （首页地图中的机车信息）
     *
     * @return
     */
    @PostMapping("/homeVehicleList")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult homeVehicleList(@RequestBody BaseVehicleVo baseVehicle) {
        return AjaxResult.success(baseVehicleService.vehicleListDT(baseVehicle));
    }

    /**
     * 点击机车获取前方四路视频 （首页地图中的机车信息）
     *
     * @return
     */
    @PostMapping("/videoCaptureUrl")
    @Log(title = "机车信息管理", businessType = BusinessType.SELECT)
    public AjaxResult videoCaptureUrl(@RequestBody BaseVehicleTerminalDto baseVehicleTerminalDto) {
        return AjaxResult.success(baseCameraManagementService.videoCaptureUrl(baseVehicleTerminalDto));
    }

    /**
     * 查询线路信息集合
     *
     * @param baseRailwayManagementVo
     * @return
     */
    @PostMapping("/railwayList")
    @Log(title = "线路台账管理", businessType = BusinessType.SELECT)
    public AjaxResult selectBaseLineManagement(@RequestBody BaseRailwayManagementVo baseRailwayManagementVo) {
        LambdaQueryWrapper<BaseRailwayManagement> lw = new LambdaQueryWrapper<BaseRailwayManagement>();
        if (!StringUtils.isBlank(baseRailwayManagementVo.getRailwayCode())) {
            lw.like(BaseRailwayManagement::getRailwayCode, "%" + baseRailwayManagementVo.getRailwayCode() + "%");
        }
        if (!ObjectUtils.isEmpty(baseRailwayManagementVo.getRailwayType()) && baseRailwayManagementVo.getRailwayType() != 0) {
            lw.eq(BaseRailwayManagement::getRailwayType, baseRailwayManagementVo.getRailwayType());
        }
        List<BaseRailwayManagement> list = baseRailwayManagementService.list(lw);
        List<SysDictData> data = dictTypeService.selectDictDataByType("railway_type");
        List<BaseRailwayManagement> dto1 = new ArrayList<>();
        if (!ObjectUtils.isEmpty(list)) {
            dto1 = list.stream().map(o -> {
                for (SysDictData datum : data) {
                    if (datum.getDictValue().equals(o.getRailwayType().toString())) {
                        o.setRailwayTypeName(datum.getDictLabel());
                    }
                }
                return o;
            }).collect(Collectors.toList());
        }
        return AjaxResult.success(dto1);
    }
}

