package com.zcxk.charge.web.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxk.charge.api.dto.query.SceneDto;
import com.zcxk.charge.api.dto.query.ScenePageDto;
import com.zcxk.charge.api.enums.ChargeErrorEnum;
import com.zcxk.charge.core.entity.DeviceSceneEntity;
import com.zcxk.charge.core.entity.ParmSettingEntity;
import com.zcxk.charge.core.entity.SceneEntity;
import com.zcxk.charge.web.common.FileUploadUtil;
import com.zcxk.charge.web.common.Pagination;
import com.zcxk.charge.web.service.ParmSettingService;
import com.zcxk.charge.web.service.SceneService;
import com.zcxk.charge.web.util.SceneUtil;
import com.zcxk.core.common.enums.RespCodeEnum;
import com.zcxk.core.common.pojo.AjaxMessage;
import com.zcxk.core.common.util.BeanCopyUtils;
import com.zcxk.core.oauth2.pojo.LoginUser;
import com.zcxk.core.oauth2.util.UserUtil;
import com.zcxk.core.utils.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 场景信息页面控制器
 * @author WYY
 * @date 2020-11-17 21:15
 */
@RestController
@RequestMapping("/scene")
@Api(tags = "场景管理")
public class SceneController {



    @Autowired
    private SceneService sceneService;

    @Value("${SMS.sys_config_path}")
    private String baseDir;

    @Autowired
    private ParmSettingService parmSettingService;

    @ApiOperation(value = "分页查询场景")
    @RequestMapping(value = "/selectPage", method = RequestMethod.POST)
    @ResponseBody
    public AjaxMessage selectPage(@RequestBody @Valid ScenePageDto dto) {
        IPage<SceneEntity> iPage = new Page<>(dto.getPageNum(), dto.getPageSize());
        SceneEntity sceneEntity = new SceneEntity();
        BeanCopyUtils.copyProperties(dto, sceneEntity, SceneEntity.class);
        iPage = sceneService.findPage(iPage, sceneEntity);
        Pagination<SceneEntity> pages = new Pagination<>(iPage);
        return AjaxMessage.success(pages);
    }

    @ApiOperation(value = "查询场景树")
    @RequestMapping(value = "/selectList", method = RequestMethod.GET)
    @ResponseBody
    public AjaxMessage allList(@RequestParam String sceneTypeName) {
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setSceneTypeName(sceneTypeName);
        return AjaxMessage.success(sceneService.findAllList(new SceneEntity()));
    }

    @ApiOperation(value = "查询场景树")
    @RequestMapping(value = "/selectListForParm", method = RequestMethod.GET)
    @ResponseBody
    public AjaxMessage selectListForParm(@RequestParam(required = false) Long comId,
                                         @RequestParam(required = false) Long deptId) {
        if (comId != null) {
            SceneEntity sceneEntity = new SceneEntity();
            sceneEntity.setCompanyOrgId(comId);
            sceneEntity.setDeptOrgId(deptId);
            List<SceneEntity> menuEntities = sceneService.findAllList(sceneEntity);
            return AjaxMessage.success(menuEntities);
        }
        return AjaxMessage.success();
    }

    @ApiOperation(value = "场景图片")
    @RequestMapping(value = "addSceneImage", method = RequestMethod.POST)
    @ResponseBody
    public AjaxMessage addUserPhoto(@ApiParam(value = "场景图片", required = true) @RequestParam("avatarfile") MultipartFile file) {
        String avatar = "";
        if (!file.isEmpty()) {
            try {
                avatar = FileUploadUtil.uploadWeb(baseDir, file);
            } catch (IOException e) {
                return AjaxMessage.fail(RespCodeEnum.ERROR_500.getStatus(), e.getMessage());
            }
        }
        return AjaxMessage.success(avatar);
    }

    @ApiOperation(value = "上传多个场景图片")
    @RequestMapping(value = "addSceneImages", method = RequestMethod.POST)
    @ResponseBody
    public AjaxMessage addUserPhotos(@ApiParam(value = "场景图片", required = true) @RequestParam("avatarfile") MultipartFile[] file) {
        String avatar = "";
        if (file.length > 0) {
            for (MultipartFile item : file) {
                try {
                    avatar += FileUploadUtil.uploadWeb(baseDir, item)+",";
                } catch (IOException e) {
                    return AjaxMessage.fail(RespCodeEnum.ERROR_500.getStatus(), e.getMessage());
                }
            }
        }
        return AjaxMessage.success( avatar.substring(0,avatar.length()-1));
    }

    @ApiOperation(value = "新增")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public AjaxMessage<Integer> addScene(@ApiParam(value = "场景", required = true) @RequestBody SceneEntity scene) {
        int result = sceneService.addScene(scene) ? 1 : 0;
        return AjaxMessage.success(result);
    }

    @ApiOperation(value = "按ID查询场景")
    @RequestMapping(value = "/selectById", method = RequestMethod.GET)
    @ResponseBody
    public AjaxMessage<SceneEntity> selectById(@ApiParam(value = "ID", required = true) @RequestParam Long id) {
        return AjaxMessage.success(sceneService.findSceneById(id));
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "修改保存场景信息")
    public AjaxMessage editScene(@ApiParam(value = "场景", required = true) @RequestBody SceneEntity scene) {
        if(scene.getParentSceneId()!=null&&scene.getParentSceneId().equals(scene.getId())){
            return AjaxMessage.success(ChargeErrorEnum.SCENE_PARENT_ALREADY_EXISTS);
        }
        int result = sceneService.updateSceneById(scene) ? 1 : 0;
        return AjaxMessage.success(result);
    }

    @RequestMapping(value = "/findByParentIdsLike", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据父级ID查询所有子节点及本身")
    public  List<Long> findByParentIdsLike(@ApiParam(value = "父级场景ID")@RequestParam(required = false) Long id) {
        return sceneService.findByParentIdsLike(id);
    }

    @ApiOperation(value = "删除")
    @RequestMapping(value = "/deleteByIds", method = RequestMethod.POST)
    @ResponseBody
    public AjaxMessage del(@ApiParam(value = "场景ID", required = true) @RequestBody Long[] ids) {
        List<SceneEntity> scenes = sceneService.findByParentSceneIds(ids);
        if (scenes.size() > 0) {
            return AjaxMessage.success(ChargeErrorEnum.EXSIT_IS_PARENT_ERROR);
        }
        int result = sceneService.delSceneByIds(ids) ? 1 : 0;
        return AjaxMessage.success( result);
    }

    @ApiOperation(value = "一级场景查询",notes = "sceneTypeName 为水源、水厂、泵站")
    @RequestMapping(value = "/selectByTypeName", method = RequestMethod.GET)
    @ResponseBody
    public AjaxMessage selectByTypeName(@ApiParam(value = "一级场景类型名称", required = true) @RequestParam String sceneTypeName) {
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setSceneTypeName(sceneTypeName);
        return AjaxMessage.success(sceneService.selectByTypeName(sceneEntity));
    }
    @RequestMapping(value = "/findByParentId", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据父级ID查询所有子节点及本身(全部信息)")
    public  AjaxMessage findByParentId(@ApiParam(value = "父级场景ID")@RequestParam(required = false) Long id) {
        return AjaxMessage.success(sceneService.findByParentId(id));
    }

    @RequestMapping(value="batchSave" , method = RequestMethod.POST)
    @ApiOperation(value = "批量绑定设备及参数(绑定设备)")
    public AjaxMessage<Integer> batchEdit( @ApiParam(value = "设备信息") @RequestBody List<DeviceSceneEntity> deviceScenes){
        sceneService.saveUpdateBatch(deviceScenes);
        return AjaxMessage.success(1 );
    }

    @RequestMapping(value = "/selectAlarmSceneAndDevice", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "场景及设备故障率")
    public  AjaxMessage<Object> selectAlarmSceneAndDevice(@RequestBody @Valid SceneDto dto) throws ParseException {
        LocalDate localDate = LocalDate.now();
        LoginUser loginUser = UserUtil.getCurrentUser();
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setTenantId(loginUser.getTenantId());
        sceneEntity.setProgramItems(loginUser.getProgramItemList());
        sceneEntity.setUserType(loginUser.getType());
        // 1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        sceneEntity.setPermissonType(loginUser.getPermissonType());
        int days = 1;
        String startDate = dto.getStartDate();
        String endDate   = dto.getEndDate();
        switch (dto.getStatsType()) {
            case 0:
                startDate = String.format("%s-01", startDate);
                endDate = SceneUtil.subMonth(startDate, 1);

                days = DateUtil.getDaysOfMonth(startDate);
                if (localDate.getYear() == Integer.parseInt(startDate.substring(0,4))&&
                    localDate.getMonthValue() == Integer.parseInt(startDate.substring(5,7))){
                    days = localDate.getDayOfMonth();
                }
                break;
            case 1:
                int year = Integer.parseInt(startDate);
                if(year == localDate.getYear()){
                    days = DateUtil.differentDaysByMillisecond(String.format("%s-%s-%s",startDate,1,1),
                            String.format("%s-%s-%s",localDate.getYear(),localDate.getMonthValue(),localDate.getDayOfMonth()+1));
                }
                else {
                    days = LocalDate.of(year, 1, 1).lengthOfYear();
                }
                startDate = String.format("%s-01-01", startDate);
                endDate = SceneUtil.subYear(startDate, 1);
                break;
            case 2:
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);
                if(SceneUtil.isCurrentMonth(endDate)==true){
                    endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = SceneUtil.subMonth(endDate, 1);
                }
                days = DateUtil.differentDaysByMillisecond(startDate,endDate);
                break;
            default:
                break;
        }
        ParmSettingEntity parmSettingEntity = new ParmSettingEntity();
        parmSettingEntity.setTenantId(loginUser.getTenantId());
        parmSettingEntity.setCompanyOrgId(Long.valueOf(loginUser.getCompanyId().toString()));
        parmSettingEntity.setParmType(3);
        List<ParmSettingEntity> paramSettingList = parmSettingService.findList(parmSettingEntity);
        if ( paramSettingList.size() == 0 ){
            return new AjaxMessage<>(55555,"没有配置故障率参数",null);
        }
        ParmSettingEntity parmSetting = paramSettingList.get(0);
        String paramValue = parmSetting.getParmValue();
        String[] params =  paramValue.split(";");
        if (params.length!=3 ){
           return new AjaxMessage<>(55555,"参数设置格式错误!请参照正确格式设置:0.5;0.5~0.2;0.2",null);
        }
        String[] mParam = params[1].split("~");
        if (mParam.length != 2){
           return new AjaxMessage<>(55555,"参数设置格式错误!请参照正确格式设置:0.5;0.5~0.2;0.2",null);
        }
        if (SceneUtil.validateNumber(params[0])==false || SceneUtil.validateNumber(params[2])==false
                || SceneUtil.validateNumber(mParam[0])==false || SceneUtil.validateNumber(mParam[1])==false){
            return new AjaxMessage<>(55555,"参数设置格式错误!请参照正确格式设置:0.5;0.5~0.2;0.2",null);
        }
        List<Map<String,Object>> list = sceneService.selectAlarmSceneAndDevice(sceneEntity, startDate, endDate);
        for(int i = 0;i < list.size(); i++) {
            Map<String,Object> map = list.get(i);
            double amount =Double.parseDouble(map.get("amount").toString());
            double rate =amount / days;
            map.put("rate",rate);

            if(rate>=Double.parseDouble(params[0])){
                map.put("level","高");
            }
            else if(rate>=Double.parseDouble(mParam[1]) && rate<Double.parseDouble(mParam[0])){
                map.put("level","中");
            }
            else if(rate<Double.parseDouble(params[2])){
                map.put("level","低");
            }
        }
        return AjaxMessage.success(list);
    }

    @RequestMapping(value = "/alarmTimesStatistics", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "报警次数统计")
    public AjaxMessage alarmTimesStatistics(@RequestBody @Valid SceneDto dto) throws ParseException {
        LocalDate localDate = LocalDate.now();
        LoginUser loginUser = UserUtil.getCurrentUser();
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setTenantId(loginUser.getTenantId());
        sceneEntity.setProgramItems(loginUser.getProgramItemList());
        sceneEntity.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        sceneEntity.setPermissonType(loginUser.getPermissonType());
        sceneEntity.setId(Long.parseLong(String.valueOf(dto.getId())));
        String startDate = dto.getStartDate();
        String endDate   = dto.getEndDate();
        switch (dto.getStatsType()) {
            case 0:
                startDate = String.format("%s-01", startDate);
                if(SceneUtil.isCurrentMonth(startDate)==true){
                    endDate = String.format("%s-%s", startDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = SceneUtil.subMonth(startDate, 1);
                }
                break;
            case 1:
                startDate = String.format("%s-01-01", startDate);
                if(SceneUtil.isCurrentYear(startDate)==true){
                    endDate = String.format("%s-%s-01", localDate.getYear(),localDate.getMonthValue()+1);
                }
                else {
                    endDate = SceneUtil.subYear(startDate, 1);
                }
                break;
            case 2:
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);

                if(SceneUtil.isCurrentMonth(endDate)==true){
                    endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = SceneUtil.subMonth(endDate, 1);
                }
                break;
            default:
                break;
        }
        List<Map<String,Object>> list = new ArrayList<>();
        if(dto.getStatsType() == 0 || dto.getStatsType()== 2){
            list = sceneService.selectMonthAlarmTimes(sceneEntity, startDate, endDate,dto.getSort());
        } else if(dto.getStatsType() == 1){
            list = sceneService.selectYearAlarmTimes(sceneEntity, startDate, endDate,dto.getSort());
        }
        return AjaxMessage.success(list);
    }

    @RequestMapping(value = "/selectAlarmDeviceIdBySenceId", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据场景ID获取报警设备的ID")
    public AjaxMessage selectAlarmDeviceIdBySenceId(@ApiParam(value = "设备或场景ID", required = true) @RequestParam int id){
        return AjaxMessage.success(sceneService.selectAlarmDeviceIdBySenceId(id));
    }

    @RequestMapping(value = "/selectAlarmLable", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "报警标签")
    public AjaxMessage selectAlarmLable(@RequestBody @Valid SceneDto dto) throws ParseException {
        LocalDate localDate = LocalDate.now();
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setId(Long.parseLong(String.valueOf(dto.getId())));
        String startDate = dto.getStartDate();
        String endDate   = dto.getEndDate();
        switch (dto.getStatsType()) {
            case 0:
                startDate = String.format("%s-01", startDate);
                endDate = SceneUtil.subMonth(startDate, 1);
                break;
            case 1:
                startDate = String.format("%s-01-01", startDate);
                endDate = SceneUtil.subYear(startDate, 1);
                break;
            case 2:
                startDate = String.format("%s-01", startDate);
                endDate = String.format("%s-01", endDate);
                if(SceneUtil.isCurrentMonth(endDate)==true){
                   endDate = String.format("%s-%s", endDate.substring(0,7),localDate.getDayOfMonth()+1);
                }
                else {
                    endDate = SceneUtil.subMonth(endDate, 1);
                }
                break;
            default:
                break;
        }
        List<Map<String,Object>> list = sceneService.selectAlarmLable(sceneEntity,startDate,endDate,dto.getSort());
        return AjaxMessage.success(list);
    }




}
