package cn.ezhizao.project.business.upgrade;

import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Excel;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.lock.DistributionLock;
import cn.ezhizao.framework.lock.LockKey;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
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.IBizCollectionService;
import cn.ezhizao.project.business.order.domain.OrderExcelImportLoopModel;
import cn.ezhizao.project.business.order.service.IBizArchiveInputService;
import cn.ezhizao.project.business.upgrade.domain.*;
import cn.ezhizao.project.business.upgrade.service.IBizArchiveInputTempService;
import cn.ezhizao.project.business.upgrade.service.IBizWorkOrderUpdateService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import cn.ezhizao.project.fegin.IFeignClient;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/upgrade/crm")
public class crmUpgradeController extends BaseController {

    @Resource
    private IBizArchiveInputTempService bizArchiveInputTempService;
    @Resource
    private IBizArchiveInputService inputService;
    @Resource
    private IBizWorkOrderUpdateService bizWorkOrderUpdateService;
    @Resource
    private IBizWorkOrderService bizWorkOrderService;
    @Resource
    private IFeignClient tenantService;
    @Resource
    private IBizCollectionService bizCollectionService;
    @Resource
    private IBizCollectionDetailService bizCollectionDetailService;
    @Log(title = "基础版升级合同导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('business:upgrade:order:import')")
    @PostMapping("/order/importLoop")
    @Transactional
    public AjaxResult importLoop(MultipartFile file) throws Exception {
        String join = LockKey.join(LockKey.REPOR_UPDATE,getTenantId());
        DistributionLock lock = new DistributionLock(join);
        try {
            lock.lock(8,8,TimeUnit.MINUTES);
            ExcelUtil<OrderExcelImportLoopModel> util = new ExcelUtil<>(OrderExcelImportLoopModel.class);
            List<OrderExcelImportLoopModel> orderList = util.importExcel(file.getInputStream());

            // 获取 入Excel 表头字段
            List<String> excelHeaders = util.readExcelHeaders(file.getInputStream());
            //获取实体类字段
            List<String> names = getExcelAnnotatedFields(OrderExcelImportLoopModel.class);
            //如果不存在模板中的字段，返回错误
            if (!names.containsAll(excelHeaders)) {
                return error("导入数据与模板不匹配！");
            }
            String message = bizArchiveInputTempService.importLoop(orderList, SecurityUtils.getUserId(), getTenantId() == null ? 0 : getTenantId());
            return success(message);
        }catch (Exception e){
            logger.error(e.getMessage());
            return error("错误请联系管理员");
        }finally {
            lock.unlock();
        }
    }

    @Log(title = "基础版升级合同导入", businessType = BusinessType.OTHER)
    @PreAuthorize("@ss.hasPermi('business:upgrade:order:list')")
    @PostMapping(value = "/order/checkInput")
    public AjaxResult checkInput(@RequestParam("file") MultipartFile file) throws Exception {
        ExcelUtil<OrderExcelImportLoopModel> util = new ExcelUtil<>(OrderExcelImportLoopModel.class);
        List<OrderExcelImportLoopModel> orderList = util.importExcel(file.getInputStream());
        Map<String,String> fialmap = bizArchiveInputTempService.checkexcel(orderList,getTenantId());
        String failureNum = fialmap.get("failureNum");
        if (Integer.parseInt(failureNum) > 0) {
            return success("错误数据",fialmap.get("failureMsg"));
        }
        Map<String, List<importCheckModel>> map = bizArchiveInputTempService.checkInput(orderList,getTenantId());
        return success(map);
    }

    @Log(title = "基础版升级", businessType = BusinessType.INSERT)
    @PreAuthorize("@ss.hasPermi('business:upgrade:order:edit')")
    @PostMapping("/order/completeUpgrade")
    @Transactional
    public AjaxResult completeUpgrade(){
        String join = LockKey.join(LockKey.REPOR_UPDATE,getTenantId());
        DistributionLock lock = new DistributionLock(join);
        String message = "升级成功";
        try {
            lock.lock(8,8,TimeUnit.MINUTES);
            Long tenantId = 0L;
            tenantId = getTenantId();
            bizArchiveInputTempService.inputUpgrade(tenantId);
            List<BizWorkOrder> waitingForUpgradingList = bizWorkOrderService.lambdaQuery().eq(BizWorkOrder::getTenantId,tenantId).list();
            bizWorkOrderUpdateService.workerUpgrade(waitingForUpgradingList,tenantId);
            tenantService.completeUpgrade(tenantId,1L);


            //升级完成需要生成循环任务
            //List<BizWorkOrderUpdate> bizWorkOrderUpdates = bizWorkOrderUpdateService.lambdaQuery().eq(BizWorkOrderUpdate::getIsNew,1).list();
            List<BizWorkOrder> bizWorkOrderList = bizWorkOrderUpdateService.getNewOrder();
            bizWorkOrderList.forEach(order->inputService.addLoopTasks(order));

            List<BizWorkOrder> stopOrderList = bizWorkOrderUpdateService.getStopTaskOrder();
            stopOrderList.forEach(order->inputService.stopLoopTasks(order));
            //完成升级时需要真的删除收款合同表和详情表
            BizCollection delCollection = new BizCollection();
            delCollection.setTenantId(tenantId);
            bizCollectionService.physicalDelete(delCollection);
            BizCollectionDetail delDetail = new BizCollectionDetail();
            delDetail.setTenantId(tenantId);
            bizCollectionDetailService.physicallyDelete(delDetail);
            //工单列表页需要添加执行人的sql
        }catch (Exception e){
            logger.error(e.getMessage());
            return error("错误请联系管理员");
        }finally {
            lock.unlock();
        }

       return success(message);
    }
    @Log(title = "基础版升级", businessType = BusinessType.OTHER)
    @PreAuthorize("@ss.hasPermi('business:upgrade:order:list')")
    @PostMapping("/order/checkWorkOrder")
    public AjaxResult checkWorkOrder(){
        BizWorkOrderUpdate query = new BizWorkOrderUpdate();
        query.setTenantId(getTenantId());
        query.setType(1);
        Long count = bizWorkOrderUpdateService.getToUpLoadCount(query);
        if (null != count && count>0L) {
            return success("true");
        }
        return success("false");
    }

    /**
     * 导出档案入库列表
     */
    @PreAuthorize("@ss.hasPermi('business:upgrade:workOrder:export')")
    @Log(title = "基础版升级", businessType = BusinessType.EXPORT)
    @RequestMapping("/export")
    public void export(HttpServletResponse response, @RequestBody importCheckModelVo importCheckModelVo) throws NoSuchFieldException, IllegalAccessException, JsonProcessingException {
        response.setHeader("Content-Disposition","attachment;filename"+"文件.xlsx");
        ExcelUtil<exportModel> util = new ExcelUtil<>(exportModel.class);
        if("1".equals(importCheckModelVo.getType())){
            util.exportExcel(response, importCheckModelVo.getData().get("endMonth"), "导入的合同结束时间小于当前时间");
        }else if("2".equals(importCheckModelVo.getType())){
            util.exportExcel(response, importCheckModelVo.getData().get("startMonth"), "导入的合同开始时间大于当前时间");
        }
    }

    public List<String> getExcelAnnotatedFields(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<String> result = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Excel.class)) {
                Excel excelAnnotation = field.getAnnotation(Excel.class);
                String fieldName = excelAnnotation.name();
                result.add(fieldName);
            }
        }
        return result;
    }
}
