package com.yunfeiyun.agmp.fms.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.core.domain.AjaxResult;
import com.yunfeiyun.agmp.common.enums.CommonEnums;
import com.yunfeiyun.agmp.common.enums.FmsMessageResVoType;
import com.yunfeiyun.agmp.common.enums.TaskStatus;
import com.yunfeiyun.agmp.common.exception.BizException;
import com.yunfeiyun.agmp.common.utils.ConfigUtils;
import com.yunfeiyun.agmp.common.utils.DateUtils;
import com.yunfeiyun.agmp.common.utils.StringUtils;
import com.yunfeiyun.agmp.common.utils.weather.WeatherReqVo;
import com.yunfeiyun.agmp.common.utils.weather.WeatherUtil;
import com.yunfeiyun.agmp.fms.domain.FmsBlock;
import com.yunfeiyun.agmp.fms.domain.FmsLand;
import com.yunfeiyun.agmp.fms.domain.FmsSolar;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsPlanReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsTaskListReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsTaskPickListReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.ScreenDataReqVo;
import com.yunfeiyun.agmp.fms.domain.resvo.*;
import com.yunfeiyun.agmp.fms.service.*;
import com.yunfeiyun.agmp.fms.util.DataAuthUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * 首页Controller
 *
 * @author 刘耀文
 */
@RestController
@RequestMapping("/fms/console")
public class FmsConsoleController {
    private static final Logger log = LoggerFactory.getLogger(FmsConsoleController.class);
    @Resource
    private IFmsSolarService iFmsSolarService;
    @Autowired
    private IFmsLandService fmsLandService;
    @Autowired
    private IFmsBlockService fmsBlockService;
    @Autowired
    private IFmsPlanService fmsPlanService;
    @Autowired
    private IFmsTaskService fmsTaskService;
    @Autowired
    private IFmsWarnService fmsWarnService;
    @Autowired
    private IWmsChangeapplyService wmsChangeapplyService;
    @Autowired
    private IFmsTaskpickService fmsTaskpickService;
    @Autowired
    private DataAuthUtil dataAuthUtil;

    /**
     * 查询天气信息
     */
    @PreAuthorize("@ss.hasPermi('fms:console:weather:info')")
    @GetMapping("/weather/info")
    public AjaxResult weatherInfo(ScreenDataReqVo reqVo) {

        FmsWeatherInfoResVo fmsWeatherInfoResVo = new FmsWeatherInfoResVo();
        FmsSolar fmsSolar = iFmsSolarService.getNowSolar(DateUtils.dateTimeNow());
        fmsWeatherInfoResVo.setSolarName(fmsSolar.getSolarName());
        fmsWeatherInfoResVo.setSolarRemark(fmsSolar.getSolarRemark());
        fmsWeatherInfoResVo.setSolarDigest(fmsSolar.getSolarDigest());
        return AjaxResult.success(fmsWeatherInfoResVo);
    }

    public static void main1(String[] args){
        WeatherUtil.getWeather(null);
    }
    /**
     * 获取基地统计信息
     */
    @PreAuthorize("@ss.hasPermi('fms:console:top:stat')")
    @GetMapping(value = "/top/stat")
    public AjaxResult selectFmsLandTotal() {
        FmsLandTotalResVo fmsLandTotalResVo = fmsLandService.selectFmsLandTotal(null);

        BigDecimal blockArea = fmsBlockService.selectSumAreaByLandId(null);
        fmsLandTotalResVo.setBlockAreaSum(blockArea == null ? "0" : blockArea.toString());
        FmsPlanReqVo fmsPlanReqVo = new FmsPlanReqVo();
        fmsPlanReqVo.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());
        BigDecimal planArea = fmsPlanService.selectSumPlanArea(fmsPlanReqVo);
        fmsLandTotalResVo.setPlanAreaSum(planArea == null ? "0" : planArea.toString());
        int count = fmsPlanService.selectCountFmsPlan(fmsPlanReqVo);
        fmsLandTotalResVo.setPlanCropTypeNum(String.valueOf(count));

        if(null != planArea){
            BigDecimal divide = planArea.multiply(new BigDecimal(100)).divide(blockArea, 2, BigDecimal.ROUND_HALF_UP);
            fmsLandTotalResVo.setBlockUsageRate(divide.toString());
        }else {
            fmsLandTotalResVo.setBlockUsageRate("0");
        }
        return AjaxResult.success(fmsLandTotalResVo);
    }

    /**
     * 获取农事任务统计信息
     */
    @PreAuthorize("@ss.hasPermi('fms:console:task:stat')")
    @GetMapping(value = "/task/stat")
    public AjaxResult selectTaskStat() {
        FmsTaskListReqVo reqVo = new FmsTaskListReqVo();
//        reqVo.setTaskAuditstatus(TaskStatus.COMPLETED.getCode());
//        reqVo.setTaskAudittype(CommonEnums.TASK_AUDIT_TYPE_DOWN.getCode() + "," + CommonEnums.TASK_AUDIT_TYPE_UP.getCode());
        reqVo.setStartDate(LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        reqVo.setEndDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        List<FmsTaskTypeCountResVo> typeCounts = fmsTaskService.selectCountFmsTaskByType(reqVo);

        //待执行
//        reqVo.setTaskAuditstatus(TaskStatus.EXECUTING.getCode() + "," + TaskStatus.UNAUDITED.getCode());
//        int count1 = fmsTaskService.selectCountFmsTask(reqVo);

        reqVo.setTaskAuditstatus(TaskStatus.COMPLETED.getCode());
        reqVo.setStartDate(LocalDateTime.of(LocalDate.now(), LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        int count1 = fmsTaskService.selectCountFmsTask(reqVo);

        reqVo.setTaskAuditstatus(TaskStatus.COMPLETED.getCode());
        reqVo.setStartDate(LocalDateTime.of(LocalDate.now(), LocalTime.MIN).with(DayOfWeek.MONDAY).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        int count2 = fmsTaskService.selectCountFmsTask(reqVo);

        reqVo.setStartDate(LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        int count3 = fmsTaskService.selectCountFmsTask(reqVo);

        reqVo.setStartDate(LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        int count4 = fmsTaskService.selectCountFmsTask(reqVo);

        Map<String, Object> statMap = new HashMap<>();
        statMap.put("count1", count1);
        statMap.put("count2", count2);
        statMap.put("count3", count3);
        statMap.put("count4", count4);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("typeCounts", typeCounts);
        resultMap.put("statMap", statMap);

        return AjaxResult.success(resultMap);
    }


    /**
     * 获取农事任务统计信息
     */
    @PreAuthorize("@ss.hasPermi('fms:console:message:map')")
    @GetMapping(value = "/message/map")
    public AjaxResult selectMessageMap() {
        LinkedHashMap<String, FmsMessageResVo> fmsMessageResVoMap = new LinkedHashMap<>();
        fmsMessageResVoMap.put(FmsMessageResVoType.WARN.getType(),new FmsMessageResVo(FmsMessageResVoType.WARN));
        fmsMessageResVoMap.put(FmsMessageResVoType.TASK.getType(),new FmsMessageResVo(FmsMessageResVoType.TASK));
        fmsMessageResVoMap.put(FmsMessageResVoType.CHANGE.getType(),new FmsMessageResVo(FmsMessageResVoType.CHANGE));
        fmsMessageResVoMap.put(FmsMessageResVoType.PICK.getType(),new FmsMessageResVo(FmsMessageResVoType.PICK));
        fmsMessageResVoMap.put(FmsMessageResVoType.PATROL.getType(),new FmsMessageResVo(FmsMessageResVoType.PATROL));
        fmsTaskService.appendTaskMessage(fmsMessageResVoMap);
        fmsWarnService.appendWarnMessage(fmsMessageResVoMap);
        wmsChangeapplyService.appendChangeMessage(fmsMessageResVoMap);
        return AjaxResult.success(new ArrayList<>(fmsMessageResVoMap.values()));
    }

    /**
     *  首页数据查询
     */
    @PreAuthorize("@ss.hasPermi('fms:console:console:data')")
    @GetMapping(value = "/console/data")
    public AjaxResult consoleData(ScreenDataReqVo reqVo) {
        Map<String, Object> resultMap = new HashMap<>();

        /* 获取天气信息 */
        getWeather(reqVo, resultMap);

        boolean b = dataAuthUtil.isValidate();
        if (b) {
            List<String> strings = dataAuthUtil.landListOfBlock();
            if (strings.size() == 0) {
                resultMap.put("landTotal", new ArrayList<>());
                Map<String, Object> countMap = new HashMap<>();
                countMap.put("count1", new ArrayList<>());
                countMap.put("count2", new ArrayList<>());
                countMap.put("count3", new ArrayList<>());
                resultMap.put("taskTypeCount", countMap);
                resultMap.put("fmsPlanStat", new ArrayList<>());
                return AjaxResult.success(resultMap);
            }
        }

        /* 获取基地统计信息 */
        getLandStat(reqVo, resultMap, b);

        /* 获取农事任务统计信息 */
        getTaskStat(reqVo, resultMap, b);

        /* 当前种植状态 */
        getPlanStat(reqVo, resultMap, b);

        return AjaxResult.success(resultMap);
    }


    /**
     *  大屏数据展示
     */
    @PreAuthorize("@ss.hasPermi('fms:console:screen:data')")
    @GetMapping(value = "/screen/data")
    public AjaxResult screenData(ScreenDataReqVo reqVo) {
        Map<String, Object> resultMap = new HashMap<>();
        FmsTaskPickListReqVo reqVo3 = new FmsTaskPickListReqVo();
        FmsTaskListReqVo reqVo4 = new FmsTaskListReqVo();

        /* 天气查询 */
        getWeather(reqVo, resultMap);

        boolean b = dataAuthUtil.isValidate();
        if (b) {
            //true需要进行权限校验。下拉框基地列表查询需要包含分配的基地以及分配地块所属基地
            List<String> strings = dataAuthUtil.landListOfBlock();
            if (strings.size() == 0) {
                return AjaxResult.success(resultMap);
            }
            List<String> strings2 = dataAuthUtil.blockList();
            reqVo3.setDataFilter(true);
            reqVo3.setBlockIds(strings2);
            reqVo4.setDataFilter(true);
            reqVo4.setBlockIds(strings2);
        }

        /* 获取基地统计信息 */
        getLandStat(reqVo, resultMap, b);

        /* 获取农事任务统计信息 */
        getTaskStat(reqVo, resultMap, b);

        /* 当前种植状态 */
        getPlanStat(reqVo, resultMap, b);

        /* 本年度采收统计 */

        reqVo3.setLandId(reqVo.getLandId());
        reqVo3.setBlockId(reqVo.getBlockId());
        reqVo3.setTaskStatus(TaskStatus.COMPLETED.getCode());
        List<FmsTaskPickStockListResVo> fmsTaskPickStockListResVos = fmsTaskpickService.selectFmsTaskPickStockListStat(reqVo3);
        resultMap.put("fmsTaskPickStockList", JSON.parseArray(JSON.toJSONString(fmsTaskPickStockListResVos)));
        BigDecimal taskPickWeightTotal = new BigDecimal("0");
        for (FmsTaskPickStockListResVo fmsTaskPickStockListResVo : fmsTaskPickStockListResVos) {
            taskPickWeightTotal = taskPickWeightTotal.add(fmsTaskPickStockListResVo.getPickWeight());
        }
        resultMap.put("taskPickWeightTotal", taskPickWeightTotal.toString());

        /* 近期农事任务 */

        reqVo4.setLandId(reqVo.getLandId());
        reqVo4.setBlockId(reqVo.getBlockId());
        List<FmsTaskResVo> fmsTaskResVos = fmsTaskService.selectTaskListScreenData(reqVo4);
        resultMap.put("taskList", JSON.parseArray(JSON.toJSONString(fmsTaskResVos)));

        return AjaxResult.success(resultMap);
    }

    /**
     *  大屏数据展示
     */
    @PreAuthorize("@ss.hasPermi('fms:console:screen:block:data')")
    @GetMapping(value = "/screen/block/data")
    public AjaxResult screenBlockData(ScreenDataReqVo reqVo) {
        FmsBlock fmsBlock = new FmsBlock();
        fmsBlock.setLandId(reqVo.getLandId());
        List<FmsBlock> blocks = fmsBlockService.selectFmsBlockList(fmsBlock);
        JSONArray jsonArray = new JSONArray();
        for (FmsBlock block : blocks) {
            //查询种植作物，作物图片
            String blockId = block.getBlockId();
            FmsPlanReqVo fmsPlanReqVo = new FmsPlanReqVo();
            fmsPlanReqVo.setBlockId(blockId);
            fmsPlanReqVo.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());
            List<FmsPlanResVo> fmsPlanResVos = fmsPlanService.selectPlanList(fmsPlanReqVo);
            JSONObject jsonObject = JSONObject.from(block);
            jsonObject.put("cropList", fmsPlanResVos);
            jsonArray.add(jsonObject);
        }
        return AjaxResult.success(jsonArray);
    }

    public void getWeather(ScreenDataReqVo reqVo, Map<String, Object> resultMap) {
        WeatherReqVo weatherReqVo;
        try {
            String param = ConfigUtils.ConfigKeyEnum.PROJECT_LOCATION_WEATHER_PARAM.valueOf();
            weatherReqVo = JSONObject.parseObject(param, WeatherReqVo.class);
        }catch (Exception e){
            throw new BizException(ErrorCode.WEATHER_PARAM_GET_ERROR);
        }
        FmsWeatherInfoResVo fmsWeatherInfoResVo = null;
        try {
            String result = WeatherUtil.getWeatherNearlySevenDays(weatherReqVo);
            JSONObject resultObj = JSONObject.parseObject(result).getJSONObject("data").getJSONObject("content");
            fmsWeatherInfoResVo = JSONObject.parseObject(resultObj.toString(), FmsWeatherInfoResVo.class);
            Map<String, Object> map = new HashMap<>();
            if (!StringUtils.isEmpty(fmsWeatherInfoResVo.getCityid())) {
                map = iFmsSolarService.getSysZoneByZoneCode(fmsWeatherInfoResVo.getCityid());
            }
            List<FmsWeatherInfoResVo> weatherList = new ArrayList<>();
            JSONArray data = resultObj.getJSONArray("data");
            if (data != null) {
                for (int i = 0; i < data.size(); i++) {
                    String str = data.getString(i);
                    FmsWeatherInfoResVo weatherResVo = JSONObject.parseObject(str, FmsWeatherInfoResVo.class);
                    weatherResVo.setCity(fmsWeatherInfoResVo.getCity());
                    weatherResVo.setZoneProvincezh(map.get("zoneProvincezh") == null ? "" : map.get("zoneProvincezh").toString());
                    weatherResVo.setZoneCapitalzh(map.get("zoneCapitalzh") == null ? "" : map.get("zoneCapitalzh").toString());
                    weatherList.add(weatherResVo);
                }
            }
            resultMap.put("weather", weatherList);
        }catch (Exception e){
            throw new BizException(ErrorCode.FMS_WEATHER_SEARCH_FAILED);
        }

    }

    public void getLandStat(ScreenDataReqVo reqVo, Map<String, Object> resultMap, boolean isValid) {
        /* 获取基地统计信息 */
        FmsLand fmsLand = new FmsLand();
        fmsLand.setLandId(reqVo.getLandId());

        if (isValid) {
            //true需要进行权限校验。下拉框基地列表查询需要包含分配的基地以及分配地块所属基地
            List<String> strings = dataAuthUtil.landListOfBlock();
            if (strings.isEmpty()) {
                FmsLandTotalResVo fmsLandTotalResVo = new FmsLandTotalResVo();
                fmsLandTotalResVo.setBlockUsageRate("0");
                fmsLandTotalResVo.setLandAreaSum("0");
                fmsLandTotalResVo.setCount("0");
                fmsLandTotalResVo.setBlockAreaSum("0");
                fmsLandTotalResVo.setPlanAreaSum("0");
                fmsLandTotalResVo.setLandBlockcountSum("0");
                fmsLandTotalResVo.setLandDevcountSum("0");
                String jsonString = JSONObject.toJSONString(fmsLandTotalResVo);
                resultMap.put("landTotal", JSONObject.parseObject(jsonString));
                return;
            }
            List<String> strings2 = dataAuthUtil.blockList();
            fmsLand.setDataFilter(true);
            fmsLand.setBlockIds(strings2);
        }

        FmsLandTotalResVo fmsLandTotalResVo = fmsLandService.selectFmsLandTotal(fmsLand);

        BigDecimal blockArea = fmsBlockService.selectSumAreaByLandId(fmsLand);
        fmsLandTotalResVo.setBlockAreaSum(blockArea == null ? "0" : blockArea.toString());
        FmsPlanReqVo fmsPlanReqVo = new FmsPlanReqVo();
        fmsPlanReqVo.setLandId(fmsLand.getLandId());
        fmsPlanReqVo.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());
        BigDecimal planArea = fmsPlanService.selectSumPlanArea(fmsPlanReqVo);
        fmsLandTotalResVo.setPlanAreaSum(planArea == null ? "0" : planArea.toString());
        int count = fmsPlanService.selectCountFmsPlan(fmsPlanReqVo);
        fmsLandTotalResVo.setPlanCropTypeNum(String.valueOf(count));

        if(null != planArea&&null != blockArea){
            BigDecimal divide = planArea.multiply(new BigDecimal(100)).divide(blockArea, 2, BigDecimal.ROUND_HALF_UP);
            fmsLandTotalResVo.setBlockUsageRate(divide.toString());
        }else {
            fmsLandTotalResVo.setBlockUsageRate("0");
        }
        String jsonString = JSONObject.toJSONString(fmsLandTotalResVo);
        resultMap.put("landTotal", JSONObject.parseObject(jsonString));
    }

    public void getTaskStat(ScreenDataReqVo reqVo, Map<String, Object> resultMap, boolean isValid) {
        Map<String, Object> countMap = new HashMap<>();
        FmsTaskListReqVo reqVo1 = new FmsTaskListReqVo();
        reqVo1.setLandId(reqVo.getLandId());
        reqVo1.setBlockId(reqVo.getBlockId());

        if (isValid) {
            List<String> strings = dataAuthUtil.blockList();
            if (strings.size() == 0) {
                countMap.put("count1", new JSONArray());
                countMap.put("count2", new JSONArray());
                countMap.put("count3", new JSONArray());
                resultMap.put("taskTypeCount", countMap);
                return;
            }
            reqVo1.setDataFilter(true);
            reqVo1.setBlockIds(strings);
        }


//        reqVo.setTaskAuditstatus(TaskStatus.COMPLETED.getCode());
//        reqVo.setTaskAudittype(CommonEnums.TASK_AUDIT_TYPE_DOWN.getCode() + "," + CommonEnums.TASK_AUDIT_TYPE_UP.getCode());
        reqVo1.setStartDate(LocalDateTime.now().with(WeekFields.of(Locale.FRANCE).dayOfWeek(), 1).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        reqVo1.setEndDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        List<FmsTaskTypeCountResVo> typeCounts1 = fmsTaskService.selectCountFmsTaskByType(reqVo1);
        reqVo1.setStartDate(LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        reqVo1.setEndDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        List<FmsTaskTypeCountResVo> typeCounts2 = fmsTaskService.selectCountFmsTaskByType(reqVo1);
        reqVo1.setStartDate(LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN).format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        reqVo1.setEndDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode())));
        List<FmsTaskTypeCountResVo> typeCounts3 = fmsTaskService.selectCountFmsTaskByType(reqVo1);

        String count1 = JSONObject.toJSONString(typeCounts1);
        String count2 = JSONObject.toJSONString(typeCounts2);
        String count3 = JSONObject.toJSONString(typeCounts3);
        countMap.put("count1", JSON.parseArray(count1));
        countMap.put("count2", JSON.parseArray(count2));
        countMap.put("count3", JSON.parseArray(count3));
        resultMap.put("taskTypeCount", countMap);
    }

    public void getPlanStat(ScreenDataReqVo reqVo, Map<String, Object> resultMap, boolean isValid) {
        FmsPlanReqVo reqVo2 = new FmsPlanReqVo();
        reqVo2.setLandId(reqVo.getLandId());
        reqVo2.setBlockId(reqVo.getBlockId());
        reqVo2.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());

        if (isValid) {
            List<String> strings = dataAuthUtil.blockList();
            reqVo2.setDataFilter(true);
            reqVo2.setBlockIds(strings);
        }

        List<FmsPlanResVo> fmsPlanResVos = fmsPlanService.selectPlanByCropNameAndType(reqVo2);
        BigDecimal total = new BigDecimal("0");
        for (FmsPlanResVo fmsPlanResVo : fmsPlanResVos) {
            total = total.add(fmsPlanResVo.getPlanArea());
        }
        JSONArray jsonArray = new JSONArray();
        for (FmsPlanResVo fmsPlanResVo : fmsPlanResVos) {
            BigDecimal divide = fmsPlanResVo.getPlanArea().multiply(new BigDecimal(100)).divide(total, 2, BigDecimal.ROUND_HALF_UP);
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(fmsPlanResVo));
            jsonObject.put("rate", divide);
            jsonArray.add(jsonObject);
        }

        resultMap.put("fmsPlanStat", jsonArray);
    }

}
