package com.yeejoin.amos.boot.module.tdc.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netflix.discovery.converters.Auto;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.service.impl.WorkflowExcuteServiceImpl;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;
import com.yeejoin.amos.boot.module.tdc.api.entity.CheckResult;
import com.yeejoin.amos.boot.module.tdc.api.entity.ModelItem;
import com.yeejoin.amos.boot.module.tdc.api.entity.SubmitRecord;
import com.yeejoin.amos.boot.module.tdc.api.mapper.CheckResultMapper;
import com.yeejoin.amos.boot.module.tdc.api.mapper.ModelItemMapper;
import com.yeejoin.amos.boot.module.tdc.api.mapper.SubmitRecordMapper;
import com.yeejoin.amos.boot.module.tdc.api.service.ModelItemService;
import com.yeejoin.amos.boot.module.tdc.api.service.SubmitRecordService;
import com.yeejoin.amos.boot.module.tdc.api.service.SyncMethodService;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author DELL
 */
@Service
public class ModelItemServiceImpl extends ServiceImpl<ModelItemMapper, ModelItem> implements ModelItemService {

    @Autowired
    SubmitRecordService submitRecordService;

    @Autowired
    SyncMethodService syncMethodService;

    @Autowired
    CheckResultMapper checkResultMapper;

    @Autowired
    SubmitRecordMapper submitRecordMapper;

    @Autowired
    ModelItemMapper modelItemMapper;

    @Autowired
    WorkflowExcuteServiceImpl workflowExcuteService;

    @Value("${tdc.file.examine.work.flow.processDefinitionKey}")
    private String processDefinitionKey;

    @Override
    public SubmitRecord saveModelItem(JSONObject jsonObject, AgencyUserModel userInfo, int draft,  ReginParams reginParams) {
        long start = System.currentTimeMillis();
        if (ObjectUtils.isEmpty(jsonObject)) {
            return null;
        }
        SubmitRecord submitRecord = new SubmitRecord();
        // 开启工作流并执行一步
        try {
            String processInstanceId = workflowExcuteService.startAndComplete(processDefinitionKey, "1");
            submitRecord.setProcessInstanceId(processInstanceId);
        } catch (Exception e) {
            log.error("工作流启动失败" + e.getMessage());
        }
        userInfo.getUserName();

        List<CompanyModel> company = userInfo.getCompanys();
        if (!CollectionUtils.isEmpty(company)) {
            String companyName = company.get(0).getCompanyName();
            String orgCode = company.get(0).getOrgCode();
            submitRecord.setAmosOrgCode(orgCode);
            submitRecord.setAmosOrgName(companyName);
        }
        submitRecord.setDraft(draft);
        submitRecord.setSubmitPeople(userInfo.getRealName());
        submitRecord.setSubmitTime(new Date());
        String batchNo = UUID.randomUUID().toString();
        submitRecord.setBatchNo(batchNo);
        long start1 = System.currentTimeMillis();
        log.error("=====记录入库前用时："+(start1-start)+"======");
        submitRecordService.saveSubmitRecord(submitRecord);
        long end = System.currentTimeMillis();
        log.error("=====记录入库用时："+(end-start1)+"======");
        if (StringUtils.isEmpty(submitRecord.getSequenceNbr())) {
            return null;
        }

        List<ModelItem> collect = jsonObject.entrySet().stream().map(e -> {
            ModelItem modelItem = new ModelItem();
            String key = e.getKey();
            String[] s = key.split("_");
            if (s.length == 2) {
                modelItem.setModelName(s[0]);
                modelItem.setCheckItemLabel(s[1]);
            } else if (s.length == 3) {
                modelItem.setModelName(s[0]);
                modelItem.setCheckItemLabel(s[1]);
                modelItem.setType(1);
                modelItem.setTagName(s[2]);
            } else {
                return null;
            }
            String value = String.valueOf(e.getValue());
            if (!ObjectUtils.isEmpty(value.split("_")) && value.split("_").length == 2) {
                modelItem.setCheckItemValue(value.split("_")[1]);
                modelItem.setTagName(value.split("_")[0]);
                modelItem.setType(0);
            } else {
                modelItem.setCheckItemValue(value);
            }
//            modelItem.setCheckItemValue(value);
            modelItem.setSubmitRecordId(submitRecord.getSequenceNbr());
            return modelItem;
        }).filter(item -> !ObjectUtils.isEmpty(item)).collect(Collectors.toList());

        Map<String, List<ModelItem>> itemValue = collect.stream().collect(Collectors.groupingBy(ModelItem::getModelName));

        long e1 = System.currentTimeMillis();
        log.error("=====参数解析用时："+(e1-end)+"======");
         this.saveBatch(collect);
        long e2 = System.currentTimeMillis();
        log.error("=====入库用时："+(e2-e1)+"======");

        // 异步请求规则校验
        if (draft == 1) {
            syncMethodService.checkItem(itemValue, submitRecord);
        }
        return submitRecord;
    }

    @Override
    public SubmitRecord editModelItem(JSONObject jsonObject, AgencyUserModel userInfo, int draft, Long id, int examine,  ReginParams reginParams) {
        Long sequenceNbr = ObjectUtils.isEmpty(jsonObject.get("sequenceNbr")) ? null : Long.valueOf(String.valueOf(jsonObject.get("sequenceNbr")));
        String batchNo = UUID.randomUUID().toString();
        Long sequenceNbrId = ObjectUtils.isEmpty(sequenceNbr) ? id : sequenceNbr;
        SubmitRecord submitRecord = submitRecordService.updateById(sequenceNbrId, batchNo, draft, examine);
        try {
            workflowExcuteService.CompleteTask(submitRecord.getProcessInstanceId(), String.valueOf(examine), reginParams);
        } catch (Exception e) {
            throw new RuntimeException("没有执行权限");
        }

        LambdaQueryWrapper<ModelItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ModelItem::getSubmitRecordId, sequenceNbrId);
        this.baseMapper.delete(wrapper);

        List<ModelItem> collect = jsonObject.entrySet().stream().map(e -> {
            ModelItem modelItem = new ModelItem();
            String key = e.getKey();
            String[] s = key.split("_");
            if (s.length == 2) {
                modelItem.setModelName(s[0]);
                modelItem.setCheckItemLabel(s[1]);
            } else if (s.length == 3) {
                modelItem.setModelName(s[0]);
                modelItem.setCheckItemLabel(s[1]);
                modelItem.setType(1);
                modelItem.setTagName(s[2]);
            } else {
                return null;
            }
            String value = String.valueOf(e.getValue());
            if (!ObjectUtils.isEmpty(value.split("_")) && value.split("_").length == 2) {
                modelItem.setCheckItemValue(value.split("_")[1]);
                modelItem.setTagName(value.split("_")[0]);
                modelItem.setType(0);
            } else {
                modelItem.setCheckItemValue(value);
            }
//            modelItem.setCheckItemValue(value);
            modelItem.setSubmitRecordId(submitRecord.getSequenceNbr());
            return modelItem;
        }).filter(item -> !ObjectUtils.isEmpty(item)).collect(Collectors.toList());
        this.saveOrUpdateBatch(collect);

        // 异步请求规则校验
        if (draft == 1) {
            Map<String, List<ModelItem>> itemValue = collect.stream().collect(Collectors.groupingBy(ModelItem::getModelName));
            syncMethodService.checkItem(itemValue, submitRecord);
        }
        return submitRecord;
    }


    @Override
    public Map<String, Object> getModelItem(Long sequenceNbr) {
        LambdaQueryWrapper<ModelItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ModelItem::getSubmitRecordId, sequenceNbr);
        List<ModelItem> list = this.list(wrapper);
        Map<String, Object> map = new HashMap<>();
        list.forEach(item -> {
            if (item.getType() == 1 ) {
                map.put(item.getModelName() + "_" + item.getCheckItemLabel() + "_" + item.getTagName(), item.getCheckItemValue());
            } else if (item.getType() == 0) {
                map.put(item.getModelName() + "_" + item.getCheckItemLabel(), item.getTagName() + "_" + item.getCheckItemValue());
            } else {
                map.put(item.getModelName() + "_" + item.getCheckItemLabel(), item.getCheckItemValue());
            }
        });
        map.put("sequenceNbr", sequenceNbr);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteModelItem(String sequenceNbr) {
        if (!StringUtils.isEmpty(sequenceNbr)) {
            String[] split = sequenceNbr.split(",");
            List<String> list = Arrays.asList(split);
            // 1. 删除记录
            submitRecordMapper.deleteBatchIds(list);
            // 2. 删除填报项
            LambdaQueryWrapper<ModelItem> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(ModelItem::getSubmitRecordId, list);
            this.baseMapper.delete(wrapper);
            // 3. 删除校验记录
            LambdaQueryWrapper<CheckResult> resultWrapper = new LambdaQueryWrapper<>();
            resultWrapper.in(CheckResult::getSubmitRecordId, list);
            checkResultMapper.delete(resultWrapper);
        }
    }
}
