package com.jjt.emp.controller;

import com.jjt.biz.vo.EmpCalcEmpVO;
import com.jjt.biz.vo.EmpCalcTrendVO;
import com.jjt.common.annotation.Log;
import com.jjt.common.core.controller.BaseController;
import com.jjt.common.core.domain.AjaxResult;
import com.jjt.common.core.page.TableDataInfo;
import com.jjt.common.enums.BusinessType;
import com.jjt.common.utils.DateUtils;
import com.jjt.common.utils.poi.ExcelUtil;
import com.jjt.emp.domain.TwinEmpCalc;
import com.jjt.emp.service.ITwinEmpCalcService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 员工产量统计Controller
 *
 * @author wukai
 * @date 2025-01-18
 */
@Api(tags = "员工产量统计")
@RestController
@RequestMapping("/emp/empCalc")
public class TwinEmpCalcController extends BaseController {
    @Resource
    private ITwinEmpCalcService twinEmpCalcService;

    @GetMapping("/calc")
    @ResponseBody
    public AjaxResult calc(String date) {
        return toAjax(twinEmpCalcService.calc(DateUtils.parseDate(date)));
    }

    @GetMapping("/month/calc")
    @ResponseBody
    public AjaxResult monthCalc(String date) {
        List<TwinEmpCalc> list = twinEmpCalcService.selectTwinEmpCalcListByMonth(date);
        Map<String, Object> result = new HashMap<>();
        List<EmpCalcTrendVO> trend = list.stream()
                .collect(Collectors.groupingBy(TwinEmpCalc::getEmpDate))
                .entrySet().stream()
                .map(entry -> {
                            List<TwinEmpCalc> group = entry.getValue();
                            // 过滤出 A 组和 B 组的数据
                            List<TwinEmpCalc> groupA = group.stream().filter(d -> "A".equals(d.getEmpTeam())).collect(Collectors.toList());
                            List<TwinEmpCalc> groupB = group.stream().filter(d -> "B".equals(d.getEmpTeam())).collect(Collectors.toList());
                            BigDecimal totalPrice = calculateTotalPrice(group);
                            BigDecimal totalPriceA = calculateTotalPrice(groupA);
                            BigDecimal totalPriceB = calculateTotalPrice(groupB);

                            // 计算总生产米数
                            BigDecimal length = calculateLength(group);
                            BigDecimal lengthA = calculateLength(groupA);
                            BigDecimal lengthB = calculateLength(groupB);

                            // 计算平均稼动率
                            BigDecimal eff = calculateAverageEfficiency(group);
                            BigDecimal effA = calculateAverageEfficiency(groupA);
                            BigDecimal effB = calculateAverageEfficiency(groupB);

                            EmpCalcTrendVO vo = new EmpCalcTrendVO();
                            vo.setEmpDate(entry.getKey());
                            vo.setTotalPrice(totalPrice);
                            vo.setTotalPriceA(totalPriceA);
                            vo.setTotalPriceB(totalPriceB);

                            vo.setLength(length);
                            vo.setLengthA(lengthA);
                            vo.setLengthB(lengthB);

                            vo.setEfficiency(eff);
                            vo.setEfficiencyA(effA);
                            vo.setEfficiencyB(effB);
                            return vo;
                        }
                ).sorted(Comparator.comparing(EmpCalcTrendVO::getEmpDate)).collect(Collectors.toList());


        List<EmpCalcEmpVO> emp = list.stream()
                .collect(Collectors.groupingBy(TwinEmpCalc::getEmpName))
                .entrySet().stream()
                .map(entry -> {
                            List<TwinEmpCalc> group = entry.getValue();
                            BigDecimal totalPrice = calculateTotalPrice(group);
                            BigDecimal length = calculateLength(group);
                            BigDecimal eff = calculateAverageEfficiency(group);
                            EmpCalcEmpVO vo = new EmpCalcEmpVO();
                            vo.setEmpName(entry.getKey());
                            vo.setTotalPrice(totalPrice);
                            vo.setLength(length);
                            vo.setEfficiency(eff);
                            return vo;
                        }
                ).sorted(Comparator.comparing(EmpCalcEmpVO::getTotalPrice).reversed()).collect(Collectors.toList());

        result.put("trend", trend);
        result.put("emp", emp);
        return success(result);
    }

    /**
     * 辅助方法：计算总金额
     */
    private BigDecimal calculateTotalPrice(List<TwinEmpCalc> group) {
        return group.stream()
                .map(TwinEmpCalc::getTotalPrice).filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 辅助方法：计算总生产米数
     */
    private BigDecimal calculateLength(List<TwinEmpCalc> group) {
        return group.stream()
                .map(TwinEmpCalc::getLength)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 辅助方法：计算平均稼动率
     */
    private BigDecimal calculateAverageEfficiency(List<TwinEmpCalc> group) {
        if (group.size() == 0) {
            return BigDecimal.ZERO;
        }
        return group.stream()
                .map(TwinEmpCalc::getEfficiency)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal(group.size()), 4, RoundingMode.HALF_UP);
    }

    /**
     * 查询员工产量统计列表
     */
    @ApiOperation("查询员工产量统计列表")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:list')")
    @GetMapping("/list")
    public TableDataInfo list(TwinEmpCalc twinEmpCalc) {
        startPage();
        List<TwinEmpCalc> list = twinEmpCalcService.selectTwinEmpCalcList(twinEmpCalc);
        return getDataTable(list);
    }

    /**
     * 导出员工产量统计列表
     */
    @ApiOperation("导出员工产量统计列表")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:export')")
    @Log(title = "员工产量统计", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, TwinEmpCalc twinEmpCalc) {
        List<TwinEmpCalc> list = twinEmpCalcService.selectTwinEmpCalcList(twinEmpCalc);
        ExcelUtil<TwinEmpCalc> util = new ExcelUtil<TwinEmpCalc>(TwinEmpCalc.class);
        util.exportExcel(response, list, "员工产量统计数据");
    }

    /**
     * 获取员工产量统计详细信息
     */
    @ApiOperation("获取员工产量统计详细信息")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:query')")
    @GetMapping(value = "/{calcId}")
    public AjaxResult getInfo(@PathVariable("calcId") Long calcId) {
        return success(twinEmpCalcService.selectTwinEmpCalcByCalcId(calcId));
    }

    /**
     * 新增员工产量统计
     */
    @ApiOperation("新增员工产量统计")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:add')")
    @Log(title = "员工产量统计", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TwinEmpCalc twinEmpCalc) {
        return toAjax(twinEmpCalcService.insertTwinEmpCalc(twinEmpCalc));
    }

    /**
     * 修改员工产量统计
     */
    @ApiOperation("修改员工产量统计")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:edit')")
    @Log(title = "员工产量统计", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TwinEmpCalc twinEmpCalc) {
        return toAjax(twinEmpCalcService.updateTwinEmpCalc(twinEmpCalc));
    }

    /**
     * 删除员工产量统计
     */
    @ApiOperation("删除员工产量统计")
    //@PreAuthorize("@ss.hasPermi('emp:empCalc:remove')")
    @Log(title = "员工产量统计", businessType = BusinessType.DELETE)
    @DeleteMapping("/{calcIds}")
    public AjaxResult remove(@PathVariable Long[] calcIds) {
        return toAjax(twinEmpCalcService.deleteTwinEmpCalcByCalcIds(calcIds));
    }
}
