package com.ltgk.catches.controller;

import com.ltgk.catches.domain.dto.FishLimitSetAndYieldReq;
import com.ltgk.catches.domain.dto.GetFishEarlyReq;
import com.ltgk.catches.domain.dto.HandleEarlyReq;
import com.ltgk.catches.domain.entity.TcFishLimitSet;
import com.ltgk.catches.domain.entity.TcFishLogNetYield;
import com.ltgk.catches.domain.entity.TpAquaticDict;
import com.ltgk.catches.domain.vo.FishLimitEarlyVo;
import com.ltgk.catches.domain.vo.FishLimitSetAndYieldVO;
import com.ltgk.catches.service.ITpAquaticDictService;
import com.ltgk.catches.service.TcFishLimitEarlyService;
import com.ltgk.catches.service.TcFishLimitSetService;
import com.ltgk.catches.service.TcFishLogNetYieldService;
import com.ltgk.common.annotation.Log;
import com.ltgk.common.core.controller.BaseController;
import com.ltgk.common.core.domain.AjaxResult;
import com.ltgk.common.core.page.TableDataInfo;
import com.ltgk.common.enums.BusinessType;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 限额捕捞预警(tc_fish_limit_early)表控制层
 *
 * @author xxxxx
 */
@RestController
@RequestMapping("/fishingPort/fishLimitEarly")
public class TcFishLimitEarlyController extends BaseController {
    /**
     * 服务对象
     */
    @Resource
    private TcFishLimitEarlyService tcFishLimitEarlyService;
    @Resource
    private ITpAquaticDictService tpAquaticDictService;
    @Resource
    private TcFishLimitSetService tcFishLimitSetService;
    @Resource
    private TcFishLogNetYieldService tcFishLogNetYieldService;

    /**
     * 获取捕捞日志种类占比
     *
     * @return {@link List<FishLimitEarlyVo>}
     */
    @PreAuthorize("@ss.hasPermi('fishingPort:tcFishLimitEarly:list')")
    @Log(title = "获取限额捕捞预警列表", businessType = BusinessType.INSERT_OR_UPDATE)
    @ApiOperation(value = "获取限额捕捞预警列表")
    @PostMapping("/list")
    public TableDataInfo list(@Valid @RequestBody GetFishEarlyReq getFishEarlyReq) {
        return getDataTable(tcFishLimitEarlyService.list(getFishEarlyReq));
    }

    @PreAuthorize("@ss.hasPermi('fishingPort:tcFishLimitEarly:handleEarly')")
    @Log(title = "处理限额捕捞预警", businessType = BusinessType.INSERT_OR_UPDATE)
    @ApiOperation(value = "处理限额捕捞预警")
    @PostMapping("/handleEarly")
    public AjaxResult handleEarly(@Valid @RequestBody HandleEarlyReq handleEarlyReq) {
        return tcFishLimitEarlyService.handleEarly(handleEarlyReq);
    }

    /**
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2025/3/10
     */
    @PreAuthorize("@ss.hasPermi('fishingPort:tcFishLimitEarly:findFishLimitSetAndYield')")
    @ApiOperation(value = "限额比对分析 - 柱状图和条形图")
    @PostMapping("/findFishLimitSetAndYield")
    public AjaxResult findFishLimitSetAndYield(@RequestBody FishLimitSetAndYieldReq req) {
        // 所查询的年份
        Integer year = req.getYear();
        LocalDate yearStart = LocalDate.of(year, 1, 1);
        LocalDate yearEnd = LocalDate.of(year, 12, 31);

        // 查询所有的渔获种类
        Map<String, String> tpAquaticDictMap = tpAquaticDictService.list().stream()
                .collect(Collectors.toMap(TpAquaticDict::getId, TpAquaticDict::getDictName));

        // 查询 限额开始时间或者是限额结束时间在本年度的限额捕捞的 整体限额配置
        List<TcFishLimitSet> tcFishLimitSetList = tcFishLimitSetService
                .lambdaQuery()
                .ge(TcFishLimitSet::getStartDate, yearStart)
                .le(TcFishLimitSet::getStartDate, yearEnd)
                .or()
                .ge(TcFishLimitSet::getEndDate, yearStart)
                .le(TcFishLimitSet::getEndDate, yearEnd)
                .list();

        // 根据 渔获分类进行分组 ，主要是获取限额开始时间和限额结束时间   使用后边创建的数据，默认同一种类创建两个限额，默认第一个限额失效
        Map<String, TcFishLimitSet> tcFishLimitSetMap = tcFishLimitSetList.stream()
                .collect(Collectors.toMap(TcFishLimitSet::getAquaticDictId, Function.identity(), (v1, v2) -> v2));

        // 整体限额捕捞数量 使用后边创建的数据，默认同一种类创建两个限额，默认第一个限额失效
        Map<String, Double> tcFishLimitSetNumMap = tcFishLimitSetList.stream()
                .collect(Collectors.toMap(TcFishLimitSet::getAquaticDictId, TcFishLimitSet::getFishLimit, (v1, v2) -> v2));

        // 查询 捕捞日期在本年度的 捕捞数据
        List<TcFishLogNetYield> tcFishLogNetYieldList = tcFishLogNetYieldService
                .lambdaQuery()
                .between(TcFishLogNetYield::getDate, yearStart, yearEnd)
                .list();

        // 根据限额捕捞的时间进行筛选；如果限额捕捞里没有，则不显示
        List<TcFishLogNetYield> newTcFishLogNetYieldList = tcFishLogNetYieldList.stream()
                .filter(it ->
                        tcFishLimitSetMap.containsKey(it.getAquaticDictId())
                                && (tcFishLimitSetMap.get(it.getAquaticDictId()).getStartDate().before(it.getDate()) || tcFishLimitSetMap.get(it.getAquaticDictId()).getStartDate().equals(it.getDate()))
                                && (tcFishLimitSetMap.get(it.getAquaticDictId()).getEndDate().after(it.getDate()) || tcFishLimitSetMap.get(it.getAquaticDictId()).getEndDate().equals(it.getDate()))
                )
                .collect(Collectors.toList());

        // 已经捕捞的数量，单位是kg
        Map<String, BigDecimal> tcFishLogNetYieldMap = newTcFishLogNetYieldList.stream()
                .collect(Collectors.toMap(TcFishLogNetYield::getAquaticDictId, TcFishLogNetYield::getYield, BigDecimal::add));
        // 渔获种类列表
        List<String> aquaticDictNameList = new ArrayList<>();
        // 整体限额数量
        List<Double> tcFishLimitSetNumList = new ArrayList<>();
        // 已捕捞数量
        List<BigDecimal> tcFishLogYieldNumList = new ArrayList<>();

        tpAquaticDictMap.forEach((k, v) -> {
            aquaticDictNameList.add(v);
            tcFishLimitSetNumList.add(tcFishLimitSetNumMap.getOrDefault(k, 0.00));
            if (tcFishLogNetYieldMap.containsKey(k)) {
                // 单位为千克
                tcFishLogYieldNumList.add(tcFishLogNetYieldMap.get(k));
            } else {
                tcFishLogYieldNumList.add(new BigDecimal("0"));
            }
        });

        return success(new FishLimitSetAndYieldVO()
                .setAquaticDictNameList(aquaticDictNameList)
                .setTcFishLimitSetNumList(tcFishLimitSetNumList)
                .setTcFishLogYieldNumList(tcFishLogYieldNumList)
        );
    }
}
