package com.yunfeiyun.agmp.fms.controller;

import com.yunfeiyun.agmp.common.annotation.Log;
import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.core.controller.BaseController;
import com.yunfeiyun.agmp.common.core.domain.AjaxResult;
import com.yunfeiyun.agmp.common.core.page.TableDataInfo;
import com.yunfeiyun.agmp.common.enums.BusinessType;
import com.yunfeiyun.agmp.common.enums.CommonEnums;
import com.yunfeiyun.agmp.common.enums.DictTypeEnums;
import com.yunfeiyun.agmp.common.framework.manager.RedisCacheManager;
import com.yunfeiyun.agmp.common.utils.DictUtils;
import com.yunfeiyun.agmp.common.utils.SecurityUtils;
import com.yunfeiyun.agmp.common.utils.StringUtils;
import com.yunfeiyun.agmp.common.utils.poi.ExcelUtil;
import com.yunfeiyun.agmp.common.utils.serialno.NoGenerator;
import com.yunfeiyun.agmp.fms.domain.*;
import com.yunfeiyun.agmp.fms.domain.reqvo.EndFmsPlanReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsBlockReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsPlanReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.FmsTaskListReqVo;
import com.yunfeiyun.agmp.fms.domain.resvo.*;
import com.yunfeiyun.agmp.fms.service.*;
import com.yunfeiyun.agmp.fms.util.DataAuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 种植计划Controller
 * 
 * @author 杨晓辉
 * @date 2023-05-18
 */
@Slf4j
@RestController
@RequestMapping("/fms/plan")
public class FmsPlanController extends BaseController
{
    @Autowired
    private IFmsPlanService fmsPlanService;
    @Autowired
    private IFmsLandService fmsLandService;
    @Autowired
    private IFmsBlockService fmsBlockService;
    @Autowired
    private IFmsPeriodService fmsPeriodService;
    @Autowired
    private IFmsTaskService fmsTaskService;
    @Autowired
    private IFmsTaskpickService fmsTaskpickService;
    @Autowired
    private IFmsTaskassetService fmsTaskassetService;
    @Autowired
    private IFmsTaskmachineService fmsTaskmachineService;
    @Autowired
    RedisCacheManager RedisCacheManager;
    @Resource
    NoGenerator noGenerator;
    @Autowired
    private IFmsCropService fmsCropService;
    @Autowired
    private DataAuthUtil dataAuthUtil;


    /**
     * 查询种植计划列表
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:list')")
    @GetMapping("/list")
    public TableDataInfo list(FmsPlan fmsPlan)
    {
        startPage();
        List<FmsPlan> list = fmsPlanService.selectFmsPlanList(fmsPlan);
        return getDataTable(list);
    }

    /**
     * 查询种植计划列表
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:show:list')")
    @GetMapping("/show/list")
    public TableDataInfo selectPlanList(FmsPlanReqVo reqVo)
    {
        reqVo.setDataFilter(dataAuthUtil.isValidate());
        reqVo.setBlockIds(dataAuthUtil.blockList());
        startPage();
        List<FmsPlanResVo> list = fmsPlanService.selectPlanList(reqVo);
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('fms:plan:show:select:list')")
    @GetMapping("/show/select/list")
    public TableDataInfo showSelectList(FmsPlanReqVo reqVo)
    {
        List<FmsPlanResVo> list = fmsPlanService.selectPlanList(reqVo);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (FmsPlanResVo resVo : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("landId", resVo.getLandId());
            map.put("landName", resVo.getLandName());
            map.put("blockId", resVo.getBlockId());
            map.put("blockName", resVo.getBlockName());
            map.put("planId", resVo.getPlanId());
            map.put("planNo", resVo.getPlanNo());
            map.put("cropId", resVo.getCropId());
            map.put("cropType", resVo.getCropType());
            map.put("cropName", resVo.getCropName());
            map.put("planArea", resVo.getPlanArea());
            resultList.add(map);
        }
        return getDataTable(resultList);
    }

    /**
     * 种植情况地图总览页面，查询
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:map:info')")
    @GetMapping("/map/info")
    public AjaxResult selectInfoInMap(FmsPlanReqVo reqVo)
    {
        FmsLand fmsLand = new FmsLand();
        fmsLand.setLandId(reqVo.getLandId());
        FmsBlockReqVo blockAreaReqVo = new FmsBlockReqVo();
        blockAreaReqVo.setLandId(reqVo.getLandId());
        FmsPlanReqVo fmsPlanReqVo = new FmsPlanReqVo();

        boolean b = dataAuthUtil.isValidate();
        if (b) {
            //true需要进行权限校验。基地列表需要分配的基地才能查询
            List<String> strings = dataAuthUtil.landListOfBlock();
            if (strings.size() == 0) {
                SelectInfoInMapResVo resVo = new SelectInfoInMapResVo();
                resVo.setCount("0");
                resVo.setLandAreaSum("0");
                resVo.setLandBlockcountSum("0");
                resVo.setBlockAreaSum("0");
                resVo.setPlanAreaSum("0");
                resVo.setCropList(new ArrayList());
                resVo.setBlockList(new ArrayList());
                return success(resVo);
            }
            fmsLand.setDataFilter(true);
            fmsLand.setLandIds(strings);

            List<String> strings2 = dataAuthUtil.blockList();
            blockAreaReqVo.setDataFilter(true);
            blockAreaReqVo.setBlockIds(strings2);
            fmsPlanReqVo.setDataFilter(true);
            fmsPlanReqVo.setBlockIds(strings2);
            fmsPlanReqVo.setLandIds(strings);
        }

        FmsLandTotalResVo fmsLandTotalResVo = fmsLandService.selectFmsLandTotal(fmsLand);

        //查询地块总面积
        BigDecimal blockArea = fmsBlockService.selectSumArea(blockAreaReqVo);

        //查询种植总面积

        fmsPlanReqVo.setLandId(reqVo.getLandId());
        fmsPlanReqVo.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode() + "," + CommonEnums.PLAN_STATUS_NOT_START.getCode());
        BigDecimal planArea = fmsPlanService.selectSumPlanArea(fmsPlanReqVo);

        //查询种养品种
        List<FmsPlanResVo> fmsPlanResVos = fmsPlanService.selectPlanByCropName(fmsPlanReqVo);
        for (FmsPlanResVo fmsPlanResVo : fmsPlanResVos) {
            String cropName = fmsPlanResVo.getCropName();
            FmsCrop fmsCrop = new FmsCrop();
            fmsCrop.setCropName(cropName);
            List<FmsCropResVo> list = fmsCropService.selectFmsCropList(fmsCrop);
            for (FmsCropResVo resVo : list) {
                if (!StringUtils.isEmpty(resVo.getResIds()) && !StringUtils.isEmpty(resVo.getCropPreview())) {
                    fmsPlanResVo.setResIds(resVo.getResIds());
                    fmsPlanResVo.setCropPreview(resVo.getCropPreview());
                    break;
                }
            }
        }

        //查询地块列表
        List<FmsBlockResVo> fmsBlockResVos = fmsBlockService.selectFmsBlockHasPlan(blockAreaReqVo);

        SelectInfoInMapResVo resVo = new SelectInfoInMapResVo();
        resVo.setCount(fmsLandTotalResVo.getCount());
        resVo.setLandAreaSum(fmsLandTotalResVo.getLandAreaSum());
        resVo.setLandBlockcountSum(fmsLandTotalResVo.getLandBlockcountSum());
        resVo.setBlockAreaSum(blockArea == null ? "0" : String.valueOf(blockArea));
        resVo.setPlanAreaSum(planArea == null ? "0" : String.valueOf(planArea));
        resVo.setCropList(fmsPlanResVos);
        resVo.setBlockList(fmsBlockResVos);
        return success(resVo);
//        return success(JSON.parse(JSON.toJSONString(resVo)));
    }

    /**
     * App端首页查询种植规划列表
     * @param landId 基地标识
     * @return
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:task:status:list')")
    @GetMapping("/task/status/list")
    public TableDataInfo planListOfTaskStatus(@RequestParam(value = "landId") String landId){
        startPage();
        Map<String, Object> param = new HashMap<>();
        param.put("landId", landId);
        param.put("userId", SecurityUtils.getUserId());
        List<FmsPlanListOfTaskStatusResVo> fmsPlanListOfTaskStatusResVos = fmsPlanService.selectPlanListOfTaskStatus(param);
        return getDataTable(fmsPlanListOfTaskStatusResVos);
    }

    /**
     * 导出种植计划列表
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:export')")
    @Log(title = "种植计划", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, FmsPlan fmsPlan)
    {
        List<FmsPlan> list = fmsPlanService.selectFmsPlanList(fmsPlan);
        ExcelUtil<FmsPlan> util = new ExcelUtil<FmsPlan>(FmsPlan.class);
        util.exportExcel(response, list, "种植计划数据");
    }

    /**
     * 获取种植计划详细信息
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:info')")
    @GetMapping(value = "/info")
    public AjaxResult getInfo(@RequestParam("planId") String planId)
    {
        return success(fmsPlanService.selectFmsPlanByPlanId(planId));
    }

    /**
     * 获取种植计划详细信息
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:record:info')")
    @GetMapping(value = "/record/info")
    public AjaxResult getRecordInfo(@RequestParam("planId") String planId)
    {
        /* 头部详情 */
        FmsPlanResVo resVo = fmsPlanService.selectFmsPlanRecordByPlanId(planId);
        /* 采收记录 */
        List<FmsTaskPickListResVo> fmsTaskPickListResVos = fmsTaskpickService.selectFmsTaskpickByPlanId(planId);
        /* 农事记录 */
        List<FmsTaskResVo> list = fmsTaskService.getInfoByPlanId(planId);
        for (FmsTaskResVo fmsTaskResVo : list) {
            String taskrcdId = fmsTaskResVo.getTaskrcdId();
            /* 涉及农资查询 */
            List<FmsTaskAssetUsageResVo> resVos = fmsTaskassetService.selectFmsTaskAssetByRcdId(taskrcdId);
            StringBuffer goodInfoSb = new StringBuffer("");
            for (FmsTaskAssetUsageResVo vo : resVos) {
                goodInfoSb.append(StringUtils.parsStr(vo.getGoodsName()));
                goodInfoSb.append("(");
                goodInfoSb.append(StringUtils.parsStr(vo.getTaskassetUsedcount()));
                goodInfoSb.append(DictUtils.getDictLabel(DictTypeEnums.WMS_GOODS_UNIT.getCode(), vo.getGoodsUnit()));
                goodInfoSb.append(" ");
                goodInfoSb.append(StringUtils.parsStr(vo.getGoodsSpec()));
                goodInfoSb.append(")");
                goodInfoSb.append("、");
            }
            if(goodInfoSb.length() > 0){
                goodInfoSb.deleteCharAt(goodInfoSb.length() - 1);
            }
            fmsTaskResVo.setGoodInfoContent(goodInfoSb.toString());

            /* 涉及农具查询 */
            List<FmsTaskmachineResVo> machs = fmsTaskmachineService.selectFmsTaskmachineByRcdId(taskrcdId);
            StringBuffer machInfoSb = new StringBuffer("");
            for (FmsTaskmachineResVo mach : machs) {
                machInfoSb.append(StringUtils.parsStr(mach.getMachName()));
                machInfoSb.append("(");
                machInfoSb.append(StringUtils.parsStr(mach.getTaskmachUsedcount()));
                machInfoSb.append("小时");
                machInfoSb.append(" ");
                machInfoSb.append(StringUtils.parsStr(mach.getMachSpec()));
                machInfoSb.append(")");
                machInfoSb.append("、");
            }
            if(machInfoSb.length() > 0){
                machInfoSb.deleteCharAt(machInfoSb.length() - 1);
            }
            fmsTaskResVo.setMachInfoContent(machInfoSb.toString());
        }

        /*  农资记录 */
        FmsTaskListReqVo reqVo = new FmsTaskListReqVo();
        reqVo.setPlanId(planId);
        List<FmsTaskAssetUsageResVo> fmsTaskAssetUsageResVos = fmsTaskassetService.selectFmsTaskAssetStat(reqVo);

        /*  农具记录 */
        List<FmsTaskmachineResVo> fmsTaskmachineResVos = fmsTaskmachineService.selectFmsTaskmachineStat(reqVo);

        Map resultMap = new HashMap<String, Object>();
        resultMap.put("info", resVo);
        resultMap.put("fmsTaskPickList", fmsTaskPickListResVos);
        resultMap.put("fmsTaskList", list);
        resultMap.put("fmsTaskassetList", fmsTaskAssetUsageResVos);
        resultMap.put("fmsTaskmachineList", fmsTaskmachineResVos);

        return success(resultMap);
    }

    /**
     * 新增种植计划
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:add')")
    @Log(title = "种植计划", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@Valid @RequestBody FmsPlan fmsPlan)
    {
        fmsPlan.setPlanNo(noGenerator.getPlanNo());
        //根据日期判断状态与生长周期
        String planPlanstartdate = fmsPlan.getPlanPlanstartdate();
        try {
            LocalDateTime startDate = LocalDateTime.parse(planPlanstartdate, DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode()));
            LocalDateTime nowDate = LocalDateTime.now();

            if (!startDate.isAfter(nowDate)) {
                //种植中
                fmsPlan.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());

                long days = nowDate.toLocalDate().toEpochDay() - startDate.toLocalDate().toEpochDay();

                List<FmsPeriod> fmsPeriods = fmsPeriodService.selectFmsPeriodByCropId(fmsPlan.getCropId());
                int periodDays = 0;
                for (FmsPeriod fmsPeriod : fmsPeriods) {
                    periodDays += fmsPeriod.getPeriodDays();
                    if (periodDays >= days) {
                        fmsPlan.setPlanPeriodname(fmsPeriod.getPeriodName());
                        break;
                    }
                }
                if (periodDays < days&& !fmsPeriods.isEmpty()) {
                    fmsPlan.setPlanPeriodname(fmsPeriods.get(fmsPeriods.size()-1).getPeriodName());
                }

            }
            if (startDate.isAfter(nowDate)) {
                //未开始
                fmsPlan.setPlanStatus(CommonEnums.PLAN_STATUS_NOT_START.getCode());
                fmsPlan.setPlanPeriodname(null);
            }
            /* 更新地块的种植面积 */
            FmsBlock fmsBlock = fmsBlockService.selectFmsBlockByBlockId(fmsPlan.getBlockId());
            if (fmsBlock == null) {
                return AjaxResult.error(ErrorCode.INVALID_PARAMETER.getCode(), ErrorCode.INVALID_PARAMETER.getMessage());
            }

            AjaxResult ajaxResult = setBlockAreaplant(fmsBlock, fmsPlan.getPlanArea());
            if (!ErrorCode.SUCCESS.getCode().equals(ajaxResult.get(AjaxResult.CODE_TAG))) {
                return ajaxResult;
            }

            return toAjax(fmsPlanService.insertFmsPlan(fmsPlan, fmsBlock));

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 修改种植计划
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:edit')")
    @Log(title = "种植计划", businessType = BusinessType.UPDATE)
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody FmsPlan fmsPlan)
    {
        FmsPlanResVo resVo = fmsPlanService.selectFmsPlanByPlanId(fmsPlan.getPlanId());
        String planPlanstartdateOld = resVo.getPlanPlanstartdate();

        //根据日期判断状态与生长周期
        String planPlanstartdate = fmsPlan.getPlanPlanstartdate();

        if (!planPlanstartdateOld.equals(planPlanstartdate)) {
            try {
                LocalDateTime startDate = LocalDateTime.parse(planPlanstartdate, DateTimeFormatter.ofPattern(CommonEnums.PATTERN_DATETIME.getCode()));
                LocalDateTime nowDate = LocalDateTime.now();

                if (!startDate.isAfter(nowDate)) {
                    //种植中
                    fmsPlan.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode());
                    long days = nowDate.toLocalDate().toEpochDay() - startDate.toLocalDate().toEpochDay();
                    List<FmsPeriod> fmsPeriods = fmsPeriodService.selectFmsPeriodByCropId(fmsPlan.getCropId());
                    if (!fmsPeriods.isEmpty()) {
                        int periodDays = 0;
                        for (FmsPeriod fmsPeriod : fmsPeriods) {
                            periodDays += fmsPeriod.getPeriodDays();
                            if (periodDays >= days) {
                                fmsPlan.setPlanPeriodname(fmsPeriod.getPeriodName());
                                break;
                            }
                        }
                        if (periodDays < days) {
                            fmsPlan.setPlanPeriodname(fmsPeriods.get(fmsPeriods.size()-1).getPeriodName());
                        }
                    }
                }
                if (startDate.isAfter(nowDate)) {
                    //未开始
                    fmsPlan.setPlanStatus(CommonEnums.PLAN_STATUS_NOT_START.getCode());
                    fmsPlan.setPlanPeriodname(null);
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        /* 如果面积发生修改，更新地块种植面积 */
        if (!resVo.getPlanArea().equals(fmsPlan.getPlanArea())) {
            /* 更新地块的种植面积 */
            FmsBlock fmsBlock = fmsBlockService.selectFmsBlockByBlockId(fmsPlan.getBlockId());
            if (fmsBlock == null) {
                return AjaxResult.error(ErrorCode.INVALID_PARAMETER.getCode(), ErrorCode.INVALID_PARAMETER.getMessage());
            }
            AjaxResult ajaxResult = setBlockAreaplant(fmsBlock, fmsPlan.getPlanArea().subtract(resVo.getPlanArea()));
            if (!ErrorCode.SUCCESS.getCode().equals(ajaxResult.get(AjaxResult.CODE_TAG))) {
                return ajaxResult;
            }
            fmsPlanService.updateFmsPlan(fmsPlan, fmsBlock);
            return success();

        }
        fmsPlanService.updateFmsPlan(fmsPlan);
        return success();
    }

    /**
     * 结束
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:end')")
    @Log(title = "结束", businessType = BusinessType.UPDATE)
    @PutMapping(value = "/end")
    public AjaxResult end(@Valid @RequestBody EndFmsPlanReqVo reqVo)
    {
        FmsPlanResVo resVo = fmsPlanService.selectFmsPlanByPlanId(reqVo.getPlanId());
        FmsPlan fmsPlan = new FmsPlan();
        BeanUtils.copyProperties(resVo, fmsPlan);
        fmsPlan.setPlanEnddate(reqVo.getEndDate());
        fmsPlan.setPlanStatus(CommonEnums.PLAN_STATUS_END.getCode());
        fmsPlan.setPlanPeriodname("");

        /* 结束时更新地块种植面积 */
        FmsBlock fmsBlock = fmsBlockService.selectFmsBlockByBlockId(fmsPlan.getBlockId());
        if (fmsBlock == null) {
            return AjaxResult.error(ErrorCode.INVALID_PARAMETER.getCode(), ErrorCode.INVALID_PARAMETER.getMessage());
        }
        setBlockAreaplant(fmsBlock, resVo.getPlanArea().negate());
        fmsPlanService.updateFmsPlan(fmsPlan, fmsBlock);
        return success();
    }



    /**
     * 删除种植计划
     */
    @PreAuthorize("@ss.hasPermi('fms:plan:delete')")
    @Log(title = "种植计划", businessType = BusinessType.DELETE)
	@DeleteMapping("/delete")
    public AjaxResult remove(@RequestParam("planIds") String[] planIds)
    {
        for (int i = 0; i < planIds.length; i++) {
            int count = fmsTaskService.selectCountFmsTaskByPlanId(planIds[i]);
            if (count > 0) {
                return AjaxResult.error(ErrorCode.DEL_CURNODE_ERROR.getCode(), ErrorCode.DEL_CURNODE_ERROR.getMessage());
            }
        }
        return toAjax(fmsPlanService.deleteFmsPlanByPlanIds(planIds));
    }

    public AjaxResult setBlockAreaplant (FmsBlock fmsBlock, BigDecimal addArea) {
        FmsPlanReqVo fmsPlanReqVo = new FmsPlanReqVo();
        fmsPlanReqVo.setBlockId(fmsBlock.getBlockId());
        fmsPlanReqVo.setPlanStatus(CommonEnums.PLAN_STATUS_START.getCode() + "," + CommonEnums.PLAN_STATUS_NOT_START.getCode());
        BigDecimal sumArea = fmsPlanService.selectSumPlanArea(fmsPlanReqVo);
        if (sumArea == null) {
            sumArea = new BigDecimal("0");
        }
        if (addArea != null) {
            sumArea = sumArea.add(addArea);
        }
        if (sumArea.compareTo(fmsBlock.getBlockArea()) > 0) {
            return AjaxResult.error(ErrorCode.INVALID_PARAMETER.getCode(), ErrorCode.INVALID_PARAMETER_PLAN_AREA.getMessage());
        }

        fmsBlock.setBlockAreaplant(sumArea);
        return success();
    }
}
