package cn.ezhizao.project.business.controller;

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

import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
import cn.ezhizao.project.business.domain.*;
import cn.ezhizao.project.business.service.IBizDayworkService;
import cn.ezhizao.project.business.service.IBizOutsourcedOrderDetailService;
import cn.ezhizao.project.business.service.IBizProductionPlanDetailSubDetailService;
import cn.ezhizao.project.business.service.IBizTaksStockLotService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * 盘点批次信息Controller
 *
 * @author ezhizao
 * @date 2024-08-15
 */
@RestController
@RequestMapping("/business/taksStockLot")
public class BizTaksStockLotController extends BaseController {
    @Resource
    private IBizTaksStockLotService bizTaksStockLotService;
    @Resource
    private IBizOutsourcedOrderDetailService bizOutsourcedOrderDetailService;
    @Resource
    private IBizProductionPlanDetailSubDetailService bizProductionPlanDetailSubDetailService;
    @Resource
    private IBizDayworkService bizDayworkService;

    /**
     * 查询盘点批次信息列表
     */
    @GetMapping("/list")
    public TableDataInfo list(BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        startPage();
        List<BizTaksStockLot> list = bizTaksStockLotService.getList(bizTaksStockLot);
        return getDataTable(list);
    }

    /**
     * 导出盘点批次信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:taksStockLot:export')")
    @Log(title = "盘点批次信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizTaksStockLot);
        List<BizTaksStockLot> list = bizTaksStockLotService.getList(bizTaksStockLot);
        list.forEach(l -> {
            //标识
            List<String> flags = new ArrayList<>();
            if (l.getIsWaste() == 1) {
                flags.add("批废");
            }
            if (l.getIsAmend() == 1) {
                flags.add("工艺修改");

            }
            if (l.getIsWasteRecycling() == 1L) {
                flags.add("废品回用");
            }
            if (l.getIsSuperaddition() == 1) {
                flags.add("追增");
            }
            l.setFlag(String.join(",", flags));
            //盘点状态
            if(l.getStatus() == 0) {
                l.setTaksStatus("未盘点");
            }else{
                l.setTaksStatus("已盘点");
            }
        });
        ExcelUtil<BizTaksStockLot> util = new ExcelUtil<BizTaksStockLot>(BizTaksStockLot.class);
        util.exportExcel(response, list, "盘点批次信息数据");
    }

    @PreAuthorize("@ss.hasPermi('business:taksStockLot:edit')")
    @Log(title = "盘点批次信息导出", businessType = BusinessType.EXPORT)
    @PostMapping("/exportDetails")
    public void exportDetails(HttpServletResponse response, BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        // 获取未盘点的批次信息
    }

    /**
     * 获取盘点批次信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:taksStockLot:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(bizTaksStockLotService.getById(id));
    }

    /**
     * 新增盘点批次信息
     */
    @Log(title = "盘点批次信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        return toAjax(bizTaksStockLotService.save(bizTaksStockLot));
    }

    //一键盘点未开始批次
    @PostMapping("/updateNoStartLot")
    public AjaxResult updateNoStartLot(@RequestBody BizTaksStockLot bizTaksStockLot) {
        List<BizTaksStockLot> list = bizTaksStockLotService.query()
                .eq("take_stock_period_id", bizTaksStockLot.getTakeStockPeriodId())
                .eq("daywork_id", 0)
                .eq("is_taks_stock", 0)
                .eq("dept_id", bizTaksStockLot.getDeptId()).list();
        list.forEach(item -> {
            item.setTaksStockNum(item.getProdNum());
            item.setIsTaksStock(1);
        });
        bizTaksStockLotService.updateBatchById(list);
        return success();
    }

    @Log(title = "盘点导出", businessType = BusinessType.EXPORT)
    @PostMapping("/download")
    public void download(HttpServletResponse response, BizTakeStockPeriod bizTakeStockPeriod) throws NoSuchFieldException, IllegalAccessException {
        List<BizTaksStockLot> list = bizTaksStockLotService.getInfo(bizTakeStockPeriod);
        //根据产品分组
        Map<String, List<BizTaksStockLot>> groupedByProduct = new TreeMap<>();
        for (BizTaksStockLot obj : list) {
            String key = obj.getProductCode();
            if (!groupedByProduct.containsKey(key)) {
                groupedByProduct.put(key, new ArrayList<>());
            }
            groupedByProduct.get(key).add(obj);
        }
        List<BizTaksStockLotDownLoad> newList = new ArrayList<>();
        for (Map.Entry<String, List<BizTaksStockLot>> entry : groupedByProduct.entrySet()) {
            BizTaksStockLotDownLoad item = new BizTaksStockLotDownLoad();
            List<BizTaksStockLot> values = entry.getValue();
            int productNum = 0;
            productNum = values.stream().mapToInt(BizTaksStockLot::getTaksStockNum).sum();
            item.setProductCode(entry.getKey());
            item.setStockYear(values.get(0).getStockYear());
            item.setStockMonth(values.get(0).getStockMonth());
            item.setProductDescription(values.get(0).getProductDescription());
            item.setProductNum(productNum);
            newList.add(item);
        }
        ExcelUtil<BizTaksStockLotDownLoad> util = new ExcelUtil<>(BizTaksStockLotDownLoad.class);
        util.exportExcel(response, newList, "盘点数据");
    }

    /**
     * 修改盘点批次信息
     */
    @Log(title = "盘点批次信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizTaksStockLot);
        boolean result = bizTaksStockLotService.updateById(bizTaksStockLot);
        return result ? success(bizTaksStockLot) : error("未保存成功");
    }
    @PostMapping("/getLotNumber")
    public AjaxResult getLotNumber(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        //子计划投产数
       int lotTotalNumber = bizProductionPlanDetailSubDetailService.query().eq("production_plan_detail_id", bizTaksStockLot.getProductionPlanDetailId()).list()
                .stream().mapToInt(BizProductionPlanDetailSubDetail::getLotNumber)
                .sum();
       bizTaksStockLot.setLotTotalNumber(lotTotalNumber);
       //已生成的正常批数
        long normalLotNumber = bizTaksStockLotService.query().eq("production_plan_detail_id", bizTaksStockLot.getProductionPlanDetailId())
                .eq("is_waste_recycling", 0)
                .eq("from_lot_id", 0)
                .eq("is_superaddition", 0)
                .ne("daywork_id",0)
                .eq("take_stock_period_id",bizTaksStockLot.getTakeStockPeriodId())
                .list().stream().count();
        bizTaksStockLot.setNormalLotNumber(normalLotNumber);
        //已盘点未生产的批次数
        long notProductionLotNumber = bizTaksStockLotService.query().eq("production_plan_detail_id", bizTaksStockLot.getProductionPlanDetailId())
                .eq("daywork_id", 0)
                .eq("is_taks_stock", 1)
                .eq("take_stock_period_id",bizTaksStockLot.getTakeStockPeriodId())
                .list().stream().count();
        bizTaksStockLot.setNotProductionLotNumber(notProductionLotNumber);
        long allowLotNum = (lotTotalNumber - normalLotNumber -notProductionLotNumber)>0? (lotTotalNumber - normalLotNumber -notProductionLotNumber) : 0 ;
        bizTaksStockLot.setAllowLotNum(allowLotNum);
        return success(bizTaksStockLot);
    }
    //一键盘点
    @PutMapping("/multiplyInventoryCheck")
    public AjaxResult multiplyInventoryCheck(@RequestBody List<BizTaksStockLot> bizTaksStockLotList) throws NoSuchFieldException, IllegalAccessException {
        bizTaksStockLotList.forEach(item ->{
            item.setTaksStockNum(item.getProdNum());
            item.setIsTaksStock(1);
        });
        bizTaksStockLotService.updateBatchById(bizTaksStockLotList);
        //判断如果一键盘点后，该计划单下没有未生产的未盘点批次，则返回前端一个值
        List<BizTaksStockLot> list = bizTaksStockLotService.query().eq("production_plan_detail_id", bizTaksStockLotList.get(0).getProductionPlanDetailId())
                .eq("is_taks_stock", 0)
                .eq("take_stock_period_id", bizTaksStockLotList.get(0).getTakeStockPeriodId())
                .eq("daywork_id", 0)
                .list();
        return success(list.isEmpty()? false:true);
        }
    @PutMapping("/singleInventoryCheck")
    public AjaxResult singleInventoryCheck(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizTaksStockLot);
        bizTaksStockLotService.updateById(bizTaksStockLot);
        //判断如果一键盘点后，该计划单下没有未生产的未盘点批次，则返回前端一个值
        List<BizTaksStockLot> list = bizTaksStockLotService.query().eq("production_plan_detail_id", bizTaksStockLot.getProductionPlanDetailId())
                .eq("is_taks_stock", 0)
                .eq("take_stock_period_id", bizTaksStockLot.getTakeStockPeriodId())
                .eq("daywork_id", 0)
                .list();
        return success(list.isEmpty()? false:true);
    }

    @PostMapping("/getProductionPlanDetail")
    public AjaxResult getProductionPlanDetail(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException {
        List<BizTaksStockLot> productionPlanDetailList = bizTaksStockLotService.getProductionPlanDetailList(bizTaksStockLot);
        return success(productionPlanDetailList);
    }

    @PostMapping("/getNotTaksLot")
    public AjaxResult getNotTaksLot(@RequestBody BizTaksStockLot bizTaksStockLot) throws NoSuchFieldException, IllegalAccessException{
        List<BizTaksStockLot> list = bizTaksStockLotService.getNotTaksLot(bizTaksStockLot);
        return success(list);
    }



    /**
     * 删除盘点批次信息
     */
    @PreAuthorize("@ss.hasPermi('business:taksStockLot:remove')")
    @Log(title = "盘点批次信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids)
    {
        return toAjax(bizTaksStockLotService.removeBatchByIds(ids));
    }

    @Log(title = "盘点批次信息", businessType = BusinessType.DELETE)
    @PostMapping("/getLotsByOutsourceFormNo")
    public AjaxResult getLotsByOutsourceFormNo(@RequestBody BizTaksStockLot bizTaksStockLot)
    {
        // 查询所有该外协单的批次
        List<BizOutsourcedOrderDetail> details = bizOutsourcedOrderDetailService.query().eq("form_code", bizTaksStockLot.getOutsourceFormNo()).list();
        BizTaksStockLot conditions = new BizTaksStockLot();
        conditions.setLotIds(details.isEmpty() ? Collections.singletonList(0L) : details.stream().map(BizOutsourcedOrderDetail::getLotId).collect(Collectors.toList()));
        conditions.setTakeStockPeriodId(bizTaksStockLot.getTakeStockPeriodId());
        // 根据外协单批次查询盘点信息
        List<BizTaksStockLot> lots = bizTaksStockLotService.getList(conditions);
//        Map<String, Object> map = new HashMap<>();
        // 在外协的批次
        List<BizTaksStockLot> outsourcedPart = lots.stream().filter(v -> v.getDeptCode().equals("170000")).collect(Collectors.toList());
        // 在外协且未盘点的批次
//        List<BizTaksStockLot> outsourcedPartUnFinished = outsourcedPart.stream().filter(v -> v.getIsTaksStock().equals(0)).collect(Collectors.toList());
        // 在外协且已盘点的批次
//        List<BizTaksStockLot> outsourcedPartFinished = outsourcedPart.stream().filter(v -> v.getIsTaksStock().equals(1)).collect(Collectors.toList());
        // 不在外协的批次

        List<BizTaksStockLot> notOutsourcedPart = lots.stream().filter(v -> !v.getDeptCode().equals("170000")).collect(Collectors.toList());
//        map.put("list", outsourcedPart);
//        map.put("msg", outsourcedPartUnFinished.isEmpty() ? null : "")
        return outsourcedPart.isEmpty() ? error("该发出单中没有需要外协盘点的批次") : success(outsourcedPart);
    }

    @Log(title = "批量外协批次盘点", businessType = BusinessType.UPDATE)
    @PostMapping("/batchTaksStockLot")
    @Transactional
    public AjaxResult batchTaksStockLot(@RequestBody List<BizTaksStockLot> lots) throws NoSuchFieldException, IllegalAccessException {
        List<BizTaksStockLot> oldLots = bizTaksStockLotService.query().in("id", lots.stream().map(BizTaksStockLot::getId).collect(Collectors.toList())).list();
        List<BizTaksStockLot> changeLots = oldLots.stream().filter(v -> v.getIsTaksStock().equals(0)).collect(Collectors.toList());
        List<BizTaksStockLot> finishedLots = oldLots.stream().filter(v -> v.getIsTaksStock().equals(1)).collect(Collectors.toList());
        changeLots.forEach(l -> {
            l.setIsTaksStock(1);
            l.setTaksStockNum(l.getProdNum());
        });
        bizTaksStockLotService.updateBatchById(changeLots);
        return success(finishedLots.isEmpty() ? "盘点成功" : "未盘点批次已盘点完成，以下批次号已经盘点，未进行再次盘点。批次号：" + finishedLots.stream().map(BizTaksStockLot::getLotCode).collect(Collectors.joining(",")));
    }
}
