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

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
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.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.entrust.domain.BizEntrust;
import cn.ezhizao.project.business.entrust.service.IBizEntrustService;
import cn.ezhizao.project.business.housingFund.service.IBizHousingFundConfirmService;
import cn.ezhizao.project.business.keepAccounts.domain.BizFinancialKeepAccount;
import cn.ezhizao.project.business.keepAccounts.service.IBizFinancialKeepAccountService;
import cn.ezhizao.project.business.reportTax.service.IBizFinancialReportTaxService;
import cn.ezhizao.project.business.salary.service.IBizFinancialSalaryService;
import cn.ezhizao.project.business.socialSecurity.service.IBizSocialSecurityConfirmDetailService;
import cn.ezhizao.project.business.socialSecurity.service.IBizSocialSecurityConfirmService;
import cn.ezhizao.project.business.upgrade.domain.*;
import cn.ezhizao.project.business.upgrade.service.IBizArchiveInputDetailUpdateService;
import cn.ezhizao.project.business.upgrade.service.IBizArchiveInputTempService;
import cn.ezhizao.project.business.upgrade.service.IBizWorkOrderDetailUpdateService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import cn.ezhizao.project.business.upgrade.service.IBizWorkOrderUpdateService;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;

/**
 * 企业租户Controller
 *
 * @author ruoyi
 * @date 2024-10-14
 */
@RestController
@RequestMapping("/business/upgrade/workorder")
public class BizWorkOrderUpdateController extends BaseController
{
    @Resource
    private IBizWorkOrderUpdateService bizWorkOrderUpdateService;
    @Resource
    private IBizEntrustService entrustService;
    @Resource
    private IBizWorkOrderDetailUpdateService bizWorkOrderDetailService;
    @Resource
    private IBizArchiveInputTempService bizArchiveInputService;
    @Resource
    private IBizArchiveInputDetailUpdateService bizArchiveInputDetailService;
    @Resource
    private BizCollectionServiceImpl bizCollectionService;
    @Resource
    private IBizCollectionDetailService bizCollectionDetailService;

    @Resource
    private IBizFinancialKeepAccountService financialKeepAccountService;
    @Resource
    private IBizHousingFundConfirmService bizHousingFundConfirmService;
    @Resource
    private IBizFinancialReportTaxService bizFinancialReportTaxService;
    @Resource
    private IBizSocialSecurityConfirmService bizSocialSecurityConfirmService;
    @Resource
    private IBizFinancialSalaryService bizFinancialSalaryService;
    @Resource
    private IBizWorkOrderService bizWorkOrderService;
    final String[] reportTaskTableNames = {"biz_financial_individual_income_tax", "biz_financial_keep_account", "biz_financial_receive_ticket", "biz_financial_report_tax", "biz_financial_salary"};

    final String[] housingFundTaskTableNames = {"biz_housing_fund_confirm", "biz_housing_fund_declare"};

    final String[] socialSecurityTaskTableNames = {"biz_social_security_confirm", "biz_social_security_declare"};

    /**
     * 查询工单信息列表
     */
    @PreAuthorize("@ss.hasAnyPermi('business:upgrade:workorder:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizWorkOrderUpdate bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {

        //根据客户名称模糊查询去除两边空格
        List<BizWorkOrderUpdate> list = getBizWorkOrderUpdates(bizWorkOrder,true);
        return getDataTable(list);
    }

    private List<BizWorkOrderUpdate> getBizWorkOrderUpdates(BizWorkOrderUpdate bizWorkOrder,boolean ispage) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);

        if (ispage) startPage();

        //排序
        startOrderBy();
        if (bizWorkOrder.getCompanyName() != null) {
            if (!bizWorkOrder.getCompanyName().equals(""))
                bizWorkOrder.setCompanyName(bizWorkOrder.getCompanyName().trim());
        }
//        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        //有合并工单情况 不可以用合同明细联查
        List<BizWorkOrderUpdate> list = null;

        if(bizWorkOrder.getNoContract() == 1){
            list = bizWorkOrderUpdateService.gettoUpLoadList(bizWorkOrder);
        }else{
            list = bizWorkOrderUpdateService.getList2(bizWorkOrder);
        }
        BizEntrust entrustConditions = new BizEntrust();
        entrustConditions.setWorkOrderIds(list.stream().map(BizWorkOrderUpdate::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 (BizWorkOrderUpdate v : list) {
                BizWorkOrderDetailUpdate workOrderDetail = new BizWorkOrderDetailUpdate();
                workOrderDetail.setWorkOrderId(v.getId());
                //查询工单明细
                List<BizWorkOrderDetailUpdate> detailList = bizWorkOrderDetailService.getList(workOrderDetail);

                //查询合同收款金额
                BizArchiveInputUpdate 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) {

                            //且收款金额为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 (BizWorkOrderDetailUpdate d : detailList) {
                                Long contractDetailId = d.getContractDetailId();
                                //判断是否有起始月份

                                BizArchiveInputDetailUpdate detail = bizArchiveInputDetailService.getById(contractDetailId);
                                // 该明细的合同总金额
                                BizArchiveInputUpdate e = bizArchiveInputService.getById(d.getContractId());
                                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 list;
    }
    @PreAuthorize("@ss.hasPermi('business:upgrade:workOrder:edit')")
    @PostMapping("/updatestartmonth")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updatestartmonth(@RequestBody BizWorkOrderUpdate bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
        boolean status = bizWorkOrderUpdateService.saveOrUpdate(bizWorkOrder);
        return toAjax(status);
    }
    /**
     * 导出工单信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:upgrade:workOrder:export')")
    @Log(title = "工单信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizWorkOrderUpdate bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
   //     setTenantId(bizWorkOrder);
//        startPage();
   //     startOrderBy();
        List<BizWorkOrderUpdate> list = this.getBizWorkOrderUpdates(bizWorkOrder,false);
        ExcelUtil<BizWorkOrderUpdate> util = new ExcelUtil<BizWorkOrderUpdate>(BizWorkOrderUpdate.class);
        util.exportExcel(response, list, "工单信息数据");
    }

    @PreAuthorize("@ss.hasPermi('business:upgrade:workOrder:edit')")
    @Log(title = "工单信息", businessType = BusinessType.OTHER)
    @PostMapping("/OrderDisable")
    public AjaxResult OrderDisable(@RequestBody List<Long> ids) throws NoSuchFieldException, IllegalAccessException {
        bizWorkOrderService.updateByWorkOrderId(ids);
        List<BizWorkOrder> workOrderList = bizWorkOrderService.query().in("id",ids).list();
//        financialKeepAccountService.updateByWorkOrderId(ids);
//        bizHousingFundConfirmService.updateByWorkOrderId(ids);
//        bizFinancialReportTaxService.updateByWorkOrderId(ids);
//        bizSocialSecurityConfirmService.updateByWorkOrderId(ids);
//        bizFinancialSalaryService.updateByWorkOrderId(ids);
        workOrderList.forEach(workOrder -> {
            stopLoopTasks(workOrder);
        });
        return success("成功");
    }

    // 停止循环任务
    public boolean stopLoopTasks(BizWorkOrder workOrder) {
        if (workOrder.getTaskTypeId() == 1L) {
            return stopReportTask(workOrder);
        } else if (workOrder.getTaskTypeId() == 2L) {
            return stopSocialSecurity(workOrder);
        } else if (workOrder.getTaskTypeId() == 3L) {
            return stopHousingFund(workOrder);
        }
        return true;
    }

    private boolean stopHousingFund(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(housingFundTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            map.put("is_continue", 0);
            map.put("is_stop", 1);
            return map;
        }).collect(Collectors.toList());
        bizWorkOrderService.stopTasks(maps);
        return true;
    }
    private boolean stopSocialSecurity(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(socialSecurityTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            map.put("is_continue", 0);
            map.put("is_stop", 1);
            return map;
        }).collect(Collectors.toList());
        bizWorkOrderService.stopTasks(maps);
        return true;
    }
    private boolean stopReportTask(BizWorkOrder workOrder) {
        List<Map<String, Object>> maps = Arrays.stream(reportTaskTableNames).map(v -> {
            Map<String, Object> map = new HashMap<>();
            map.put("tableName", v);
            map.put("workOrderId", workOrder.getId());
            map.put("is_continue", 0);
            map.put("is_stop", 1);
            return map;
        }).collect(Collectors.toList());
        bizWorkOrderService.stopTasks(maps);
        return true;
    }
}
