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

import cn.ezhizao.common.exception.ServiceException;
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.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderOnce;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderOnceExport;
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.system.service.ISysDictDataService;
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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 单次委托工单Controller
 *
 * @author ruoyi
 * @date 2023-11-13
 */
@RestController
@RequestMapping("/business/workOrderOnce")
public class WorkOrderOnceController extends BaseController {
    @Resource
    IBizWorkOrderService bizWorkOrderService;
    @Resource
    ISysCurrentMonthService sysCurrentMonthService;
    @Resource
    IBizEntrustService bizEntrustService;
    @Resource
    ITenantService tenantService;
    @Resource
    private ISysDictDataService sysDictDataService;

    /**
     * 查询工单信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:once:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizWorkOrder);
        startPage();
        startOrderBy();
//        bizWorkOrder.setIsStop(0);
        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        list.forEach(v ->{
            Integer style = v.getAddressStyle();
            if(style ==null){
                return;
            }
            if (v.getTaskTypeId() == 5L && style == 1){
                //自有地址
                v.setExplain("自有地址:"+v.getInputProvince()+v.getInputCity()+v.getInputDistrict());
            }else if (v.getTaskTypeId() == 5L && style == 2){
                //虚拟地址
                v.setExplain("虚拟地址:"+sysDictDataService.selectDictDataById(v.getFictionAddressId()).getDictLabel());
            }else {
                v.setExplain("办理地区:"+v.getInputProvince()+v.getInputCity()+v.getInputDistrict());
            }

        });
        BizEntrust bizEntrust = new BizEntrust();
        bizEntrust.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
        List<BizEntrust> entrusts = bizEntrustService.getList(bizEntrust);
        list.forEach(l -> {
            l.setEntrust(entrusts.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).findFirst().orElse(null));
        });
        return getDataTable(list);
    }

    /**
     * 查询工单信息列表
     */
    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:once:list')")
    @GetMapping("/listForFactory")
    public TableDataInfo listForFactory(BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException
    {
        bizWorkOrder.setToTenantId(getTenantId());
        startPage();
//        bizWorkOrder.setIsStop(0);
        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        BizEntrust bizEntrust = new BizEntrust();
        bizEntrust.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
        List<BizEntrust> entrusts = bizEntrustService.getList(bizEntrust);
        list.forEach(l -> {
            l.setEntrust(entrusts.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).findFirst().orElse(null));
        });
        return getDataTable(list);
    }

    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:current:edit')")
    @PostMapping("/addEntrust")
    public AjaxResult addEntrust(@RequestBody BizEntrust entrust) {
        // 添加本月
        boolean status = addEntrust(entrust.getWorkOrderIds(), entrust.getWorkMonth(), entrust.getToTenantId());
        // 添加委托
        return toAjax(status);
    }

    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.setTaskTypeId(l.getTaskTypeId());
            bizEntrust.setTaskTypeDetailId(l.getTaskTypeDetailId());
            addEntrusts.add(bizEntrust);
        });
        // 保存
        return (entrustList.isEmpty() || bizEntrustService.updateBatchById(entrustList)) && (addEntrusts.isEmpty() || bizEntrustService.saveBatch(addEntrusts));
    }

    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:current:edit')")
    @PostMapping("/delEntrust")
    public AjaxResult delEntrust(@RequestBody BizEntrust bizEntrust) {
        List<BizEntrust> entrustList = bizEntrustService.getList(bizEntrust);
        DateTime currentMonth = DateTime.of(bizEntrust.getWorkMonth());
        bizEntrust.setWorkMonth(currentMonth.offset(DateField.MONTH, 1).toSqlDate());
        List<BizEntrust> nextEntrustList = bizEntrustService.getList(bizEntrust);

        boolean status = (entrustList.isEmpty() || bizEntrustService.removeByIds(entrustList.stream().map(BizEntrust::getId).collect(Collectors.toList()))) && (nextEntrustList.isEmpty() || bizEntrustService.removeByIds(nextEntrustList.stream().map(BizEntrust::getId).collect(Collectors.toList())));
        // 取消委托
        return toAjax(status);
    }

    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:current:trans')")
    @GetMapping("/transNext")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult transNext() {
        // 将本月改为上一月，将下月改成本月，添加新月
        List<SysCurrentMonth> months = sysCurrentMonthService.query().eq("tenant_id", getTenantId()).ge("type", 0).list();
        SysCurrentMonth currentMonth = months.stream().filter(v -> v.getType().equals(0)).findFirst().orElse(new SysCurrentMonth());
        if (currentMonth.getId() == null) {
            throw new ServiceException("未设定本月");
        }
        SysCurrentMonth nextMonth = months.stream().filter(v -> v.getType().equals(1)).findFirst().orElse(new SysCurrentMonth());
        SysCurrentMonth newNextMonth = new SysCurrentMonth();
        currentMonth.setType(-1);
        nextMonth.setType(0);
        DateTime nextMonthDate = DateTime.of(nextMonth.getYear() + nextMonth.getMonth() + "01", "yyyyMMdd");
        newNextMonth.setMonth(nextMonthDate.offsetNew(DateField.MONTH, 1).toString("MM"));
        newNextMonth.setYear(nextMonthDate.offsetNew(DateField.MONTH, 1).toString("yyyy"));
        newNextMonth.setTenantId(getTenantId());
        newNextMonth.setType(1);

        // 获取上月的委托
        List<BizEntrust> entrusts = bizEntrustService.query().eq("tenant_id", getTenantId()).eq("work_month", nextMonthDate.toSqlDate()).list();
        entrusts.forEach(l -> {
            DateTime currentWorkMonth = DateTime.of(l.getWorkMonth());
            DateTime currentMonthDate = DateTime.of(l.getCurrentMonth());
            l.setWorkMonth(currentWorkMonth.offsetNew(DateField.MONTH, 1).toSqlDate());
            l.setCurrentMonth(currentMonthDate.offsetNew(DateField.MONTH, 1).toSqlDate());
            l.setId(null);
        });

        return toAjax(
                (currentMonth.getId() == null || sysCurrentMonthService.updateById(currentMonth)) &&
                        (nextMonth.getId() == null || sysCurrentMonthService.updateById(nextMonth)) &&
                        sysCurrentMonthService.save(newNextMonth) && (entrusts.isEmpty() || bizEntrustService.saveBatch(entrusts))
        );
    }


    /**
     * 导出单次委托
     */
    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:once:export')")
    @Log(title = "单次委托", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizWorkOrder bizWorkOrder) throws NoSuchFieldException, IllegalAccessException {
        //如果有ToTenantId，说明是工厂版导出，不设置TenantId
        if(bizWorkOrder.getToTenantId()==null){
            setTenantId(bizWorkOrder);
        }
        startPage();
        startOrderBy();
//        bizWorkOrder.setIsStop(0);
        //查询单次委托列表
        List<BizWorkOrder> list = bizWorkOrderService.getList(bizWorkOrder);
        //非工厂版实体类集合
        List<BizWorkOrderOnceExport> listExport = new ArrayList<>();
        //工厂版实体类集合
        List<BizWorkOrderOnce> listOnce = new ArrayList<>();
        //查询当前期间
        List<SysCurrentMonth> months = sysCurrentMonthService.query().eq("tenant_id", getTenantId()).eq("type", 0).list();
        //如果没设置当前期间
        if(months.isEmpty()){
            if(bizWorkOrder.getTenantId()!=null){
                ExcelUtil<BizWorkOrderOnceExport> util = new ExcelUtil<BizWorkOrderOnceExport>(BizWorkOrderOnceExport.class);
                util.exportExcel(response, listExport, "单次工单");
            }else{
                ExcelUtil<BizWorkOrderOnce> util = new ExcelUtil<BizWorkOrderOnce>(BizWorkOrderOnce.class);
                util.exportExcel(response, listOnce, "单次工单");
            }

        }else {
            //查询委托信息
            BizEntrust bizEntrust = new BizEntrust();
            bizEntrust.setWorkOrderIds(list.stream().map(BizWorkOrder::getId).collect(Collectors.toList()));
            List<BizEntrust> entrusts = bizEntrustService.getList(bizEntrust);

            list.forEach(l -> {
                //设置委托信息
                l.setEntrust(entrusts.stream().filter(v -> v.getWorkOrderId().equals(l.getId())).findFirst().orElse(null));
                //工单类型
                l.setTypeName(l.getType()==1?"循环工单":"代办工单");
                //项目
                l.setTaskTypeName((l.getNoContract() == 1 ?l.getRemark() : "")+l.getTaskTypeName()+(l.getTaskTypeDetailName()!=null?"-"+l.getTaskTypeDetailName():""));
                //负责人
                l.setExecutor(l.getEntrust() == null ? l.getServiceName() : l.getEntrust().getToAccountName());

                BizWorkOrderOnceExport export = new BizWorkOrderOnceExport();
                export.setCompanyName(l.getCompanyName());
                export.setSocialCreditCode(l.getSocialCreditCode());
                export.setTypeName(l.getTypeName());
                export.setTaskTypeName(l.getTaskTypeName());
                export.setExecutor(l.getExecutor());
                listExport.add(export);

                //工厂版导出数据
                if(bizWorkOrder.getTenantId()==null){
                    BizWorkOrderOnce once=new BizWorkOrderOnce();
                    once.setCompanyName(l.getCompanyName());
                    once.setSocialCreditCode(l.getSocialCreditCode());
                    once.setTypeName(l.getTypeName());
                    once.setTaskTypeName(l.getTaskTypeName());
                    once.setExecutor(l.getExecutor());
                    once.setFromCompanyName(l.getFromCompanyName());
                    listOnce.add(once);
                }
            });

            if(bizWorkOrder.getTenantId()!=null){
                ExcelUtil<BizWorkOrderOnceExport> util = new ExcelUtil<BizWorkOrderOnceExport>(BizWorkOrderOnceExport.class);
                util.exportExcel(response, listExport, "单次工单");
            }else{
                ExcelUtil<BizWorkOrderOnce> util = new ExcelUtil<BizWorkOrderOnce>(BizWorkOrderOnce.class);
                util.exportExcel(response, listOnce, "单次工单");
            }
        }
    }

    @PreAuthorize("@ss.hasPermi('business:entrust:workOrder:current:addEntrust')")
    @GetMapping("/getFactories")
    public AjaxResult getFactories() {
        List<Tenant> tenants = tenantService.getFactories();
        return success(tenants);
    }
}
