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

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.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.domain.BizArchiveInputDetailProcess;
import cn.ezhizao.project.business.order.service.IBizArchiveInputDetailProcessService;
import cn.ezhizao.project.business.order.service.IBizArchiveInputService;
import cn.ezhizao.project.business.standardCpmpany.domain.BizStandardCompany;
import cn.ezhizao.project.business.standardCpmpany.service.IBizStandardCompanyService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderDetail;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderDetailService;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import cn.ezhizao.project.system.domain.SysCurrentMonth;
import cn.ezhizao.project.system.service.ISysCurrentMonthService;
import cn.ezhizao.project.tenant.domain.Tenant;
import cn.ezhizao.project.tenant.service.ITenantService;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.sql.Date;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

/**
 * standardCompanyController
 *
 * @author ezhizao
 * @date 2023-10-30
 */
@RestController
@RequestMapping("/business/standardCompany")
public class BizStandardCompanyController extends BaseController {
    @Resource
    IBizStandardCompanyService bizStandardCompanyService;

    @Resource
    ISysCurrentMonthService sysCurrentMonthService;

    @Resource
    IBizEntrustService bizEntrustService;

    @Resource
    IBizArchiveInputDetailProcessService archiveInputDetailProcessService;

    @Resource
    IBizArchiveInputService bizArchiveInputService;

    @Resource
    ITenantService tenantService;

    @Resource
    IBizWorkOrderDetailService bizWorkOrderDetailService;

    @Resource
    IBizWorkOrderService bizWorkOrderService;

    /**
     * 查询standardCompany列表
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizStandardCompany bizStandardCompany) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizStandardCompany);
        startPage();
        startOrderBy();
        List<BizStandardCompany> list = bizStandardCompanyService.getList(bizStandardCompany);
        return getDataTable(list);
    }

    /**
     * 导出standardCompany列表
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:export')")
    @Log(title = "standardCompany", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizStandardCompany bizStandardCompany) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizStandardCompany);
        List<BizStandardCompany> list = bizStandardCompanyService.getList(bizStandardCompany);
        list.forEach(l -> {
            l.setZero(l.getIsZero() == 1 ? "是" : "否");
        });
        ExcelUtil<BizStandardCompany> util = new ExcelUtil<BizStandardCompany>(BizStandardCompany.class);
        util.exportExcel(response, list, "standardCompany数据");
    }

    /**
     * 生成单次委托
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:setOneEntrust')")
    @Log(title = "生成单次委托", businessType = BusinessType.INSERT)
    @PostMapping("/setOneEntrust")
    public AjaxResult setOneEntrust(@RequestBody BizArchiveInput archiveInput) throws NoSuchFieldException, IllegalAccessException {
        List<BizWorkOrder> workOrders = bizWorkOrderService.query().eq("company_id", archiveInput.getCompanyId()).eq("is_stop", 0).list();
        //查询委托签约合同
        List<Tenant> tenants = tenantService.getFactoriesId(getTenantId());
        List<BizWorkOrder> newWorkOrders = new ArrayList<>();
        boolean bool = true;
        List<Long> list = new ArrayList<>();
        for (BizArchiveInputDetail detail : archiveInput.getDetails()) {
            for (BizArchiveInputDetailProcess process : detail.getProcesses()) {
                BizWorkOrder workOrder = new BizWorkOrder();
                workOrder.setNoContract(0);
                workOrder.setType(2);
                workOrder.setIsContinue(0);
                workOrder.setTenantId(getTenantId());
                workOrder.setTaskTypeId(detail.getTaskTypeId());
                workOrder.setTaskTypeDetailId(process.getTaskTypeDetailId());
                workOrder.setCompanyId(archiveInput.getCompanyId());
                bizWorkOrderService.save(workOrder);
                newWorkOrders.add(workOrder);
                list.add(workOrder.getId());
            }
        }

        //如果只有一家工厂，设置委托
        if (tenants.size() == 1) {
            bool = addEntrust(list, new java.sql.Date(archiveInput.getFormDate().getTime()), tenants.get(0).getId());
            newWorkOrders.forEach(bizArchiveInputService::addLoopTasks);
        }
        return success(bool);
    }

    /**
     * 生成循环委托
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:setLoopEntrust')")
    @Log(title = "生成循环委托", businessType = BusinessType.INSERT)
    @PostMapping("/setLoopEntrust")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setLoopEntrust(@RequestBody BizWorkOrder order) throws NoSuchFieldException, IllegalAccessException {
        //查询委托签约合同
        List<Tenant> tenants = tenantService.getFactoriesId(getTenantId());
        boolean bool = true;
        List<Long> list = new ArrayList<>();
        List<BizWorkOrder> newWorkOrders = new ArrayList<>();

        //生成工单
        for (BizStandardCompany company : order.getCompanies()) {

            for (Long typeId : order.getTaskTypeIds()) {
                if (typeId == 1) {
                    if (company.getIsZero() == null) {
                        company.setIsZero(order.getIsZero());
                        bizStandardCompanyService.updateById(company);

                    }
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(order.getStartMonth());
                    calendar.add(Calendar.MONTH, -1);
                    order.setStartMonth(new java.sql.Date(calendar.getTime().getTime()));
                }
                BizWorkOrder workOrder = new BizWorkOrder();
                workOrder.setTenantId(getTenantId());
                workOrder.setCompanyId(company.getId());
                workOrder.setTaskTypeId(typeId);
                workOrder.setIsStop(0);
                workOrder.setType(1);
                workOrder.setStartMonth(order.getStartMonth());

                //查询是否存在该期间工单
                List<BizWorkOrder> workOrders = bizWorkOrderService.selectStarMonthList(workOrder);
                if (workOrders.size() > 0) {

                    throw new RuntimeException("已有该期间工单");
                }
                workOrder.setIsContinue(0);
                workOrder.setStartMonth(null);
                workOrders = bizWorkOrderService.getList(workOrder);
                workOrder.setStartMonth(order.getStartMonth());
                if(typeId == 1){

                }
                if (workOrders.size() > 0) {
                    workOrder.setStartMonth(order.getStartMonth());
                    BizWorkOrder orders = workOrders.get(0);
                    Long oldCurrentMontn = orders.getStartMonth().getTime();
                    Long newCurrentMontn = workOrder.getStartMonth().getTime();
                    //计算时间差
                    if (newCurrentMontn > oldCurrentMontn) {
                        long daysBetween = newCurrentMontn - oldCurrentMontn;
                        daysBetween = daysBetween / (24 * 60 * 60 * 1000);
                        //时间差大于30天
                        if (daysBetween > 30) {
                            BizEntrust entrust = new BizEntrust();
                            entrust.setWorkOrderId(orders.getId());
                            entrust.setWorkMonth(new Date(orders.getStartMonth().getTime()));
                            // 获取已有委托
                            List<BizEntrust> entrustList = bizEntrustService.getList(entrust);
                            //如果有委托
                            if (entrustList.size() > 0) {
                                Calendar calendar = Calendar.getInstance();
                                calendar.setTime(order.getStartMonth());
                                //计算前一个月的日期
                                calendar.add(Calendar.MONTH, -1);
                                orders.setEndMonth(calendar.getTime());
                                bizWorkOrderService.updateById(orders);
                                bool = bizWorkOrderService.save(workOrder);
                                BizWorkOrderDetail bizWorkOrderDetail = new BizWorkOrderDetail();
                                bizWorkOrderDetail.setCompanyId(workOrder.getCompanyId());
                                bizWorkOrderDetail.setWorkOrderId(workOrder.getId());
                                bizWorkOrderDetail.setTaskTypeId(workOrder.getTaskTypeId());
                                bizWorkOrderDetail.setTenantId(workOrder.getTenantId());
                                bizWorkOrderDetailService.save(bizWorkOrderDetail);
                            } else {
                                LocalDateTime localDateTime = LocalDateTime.now();
                                Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
                                Date date = new Date(Date.from(instant).getTime());
                                oldCurrentMontn = orders.getStartMonth().getTime();
                                newCurrentMontn = date.getTime();
                                daysBetween = newCurrentMontn - oldCurrentMontn;
                                daysBetween = daysBetween / (24 * 60 * 60 * 1000);

                                if (daysBetween >  30) {
                                    orders.setIsStop(1);
                                    bizArchiveInputService.stopLoopTasks(orders);
                                    bizWorkOrderService.saveOrUpdate(orders);
                                    bool = bizWorkOrderService.save(workOrder);
                                    newWorkOrders.add(workOrder);
                                    BizWorkOrderDetail bizWorkOrderDetail = new BizWorkOrderDetail();
                                    bizWorkOrderDetail.setCompanyId(workOrder.getCompanyId());
                                    bizWorkOrderDetail.setWorkOrderId(workOrder.getId());
                                    bizWorkOrderDetail.setTaskTypeId(workOrder.getTaskTypeId());
                                    bizWorkOrderDetail.setTenantId(workOrder.getTenantId());
                                    bizWorkOrderDetailService.save(bizWorkOrderDetail);
                                    list.add(workOrder.getId());
                                } else {
                                    Calendar calendar = Calendar.getInstance();
                                    calendar.setTime(order.getStartMonth());
                                    //计算前一个月的日期
                                    calendar.add(Calendar.MONTH, -1);
                                    orders.setEndMonth(calendar.getTime());
                                    bizWorkOrderService.updateById(orders);
                                    bool = bizWorkOrderService.save(workOrder);
                                    newWorkOrders.add(workOrder);
                                    list.add(workOrder.getId());
                                }
                            }
                        }
                    }
                } else {

                    bool = bizWorkOrderService.save(workOrder);

                    BizWorkOrderDetail bizWorkOrderDetail = new BizWorkOrderDetail();
                    bizWorkOrderDetail.setCompanyId(workOrder.getCompanyId());
                    bizWorkOrderDetail.setWorkOrderId(workOrder.getId());
                    bizWorkOrderDetail.setTaskTypeId(workOrder.getTaskTypeId());
                    bizWorkOrderDetail.setTenantId(workOrder.getTenantId());
                    bizWorkOrderDetailService.saveOrUpdate(bizWorkOrderDetail);
                    list.add(workOrder.getId());
                    newWorkOrders.add(workOrder);
                }
            }
        }
        newWorkOrders.forEach(bizArchiveInputService::addLoopTasks);

        //如果只有一家工厂，设置委托
        if (tenants.size() == 1) {
            List<SysCurrentMonth> months = sysCurrentMonthService.query().eq("tenant_id", getTenantId()).eq("type", 0).list();
            Calendar calendar = Calendar.getInstance();
            // 设置年份
            calendar.set(Calendar.YEAR, Integer.parseInt(months.get(0).getYear()));
            // 设置月份为（注意：月份是从0开始的，所以要减1）
            calendar.set(Calendar.MONTH, Integer.parseInt(months.get(0).getMonth()) - 1);
            // 设置日期
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            Date month = new java.sql.Date(calendar.getTime().getTime());
            Date newMonth = new java.sql.Date(order.getStartMonth().getTime());
            int monthDifference=0;
            //判断时间是否小于当前期间
            if(newMonth.before(month)){
                //计算相差月份
                monthDifference = getMonthDifference(month, newMonth);
            }
            if(monthDifference>0){
                //添加委托
                for(int i=0;i<=monthDifference;i++){
                    java.sql.Date workMonth = new java.sql.Date(order.getStartMonth().getTime());
                    LocalDate localDate = workMonth.toLocalDate();
                    localDate=localDate.plusMonths(i);
                    workMonth= Date.valueOf(localDate);
                    bool = addEntrust(list, workMonth, tenants.get(0).getId());
                }
            }else {
                bool = addEntrust(list, new java.sql.Date(order.getStartMonth().getTime()), tenants.get(0).getId());
            }
        }

        return success(bool);
    }

    /**
     * 计算两个日期之间的月份差。
     * 注意：此方法只考虑年份和月份，不考虑日期。
     * @param date1 第一个日期
     * @param date2 第二个日期
     * @return 两个日期之间的月份差
     */
    public int getMonthDifference(Date date1, Date date2) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);

        int monthDiff = Math.abs((calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR)) * 12 +
                (calendar1.get(Calendar.MONTH) - calendar2.get(Calendar.MONTH)));
        return monthDiff;
    }


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


    /**
     * 新增standardCompany
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:add')")
    @Log(title = "standardCompany", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BizStandardCompany bizStandardCompany) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizStandardCompany);
        return toAjax(bizStandardCompanyService.save(bizStandardCompany));
    }


    /**
     * 修改standardCompany
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:edit')")
    @Log(title = "standardCompany", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BizStandardCompany bizStandardCompany) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizStandardCompany);
        return toAjax(bizStandardCompanyService.updateById(bizStandardCompany));
    }

    /**
     * 删除standardCompany
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:remove')")
    @Log(title = "standardCompany", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids) {
        return toAjax(bizStandardCompanyService.removeBatchByIds(ids));
    }

    /**
     * 修改负责人
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:Leader')")
    @Log(title = "负责人", businessType = BusinessType.UPDATE)
    @PostMapping("/Leader/{ids}")
    public AjaxResult updateStandardCompanyLeader(@PathVariable List<Long> ids, @RequestBody Long userId) {
        return toAjax(bizStandardCompanyService.updateUserId(ids, userId, 0));
    }

    /**
     * 修改客服
     */
    @PreAuthorize("@ss.hasPermi('business:standardCompany:Adviser')")
    @Log(title = "客服", businessType = BusinessType.UPDATE)
    @PostMapping("/Adviser/{ids}")
    public AjaxResult updateStandardCompanyAdviser(@PathVariable List<Long> ids, @RequestBody Long userId) {
        return toAjax(bizStandardCompanyService.updateUserId(ids, userId, 1));
    }

    private boolean addEntrust(List<Long> workOrderId, Date paramWorkMonth, Long toTenantId) {

        BizEntrust entrust = new BizEntrust();
        entrust.setWorkOrderIds(workOrderId);
        entrust.setWorkMonth(paramWorkMonth);
        entrust.setToTenantId(toTenantId);

        // 获取所有已有委托
        List<BizEntrust> entrustList = bizEntrustService.getList(entrust);
        // 获取未有委托的工单
        List<BizWorkOrder> bizWorkOrders = new ArrayList<>();
        if (entrust.getWorkOrderIds().stream().anyMatch(e -> entrustList.stream().noneMatch(t -> t.getWorkOrderId().equals(e)))) {
            bizWorkOrders.addAll(bizWorkOrderService.query().in("id", entrust.getWorkOrderIds().stream().filter(e -> entrustList.stream().noneMatch(t -> t.getWorkOrderId().equals(e))).collect(Collectors.toList())).list());
        }
        // 修改已有委托的委托信息
        entrustList.forEach(l -> {
            l.setToTenantId(entrust.getToTenantId());
        });
        // 添加新委托
        List<BizEntrust> addEntrusts = new ArrayList<>();
        bizWorkOrders.forEach(l -> {
            BizEntrust bizEntrust = new BizEntrust();
            bizEntrust.setWorkOrderId(l.getId());
            bizEntrust.setCompanyId(l.getCompanyId());
            bizEntrust.setToTenantId(entrust.getToTenantId());
            bizEntrust.setTenantId(l.getTenantId());
            bizEntrust.setFromTenantId(l.getTenantId());
            bizEntrust.setCurrentMonth(entrust.getWorkMonth());

            if (l.getTaskTypeId() == 1L) {
                DateTime workMonth = DateTime.of(entrust.getWorkMonth());
                bizEntrust.setCurrentMonth(workMonth.offsetNew(DateField.MONTH, -1).toSqlDate());
            } else {
            }
            bizEntrust.setWorkMonth(entrust.getWorkMonth());
            bizEntrust.setTaskTypeId(l.getTaskTypeId());
            bizEntrust.setTaskTypeDetailId(l.getTaskTypeDetailId());
            addEntrusts.add(bizEntrust);
        });
        // 保存
        return (entrustList.isEmpty() || bizEntrustService.updateBatchById(entrustList)) && (addEntrusts.isEmpty() || bizEntrustService.saveBatch(addEntrusts));
    }
}
