package cn.cecep.talroad.controller;

import cn.cecep.talroad.common.core.exception.CommonException;
import cn.cecep.talroad.common.core.utils.poi.ExcelUtil;
import cn.cecep.talroad.common.core.web.controller.BasesController;
import cn.cecep.talroad.common.core.web.domain.AjaxResults;
import cn.cecep.talroad.common.log.annotation.Log;
import cn.cecep.talroad.common.log.enums.BusinessType;
import cn.cecep.talroad.common.security.utils.SecurityUtils;
import cn.cecep.talroad.domain.*;
import cn.cecep.talroad.enums.BasDeviceSiteTypeEnum;
import cn.cecep.talroad.service.IBasDeviceService;
import cn.cecep.talroad.service.IBasDeviceSiteService;
import cn.cecep.talroad.service.IMonElecOperationLogService;
import cn.cecep.talroad.vo.*;
import cn.cecep.talroad.vo.export.AmVideoDevFiExport;
import cn.cecep.talroad.vo.export.BasDeviceSiteExport;
import cn.cecep.talroad.vo.query.AmVideoDevFiQuery;
import cn.cecep.talroad.vo.query.BasDeviceQuery;
import cn.cecep.talroad.vo.query.BasDeviceSiteQuery;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.security.InvalidParameterException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Api(tags = "设备点位表")
@RestController
@RequestMapping("/deviceSite")
public class BasDeviceSiteController extends BasesController {

    @Autowired
    private IBasDeviceSiteService basDeviceSiteService;
    @Autowired
    private IBasDeviceService basDeviceService;
    @Autowired
    private IMonElecOperationLogService monElecOperationLogService;

    @ApiOperation(value = "设备点位列表")
    @GetMapping("/list")
    public AjaxResults<List<BasDeviceSite>> list(String deviceId) {
        List<BasDeviceSite> list = basDeviceSiteService.list(new QueryWrapper<BasDeviceSite>()
                .eq(StringUtils.isNotEmpty(deviceId), "device_id", deviceId));
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "站点名称下拉框")
    @GetMapping("/stationNameSelect")
    public AjaxResults<List<BasDeviceSiteExport>> stationNameSelect(BasDeviceSiteQuery basDeviceSiteQuery) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if (ObjectUtil.equal(roleId, 10L)) {
            basDeviceSiteQuery.setIsStatus("1");
        }
        QueryWrapper<BasDeviceSite> lambdaQueryWrapper = BasDeviceSiteQuery.createSingLambdaQueryWrapperQiye(basDeviceSiteQuery);
        lambdaQueryWrapper.orderByAsc("mam.name");
        List<BasDeviceSiteExport> list = basDeviceSiteService.selectBasDeviceSiteExportListT(lambdaQueryWrapper);
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "设施名称下拉框")
    @GetMapping("/deviceNameSelect")
    public AjaxResults<List<BasDeviceSiteExport>> deviceNameSelect(BasDeviceQuery basDeviceQuery) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if (ObjectUtil.equal(roleId, 10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            basDeviceQuery.setIndustry("XK");
            basDeviceQuery.setIsStatus("1");
        }
        QueryWrapper<BasDevice> lambdaQueryWrapper = BasDeviceQuery.createLambdaQueryWrapper(basDeviceQuery);
        lambdaQueryWrapper.orderByAsc("pollutant_name");
        List<BasDeviceSiteExport> list = basDeviceSiteService.selectBasDeviceList(lambdaQueryWrapper);
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "设备类型下拉框")
    @GetMapping("/deviceTypeSelect")
    public AjaxResults<List<BasDeviceSiteDeviceTypeVo>> deviceTypeSelect() {
        List<BasDeviceSiteDeviceTypeVo> basDeviceSiteDeviceTypeVoList = new ArrayList<>();
        for (BasDeviceSiteTypeEnum item : BasDeviceSiteTypeEnum.values()) {
            basDeviceSiteDeviceTypeVoList.add(new BasDeviceSiteDeviceTypeVo(item.getCode(), item.getName()));
        }
        return AjaxResults.success(basDeviceSiteDeviceTypeVoList);
    }

    @ApiOperation(value = "分表计电--设备功率设备点位列表")
    @GetMapping("/listPower")
    public AjaxResults<IPage<BasDeviceSite>> listPower(BasDeviceSiteQuery basDeviceSiteQuery) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if(ObjectUtil.equal(roleId,10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            basDeviceSiteQuery.setFactoryId(factoryId);
        }
        Page<BasDeviceSite> page = new Page<>(basDeviceSiteQuery.getPageNum(), basDeviceSiteQuery.getPageSize());
        if (StringUtils.isNotBlank(basDeviceSiteQuery.getDeviceName())) {
            // 先去反查设备
            List<BasDevice> basDeviceList = basDeviceService.list(new QueryWrapper<BasDevice>().eq("name", basDeviceSiteQuery.getDeviceName()));
            List<String> deviceIds = basDeviceList.stream().map(BasDevice::getDeviceId).collect(Collectors.toList());
            basDeviceSiteQuery.setDeviceIds(deviceIds);
        }
        IPage<BasDeviceSite> list = basDeviceSiteService.page(page, BasDeviceSiteQuery.createSingLambdaQueryWrapper(basDeviceSiteQuery));
        List<BasDeviceSite> records = list.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            List<String> deviceIdList = records.stream().map(BasDeviceSite::getDeviceId).collect(Collectors.toList());
            List<BasDevice> basDeviceList = basDeviceService.list(new QueryWrapper<BasDevice>().in("device_id", deviceIdList));
            Map<String, String> deviceIdNameMap = basDeviceList.stream().collect(Collectors.toMap(BasDevice::getDeviceId, BasDevice::getName));
            records.forEach(item -> {
                item.setDeviceName(deviceIdNameMap.get(item.getDeviceId()));
            });
        }
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "设备点位列表-企业端")
    @GetMapping("/listFactory")
    public AjaxResults<IPage<BasDeviceSiteExport>> listFactory(BasDeviceSiteQuery basDeviceSite) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if (ObjectUtil.equal(roleId, 10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            basDeviceSite.setFactoryId(factoryId);
            basDeviceSite.setIsStatus("1");
        }
        Page<BasDeviceSite> page = new Page<>(basDeviceSite.getPageNum(), basDeviceSite.getPageSize());
        IPage<BasDeviceSiteExport> list = basDeviceSiteService.selectDeviceNameById(page, BasDeviceSiteQuery.createLambdaQueryWrapper(basDeviceSite));
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "导出设备列表-企业端")
    @GetMapping("/exportFactory")
    @Log(title = "导出设备列表-企业端", businessType = BusinessType.EXPORT)
    public void exportFactory(HttpServletResponse response, BasDeviceSiteQuery basDeviceSite) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if (ObjectUtil.equal(roleId, 10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            basDeviceSite.setFactoryId(factoryId);
            basDeviceSite.setIsStatus("1");
        }
        List<BasDeviceSiteExport> list = basDeviceSiteService.selectBasDeviceSiteExportList(BasDeviceSiteQuery.createLambdaQueryWrapper(basDeviceSite));
        ExcelUtil<BasDeviceSiteExport> util = new ExcelUtil<BasDeviceSiteExport>(BasDeviceSiteExport.class);
        util.exportExcel(response, list, "视频监控数据");
    }

    @ApiOperation(value = "修改视频监控-企业端")
    @Log(title = "视频监控", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/editFactory")
    public AjaxResults<Boolean> editFactory(@RequestBody List<BasDeviceSiteExport> basDeviceSiteVo) {
        if (basDeviceSiteVo.size() == 0) {
            throw new InvalidParameterException("没有修改的内容");
        }
        List<BasDeviceSite> saveList = new ArrayList<BasDeviceSite>();
        List<BasDeviceSiteExport> saveExportList = new ArrayList<BasDeviceSiteExport>();
        for (BasDeviceSiteExport avdi : basDeviceSiteVo) {
            BasDeviceSite basDeviceSite = basDeviceSiteService.getById(avdi.getId());
            BasDeviceSiteExport basDeviceSiteExport = basDeviceSiteService.getByExport(avdi.getId());
            if (ObjectUtil.isEmpty(basDeviceSite)) {
                throw new CommonException(StrUtil.format("根据id{}查询不到数据", avdi.getId()));
            }
            basDeviceSite.setDeviceId(avdi.getDeviceId());
            basDeviceSite.setPointLat(avdi.getPointLat());
            basDeviceSite.setPointLng(avdi.getPointLng());
            saveList.add(basDeviceSite);
            saveExportList.add(basDeviceSiteExport);
        }
        basDeviceSiteService.saveLog(basDeviceSiteVo, saveExportList);
        //赋值
        return toAjax(basDeviceSiteService.saveOrUpdateBatch(saveList));
    }

    @ApiOperation(value = "操作日志列表-视频设备绑定排污可设备信息")
    @PostMapping("/getBasDeviceSiteCoordinateOperationLogList")
    public AjaxResults<IPage<BasDeviceSiteCoordinateOperationLog>> getBasDeviceSiteCoordinateOperationLogList(BasDeviceSiteQuery basDeviceSite) {
        try {
            IPage<BasDeviceSiteCoordinateOperationLog> list = basDeviceSiteService.getBasDeviceSiteCoordinateOperationLogList(basDeviceSite);
            return AjaxResults.success(list);
        } catch (Exception e) {
            return AjaxResults.error("操作日志列表获取失败！");
        }
    }


    /**
     * 获取分表计电--设备点位详细信息
     */
    @ApiOperation(value = "获取分表计电--设备点位详细信息")
    @GetMapping(value = "/{id}")
    public AjaxResults<BasDeviceSite> getInfo(@PathVariable("id") String id) {
        return AjaxResults.success(basDeviceSiteService.getById(id));
    }

    /**
     * 导出分表计电--设备点位列表
     */
    @ApiOperation(value = "导出分表计电--设备点位")
    @Log(title = "导出分表计电--设备点位", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BasDeviceSite basDeviceSite) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if(ObjectUtil.equal(roleId,10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            basDeviceSite.setFactoryId(factoryId);
        }
        List<BasDeviceSiteExcelVo> list = basDeviceSiteService.selectExportBasDeviceList(basDeviceSite);

        PrimitiveIterator.OfInt iterator = IntStream.iterate(1, k -> k + 1).iterator();
        list.forEach(e -> {
            e.setSerialnumber(iterator.next());
            if (e.getType() != null) {
                e.setType(BasDeviceSiteTypeEnum.GOVERNANCE.getNameByCode(e.getType()));
            }
        });

        ExcelUtil<BasDeviceSiteExcelVo> util = new ExcelUtil<BasDeviceSiteExcelVo>(BasDeviceSiteExcelVo.class);
        util.exportExcel(response, list, "分表记电系统参数设置");
    }

    /**
     * 新增设分表计电--设备点位
     */
    @ApiOperation(value = "新增分表计电--设备点位")
    @Log(title = "分表计电--设备点位", businessType = BusinessType.INSERT)
    @PostMapping(value = "/add")
    public AjaxResults<Boolean> add(@RequestBody BasDeviceSite basDeviceSite) {
        return toAjax(basDeviceSiteService.save(basDeviceSite));
    }

    /**
     * 修改分表计电--设备点位
     */
    @ApiOperation(value = "修改分表计电--设备点位")
    @Log(title = "分表计电--设备点位", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/edit")
    public AjaxResults<Boolean> edit(@RequestBody BasDeviceSiteVo basDeviceSiteVo) {
        if (ObjectUtil.isEmpty(basDeviceSiteVo)) {
            throw new InvalidParameterException("参数为空");
        }
        if (ObjectUtil.isEmpty(basDeviceSiteVo.getDeviceId())) {
            throw new InvalidParameterException("参数id为空");
        }
        BasDeviceSite basDeviceSite = basDeviceSiteService.getById(basDeviceSiteVo.getId());
        if (ObjectUtil.isEmpty(basDeviceSite)) {
            throw new CommonException(StrUtil.format("根据id{}查询不到数据", basDeviceSiteVo.getDeviceId()));
        }
        //赋值
        BeanUtil.copyProperties(basDeviceSiteVo, basDeviceSite);
        return toAjax(basDeviceSiteService.saveOrUpdate(basDeviceSite));
    }

    /**
     * 修改分表计电--设备点位
     *
     */
    @ApiOperation(value = "批量修改分表计电--设备点位")
    @Log(title = "批量分表计电--设备点位", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/editBatch")
    public AjaxResults<Boolean> editBatch(@RequestBody BasDeviceSiteVo[] basDeviceSiteVoArr) {
        if (basDeviceSiteVoArr == null || basDeviceSiteVoArr.length < 1) {
            throw new InvalidParameterException("参数为空");
        }
        basDeviceSiteService.editBatch(basDeviceSiteVoArr);
        return toAjax(true);
    }

    /**
     * 删除分表计电--设备点位
     */
    @ApiOperation(value = "删除分表计电--设备点位")
//    @RequiresPermissions("talroad:device:remove")
    @Log(title = "分表计电--设备点位", businessType = BusinessType.DELETE)
    @PostMapping("/remove/{deviceIds}")
    public AjaxResults<Boolean> remove(@PathVariable String[] deviceIds) {
        return toAjax(basDeviceSiteService.removeByIds(Arrays.asList(deviceIds)));
    }

    /**
     * 操作日志
     */
    @ApiOperation(value = "操作日志")
    @GetMapping("/editLogList")
    public AjaxResults<IPage<MonElecOperationLog>> editLogList(MonElecOperationLogQuery monElecOperationLogQuery) {
        Long roleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
        if(ObjectUtil.equal(roleId,10L)) {
            String factoryId = SecurityUtils.getLoginUser().getSysUser().getFactoryId();
            monElecOperationLogQuery.setFactoryId(factoryId);
        }
        Page<MonElecOperationLog> page = new Page<>(monElecOperationLogQuery.getPageNum(), monElecOperationLogQuery.getPageSize());
        IPage<MonElecOperationLog> list = monElecOperationLogService.page(page, monElecOperationLogQuery.createLambdaQueryWrapper(monElecOperationLogQuery));
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "分表计电大屏-分表计电数量总览")
    @GetMapping("/countOverview")
    public AjaxResults<BasDeviceSiteVo.CountOverview> countOverview() {
        BasDeviceSiteVo.CountOverview countOverview = basDeviceSiteService.getCountOverview();
        return AjaxResults.success(countOverview);
    }

    @ApiOperation(value = "分表计电大屏-分表计电点位分布")
    @GetMapping("/scatter")
    public AjaxResults<EChartsVO> scatterChart(@ApiParam(name = "type", value = "1:按区域, 2:按行业") @RequestParam("type") String type) {
        EChartsVO chartsVO = basDeviceSiteService.getScatterChart(type);
        return AjaxResults.success(chartsVO);
    }

}
