package cn.ezhizao.project.business.workOrder.controller;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.uuid.SnowflakeIdWorker;
import cn.ezhizao.project.business.collection.domain.BizCollection;
import cn.ezhizao.project.business.collection.domain.BizCollectionDetail;
import cn.ezhizao.project.business.collection.service.IBizCollectionDetailService;
import cn.ezhizao.project.business.collection.service.impl.BizCollectionServiceImpl;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.entrust.domain.BizEntrust;
import cn.ezhizao.project.business.entrust.service.IBizEntrustService;
import cn.ezhizao.project.business.order.domain.BizArchiveInput;
import cn.ezhizao.project.business.order.domain.BizArchiveInputDetail;
import cn.ezhizao.project.business.order.service.IBizArchiveInputDetailService;
import cn.ezhizao.project.business.order.service.impl.BizArchiveInputServiceImpl;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderDetail;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderNoContract;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderDetailService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
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;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.web.page.TableDataInfo;

/**
 * 工单信息Controller
 *
 * @author ruoyi
 * @date 2023-10-16
 */
@RestController
@RequestMapping("/business/workOrder")
public class BizWorkOrderController extends BaseController {
    @Resource
    private IBizWorkOrderService bizWorkOrderService;

    @Resource
    private IBizEntrustService entrustService;

    @Resource
    private BizCollectionServiceImpl bizCollectionService;
    @Resource
    private IBizCollectionDetailService bizCollectionDetailService;

    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;

    @Resource
    private BizArchiveInputServiceImpl bizArchiveInputService;

    @Resource
    private IBizArchiveInputDetailService bizArchiveInputDetailService;

    @Resource
    private IBizWorkOrderDetailService bizWorkOrderDetailService;

    @Resource
    private IBizCompanyService companyService;

    /**
     * 查询工单信息列表
     */
    @PreAuthorize("@ss.hasAnyPermi('business:workOrder:list,business:workOrder:noContract:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);

        startPage();
        //排序
        startOrderBy();
        //根据客户名称模糊查询去除两边空格
        if (bizWorkOrder.getCompanyName() != null) {
            if (!bizWorkOrder.getCompanyName().equals(""))
                bizWorkOrder.setCompanyName(bizWorkOrder.getCompanyName().trim());
        }
//        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        //有合并工单情况 不可以用合同明细联查
        List<BizWorkOrder> list = bizWorkOrderService.getList2(bizWorkOrder);
        BizEntrust entrustConditions = new BizEntrust();
        entrustConditions.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
        List<BizEntrust> entrusts = entrustService.getList(entrustConditions);
        list.forEach(v -> {
            v.setEntrusts(entrusts.stream().filter(e -> e.getWorkOrderId().equals(v.getId())).collect(Collectors.toList()));
        });

        //判断是否是合同查询
        if (bizWorkOrder.getNoContract() == 0) {
            for (BizWorkOrder v : list) {
                BizWorkOrderDetail workOrderDetail = new BizWorkOrderDetail();
                workOrderDetail.setWorkOrderId(v.getId());
                //查询工单明细
                List<BizWorkOrderDetail> detailList = bizWorkOrderDetailService.getList(workOrderDetail);

                //查询合同收款金额
                BizArchiveInput bizArchiveInput = bizArchiveInputService.getById(v.getContractId());
                BigDecimal money = new BigDecimal(0);
                if (bizArchiveInput != null) {
                    money = bizArchiveInput.getTrueAmount();
                }

                //如果是单次工单
                if (v.getType() == 2) {
                    BizCollection collection = new BizCollection();
                    collection.setContractId(v.getContractId());
                    collection.setStatus(1);
                    //查询收款数据
                    List<BizCollection> colList = bizCollectionService.getList(collection);
                    //已收款金额
                    BigDecimal collectionMoney = new BigDecimal(0);
                    //计算收款金额
                    for (BizCollection d : colList) {
                        BigDecimal addMoney = d.getArriveAmount();
                        if (addMoney != null) {
                            collectionMoney = collectionMoney.add(addMoney);
                        } else {
                            addMoney = new BigDecimal(0);
                        }
                    }
                    //判断是否全部收款
                    if (collectionMoney.compareTo(money) == 0) {
                        v.setOnceContractStatus("已收款");
                    } else if (collectionMoney.compareTo(money) < 0 && collectionMoney.compareTo(new BigDecimal(0)) > 0) {
                        v.setOnceContractStatus("部分收款");
                    } else if (collectionMoney.compareTo(new BigDecimal(0)) == 0) {
                        v.setOnceContractStatus("未收款");
                    }
                }
                //如果是循环工单
                if (v.getType() == 1 && detailList.size() > 0) {

                    //判断是否有起始月份
//                    BizArchiveInputDetail detail = new BizArchiveInputDetail();
////                    detail.setContractId(v.getContractId());
//                    detail.setFromId(0L);
//                    detail.setCompanyId(v.getCompanyId());
//                    detail.setDeleted(0);
//                    detail.setTaskTypeId(v.getTaskTypeId());
//                    detail = bizArchiveInputDetailService.getDetail(detail);
                    Integer monthNum = 0;
                    if (v.getStartMonth() != null) {

                        //如果只有一个合同
                        if (detailList.size() == 1) {
                            if(null == detailList.get(0).getAccountsReceivable()){
                                System.out.println("好了");
                            }
                            //且收款金额为0
                            detailList.get(0).setTotalityMoney(detailList.get(0).getTotalityMoney() == null ? new BigDecimal(0) : detailList.get(0).getTotalityMoney());
                            if (detailList.get(0).getAccountsReceivable().compareTo(new BigDecimal(0)) == 0) {
                                v.setClosingMonth("已收款");
                            } else if (detailList.get(0).getTotalityMoney().compareTo(new BigDecimal(0)) == 0) {
                                v.setClosingMonth("未收款");
                            } else if (detailList.get(0).getTotalityMoney().compareTo(detailList.get(0).getAccountsReceivable()) >= 0) {
                                v.setClosingMonth("已收款");
                            } else {
                                List<BizCollection> collectionList = new ArrayList<>();
                                BizCollection collection = new BizCollection();
                                collection.setContractId(detailList.get(0).getContractId());
                                collectionList = bizCollectionService.getList(collection);
                                if (collectionList.size() > 0) {
                                    BizCollectionDetail collectionDetails = new BizCollectionDetail();
                                    collectionDetails.setContractId(detailList.get(0).getContractId());
                                    collectionDetails.setTaskTypeId(detailList.get(0).getTaskTypeId());
                                    collectionDetails.setCollectionId(collectionList.get(0).getId());
                                    List<BizCollectionDetail> collectionDetail = bizCollectionDetailService.getListByBean(collectionDetails);
                                    if (collectionDetail != null && !collectionDetail.isEmpty() && detailList != null && !detailList.isEmpty()) {
                                        for (BizCollectionDetail d : collectionDetail) {
                                            if (d.getTaskTypeId() == detailList.get(0).getTaskTypeId()) {
                                                d.setAmount( d.getAmount()== null ? new BigDecimal(0) : d.getAmount());
                                                if (d.getAmount().compareTo(d.getArriveAmount()) <= 0) {
                                                    v.setClosingMonth("已收款");
                                                } else if (d.getAmount().compareTo(d.getArriveAmount()) > 0 && d.getArriveAmount().compareTo(new BigDecimal(0)) != 0) {
                                                    v.setClosingMonth("部分收款");
                                                } else if (d.getArriveAmount() == new BigDecimal(0)) {
                                                    v.setClosingMonth("未收款");
                                                } else {
                                                    v.setClosingMonth("未收款");
                                                }
                                            }
                                        }
                                    }
                                }

                            }

                        } else {
                            //根据单价计算月数
                            for (BizWorkOrderDetail d : detailList) {
                                Long contractDetailId = d.getContractDetailId();
                                //判断是否有起始月份

                                BizArchiveInputDetail detail = bizArchiveInputDetailService.getById(contractDetailId);
                                // 该明细的合同总金额
                                BizArchiveInput e = bizArchiveInputService.getById(d.getContractId());
                                if(null == e){
                                    System.out.println("a");
                                }
                                money = e.getAmount();
                                //如果收款金额大于0
                                if (d.getTotalityMoney() != null && d.getTotalityMoney().compareTo(new BigDecimal(0)) > 0 && d.getServiceNum() > 0) {
                                    detail.setContractId(d.getContractId());
                                    detail.setTaskTypeId(d.getTaskTypeId());
                                    detail = bizArchiveInputDetailService.getDetail(detail);
                                    BigDecimal price = money.divide(new BigDecimal(d.getServiceNum()), 2, RoundingMode.HALF_UP);//除法，保留两位小数，四舍五入
                                    monthNum += d.getTotalityMoney().divide(price, MathContext.DECIMAL64).setScale(0, RoundingMode.DOWN).intValue();
                                }
                                if (money.compareTo(BigDecimal.ZERO) == 0) {
                                    monthNum = monthNum + detail.getServiceNum() + detail.getFreeNum();
                                }
                                //判断收款月数是否等于服务月数
                                if (detail!= null && detail.getServiceNum() == monthNum) {
                                    //如果服务月数等于收款月数则加上赠送月数
                                    monthNum += detail.getFreeNum();
                                }
                            }

                            //设置收款截止月
                            Calendar rightNow = Calendar.getInstance();
                            rightNow.setTime(v.getStartMonth());
                            rightNow.add(Calendar.MONTH, monthNum == 0 ? monthNum : monthNum - 1);
                            Date closingMonth = rightNow.getTime();
                            // 创建一个SimpleDateFormat对象，指定日期格式
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
                            // 将Date对象转换为字符串
                            String dateString = sdf.format(closingMonth);
                            v.setClosingMonth("收款截止" + dateString);
                        }
                    } else {
                        v.setClosingMonth("-");
                    }
                }
            }
        }
        return getDataTable(list);
    }

    /**
     * 首页查询工单信息列表
     */

    @GetMapping("/indexList")
    public TableDataInfo indexList(BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
        //排序
        startOrderBy();
        //获取当前登录用户Id
        bizWorkOrder.setServiceId(SecurityUtils.getLoginUser().getUserId());
        //根据客户名称模糊查询去除两边空格
        if (bizWorkOrder.getCompanyName() != null) {
            if (!bizWorkOrder.getCompanyName().equals(""))
                bizWorkOrder.setCompanyName(bizWorkOrder.getCompanyName().trim());
        }
        List<BizWorkOrder> list = bizWorkOrderService.getIndexList(bizWorkOrder);
        BizEntrust entrustConditions = new BizEntrust();
        entrustConditions.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
        List<BizEntrust> entrusts = entrustService.getList(entrustConditions);
        list.forEach(v -> {
            v.setEntrusts(entrusts.stream().filter(e -> e.getWorkOrderId().equals(v.getId())).collect(Collectors.toList()));
        });

        for (BizWorkOrder v : list) {
            if (v.getNoContract() == 1) {
                v.setTaskTypeName(v.getRemark());
            }
        }

        return getDataTable(list);
    }


    /**
     * 导出工单信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:export')")
    @Log(title = "工单信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
//        startPage();
        startOrderBy();
        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        ExcelUtil<BizWorkOrder> util = new ExcelUtil<BizWorkOrder>(BizWorkOrder.class);
        util.exportExcel(response, list, "工单信息数据");
    }

    /**
     * 导出工单信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:export')")
    @Log(title = "工单信息", businessType = BusinessType.EXPORT)
    @PostMapping("/exportNoContract")
    public void exportNoContract(HttpServletResponse response, BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
//        startPage();
        startOrderBy();
        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        List<BizWorkOrderNoContract> listNoContract = new ArrayList<>();
        BizEntrust bizEntrust = new BizEntrust();
        bizEntrust.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
        List<BizEntrust> entrusts = entrustService.getList(bizEntrust);
        list.forEach(l -> {
            l.setEntrust(entrusts.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).findFirst().orElse(null));
            BizWorkOrderNoContract noContract = new BizWorkOrderNoContract();
            noContract.setRemark(l.getRemark());
            noContract.setSocialCreditCode(l.getSocialCreditCode());
            noContract.setCompanyName(l.getCompanyName());
            noContract.setServiceName(l.getEntrust() == null ? l.getServiceName() : l.getEntrust().getToAccountName());
            listNoContract.add(noContract);
        });
        ExcelUtil<BizWorkOrderNoContract> util = new ExcelUtil<BizWorkOrderNoContract>(BizWorkOrderNoContract.class);
        util.exportExcel(response, listNoContract, "工单信息数据");
    }

    /**
     * 获取工单信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(bizWorkOrderService.getById(id));
    }

    /**
     * 获取工单信息详细信息
     */
    @Log(title = "修改是否延续", businessType = BusinessType.UPDATE)
    @PreAuthorize("@ss.hasPermi('business:workOrder:continue')")
    @PostMapping(value = "/{ids}/{state}")
    @Transactional
    public AjaxResult setContract(@PathVariable("ids") List<Long> ids, @PathVariable("state") Integer state) {
        if(state.equals(0)){
            List<BizWorkOrder> workOrderList = bizWorkOrderService.query().in("id",ids).list();
            bizWorkOrderService.continueStop(workOrderList);
        }
        return toAjax(bizWorkOrderService.setContinue(ids, state));
    }

    /**
     * 新增工单信息
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:add')")
    @Log(title = "工单信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
        bizWorkOrder.setWorkOrderNo("workOrder_" + snowflakeIdWorker.nextId());
        return toAjax(bizWorkOrderService.save(bizWorkOrder));
    }

    /**
     * 修改工单信息
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:edit')")
    @Log(title = "工单信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
        return toAjax(bizWorkOrderService.updateById(bizWorkOrder) && saveInputMonth(bizWorkOrder));
    }
    private boolean saveInputMonth(BizWorkOrder bizWorkOrder) {
        List<BizWorkOrderDetail> orderDetailList = bizWorkOrderDetailService
                .query()
                .eq("work_order_id",bizWorkOrder.getId())
                .eq("deleted",0).list();
        for (BizWorkOrderDetail bizWorkOrderDetail : orderDetailList) {
            bizArchiveInputService.saveDetailMonth(bizArchiveInputService.query().eq("id",bizWorkOrderDetail.getContractId()).list().get(0));
        }
        return true;
    }

    /**
     * 删除工单信息
     */
    @PreAuthorize("@ss.hasPermi('business:workOrder:remove')")
    @Log(title = "工单信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult remove(@PathVariable List<Long> ids) {

        List<BizWorkOrder> list = bizWorkOrderService.list(new LambdaQueryWrapper<BizWorkOrder>().in(BizWorkOrder::getId, ids));
        for (BizWorkOrder item : list) {
            Long id = item.getId();
            Long companyId = item.getCompanyId();
            List<BizEntrust> bizEntrusts = entrustService.list(new LambdaQueryWrapper<BizEntrust>().eq(BizEntrust::getWorkOrderId, id).eq(BizEntrust::getCompanyId, companyId));
            if (!CollectionUtils.isEmpty(bizEntrusts)) {
                String compName = companyService.getById(companyId).getName();
                return error(compName + "该工单已经委托给工厂，请先取消委托!");
            }
        }
        return toAjax(bizWorkOrderService.removeBatchByIds(list));
    }

    @PreAuthorize("@ss.hasAnyPermi('business:customer:service:once:transactor,business:customer:service:loop:transactor')")
    @PostMapping("setService")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setService(@RequestBody BizWorkOrder workOrder) {
        List<BizWorkOrder> workOrders = bizWorkOrderService.query().in("id", workOrder.getIds()).list();
        workOrders.forEach(l -> l.setServiceId(workOrder.getServiceId()));
        return toAjax(bizWorkOrderService.updateBatchById(workOrders));
    }
}
