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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yeejoin.amos.boot.module.hygf.api.Enum.*;
import com.yeejoin.amos.boot.module.hygf.api.dto.*;
import com.yeejoin.amos.boot.module.hygf.api.entity.*;
import com.yeejoin.amos.boot.module.hygf.api.mapper.*;
import com.yeejoin.amos.boot.module.hygf.api.service.IBasicGridAcceptanceService;
import com.yeejoin.amos.boot.module.hygf.api.util.NumberUtil;
import com.yeejoin.amos.boot.module.hygf.api.util.RedisLockUtil;
import com.yeejoin.amos.component.robot.BadRequest;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.DateUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class BasicGridAcceptanceServiceImpl
		extends BaseService<BasicGridAcceptanceDto, BasicGridAcceptance, BasicGridAcceptanceMapper>
		implements IBasicGridAcceptanceService {

	@Autowired
	BasicGridAcceptanceMapper basicGridAcceptanceMapper;
	@Autowired
	HygfOnGridMapper onGridMapper;
	@Autowired
	HygfOnGridServiceImpl hygfOnGridServiceImpl;
	@Autowired
	PersonnelBusinessMapper personnelBusinessMapper;
	@Autowired
	WorkflowImpl workflow;
	@Autowired
	AcceptanceCheckItemMapper acceptanceCheckItemMapper;
	@Autowired
	AcceptanceRectificationOrderMapper acceptanceRectificationOrderMapper;
	@Autowired
	RegionalCompaniesMapper regionalCompaniesMapper;
	@Autowired
	WorkOrderMapper workOrderMapper;
	@Resource (type = RedisLockUtil.class)
	private RedisLockUtil redisLockUtil;
	@Autowired
	PeasantHouseholdMapper peasantHouseholdMapper;
	@Autowired
	private CommonServiceImpl commonService;

	private final String OK = "0";
	private final String PASS = "5";

	public Page<BasicGridAcceptanceDto> selectPage(Long regionCompanyId, Long amosDealerId, int current, int size,
			String projectAddress, String powerStationCode, String ownersName, String gridStatus,
			String gridConnectionTime, String formType) throws Exception {
		PageHelper.startPage(current, size);
		Map<String, Object> map = new HashMap<>();
		Date date = null;
//        if (StringUtils.isNotEmpty(gridConnectionTime)) {
//            date = DateUtil.formatStringToDate(gridConnectionTime, "yyyy-MM-dd HH:mm:ss");
//        }
		map.put("projectAddress", projectAddress);
		map.put("powerStationCode", powerStationCode);
		map.put("ownersName", ownersName);
		map.put("gridStatus", gridStatus);
		map.put("gridConnectionTime", gridConnectionTime);
		map.put("formType", formType);
		map.put("regionCompanyId", regionCompanyId);
		map.put("amosDealerId", amosDealerId);
		List<BasicGridAcceptanceDto> list = basicGridAcceptanceMapper.selectPageList(map);
		PageInfo<BasicGridAcceptanceDto> page = new PageInfo(list);
		Page<BasicGridAcceptanceDto> pageNew = new Page<>();
		pageNew.setCurrent(current);
		pageNew.setTotal(page.getTotal());
		pageNew.setSize(size);
		pageNew.setRecords(page.getList());
		return pageNew;
	}

	public HygfOnGrid saveEntity(HygfOnGrid grid) {
		if (grid.getSequenceNbr() != null) {
			onGridMapper.updateById(grid);
		} else {
			onGridMapper.insert(grid);
		}

		return grid;
	}

	@GlobalTransactional
	public HygfOnGrid saveAndCommit(HygfOnGrid grid, String userId) {

		BasicGridAcceptance basicGridAcceptance = basicGridAcceptanceMapper
				.selectOne(new LambdaQueryWrapper<BasicGridAcceptance>()
						.eq(BasicGridAcceptance::getWorkOrderPowerStationId, grid.getWorkOrderPowerStationId()));
		basicGridAcceptance.setGridStatus(GridStatusEnum.DSH.getCode());

		if (grid.getType() != null && "1".equals(grid.getType())) {
			// 执行工作流
			StandardDto standardDto = new StandardDto();
			standardDto.setTaskId(basicGridAcceptance.getNextTaskId());
			workflow.standard(basicGridAcceptance, standardDto, userId);

		} else {
			// 调用工作流执行第一个节点
			ProcessDto processDto = new ProcessDto();
			processDto.setProcessDefinitionKey("hygf_bwys");
			processDto.setBusinessKey(String.valueOf(basicGridAcceptance.getSequenceNbr()));
			StartProcessDto startProcessDto = new StartProcessDto();
			List<ProcessDto> process = new ArrayList<>();
			process.add(processDto);
			startProcessDto.setProcess(process);
			workflow.startProcess(basicGridAcceptance, startProcessDto, userId);

			// 线上验收
			LambdaUpdateWrapper<PeasantHousehold> up = new LambdaUpdateWrapper<>();
			up.set(PeasantHousehold::getConstructionState, ArrivalStateeEnum.并网中.getCode());
			long idsk = basicGridAcceptance.getPeasantHouseholdId();
			up.eq(PeasantHousehold::getSequenceNbr, idsk);
			peasantHouseholdMapper.update(null, up);

		}
		
		//防止重复提交
//		if (grid.getSequenceNbr() != null) {
//			onGridMapper.updateById(grid);
//		} else {
//			onGridMapper.insert(grid);
//		}
		LambdaQueryWrapper<HygfOnGrid> hog = new LambdaQueryWrapper<>();
		hog.eq(HygfOnGrid::getPeasantHouseholdId, grid.getPeasantHouseholdId());
		hygfOnGridServiceImpl.saveOrUpdate(grid,hog);
		
		basicGridAcceptanceMapper.updateById(basicGridAcceptance);

		//发起待办
//		commonService.buildTaskModel(buildBWYSTaskModel(grid, basicGridAcceptance));
		return grid;
	}

	private List<TaskModelDto> buildBWYSTaskModel(HygfOnGrid grid, BasicGridAcceptance basicGridAcceptance) {
		List<TaskModelDto> taskModelDtoList = new ArrayList<>();
		TaskModelDto taskModelDto = new TaskModelDto();
		taskModelDto.setFlowCode(basicGridAcceptance.getNextTaskId());
		taskModelDto.setFlowCreateDate(new Date());
		taskModelDto.setFlowStatus(FlowStatusEnum.TO_BE_PROCESSED.getCode());
		taskModelDto.setFlowStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
		taskModelDto.setPageType(null);
		taskModelDto.setExecuteUserIds(basicGridAcceptance.getNextExecuteUserIds());
		taskModelDto.setModel(grid);
		taskModelDto.setRelationId(basicGridAcceptance.getInstanceId());
		taskModelDto.setRoutePath(null);
		taskModelDto.setStartUserId(basicGridAcceptance.getRecUserId());
		taskModelDto.setStartUser(basicGridAcceptance.getRecUserName());
		taskModelDto.setStartDate(basicGridAcceptance.getRecDate());
		taskModelDto.setStartUserCompanyName(null);
		taskModelDto.setTaskName(basicGridAcceptance.getNextNodeName());
		taskModelDto.setTaskCode(String.valueOf(basicGridAcceptance.getWorkOrderId()));
		taskModelDto.setTaskType(BusinessTypeEnum.HYGF_BWYS.getCode());
		taskModelDto.setTaskTypeLabel(BusinessTypeEnum.HYGF_BWYS.getName());
		taskModelDto.setTaskStatus(TaskStatusEnum.UNDERWAY.getValue());
		taskModelDto.setTaskStatusLabel(TaskStatusEnum.UNDERWAY.getName());
//        taskModelDto.setTaskDesc();
//        taskModelDto.setTaskContent();
		taskModelDto.setNextExecuteUser(basicGridAcceptance.getNextExecutorIds());
		taskModelDtoList.add(taskModelDto);
		return taskModelDtoList;

	}

	public HygfOnGrid modifyEntity(HygfOnGrid grid) {
		onGridMapper.updateById(grid);
		return grid;
	}

	public Boolean deleteForBatch(Long[] sequenceNbrs) {
		if (Objects.isNull(sequenceNbrs) || sequenceNbrs.length == 0) {
			return false;
		}
		Boolean bool = Boolean.TRUE;
		Collection<HygfOnGrid> grids = onGridMapper.selectBatchIds(Arrays.asList(sequenceNbrs));
		for (HygfOnGrid x : grids) {
			x.setIsDelete(true);
			int num = onGridMapper.updateById(x);
			BasicGridAcceptance acceptance = basicGridAcceptanceMapper
					.selectOne(new LambdaQueryWrapper<BasicGridAcceptance>()
							.eq(BasicGridAcceptance::getWorkOrderPowerStationId, x.getWorkOrderPowerStationId()));
			acceptance.setIsDelete(true);
			int count = basicGridAcceptanceMapper.updateById(acceptance);
			if (0 == num || 0 == count) {
				bool = Boolean.FALSE;
				break;
			}
		}
		return bool;
	}

	@GlobalTransactional
	public void execute(AcceptanceCheckItem dto, String userId) {
		String lockName = String.format("LockName:executeWorkflow:%s", dto.getBasicGridAcceptanceId());
		Boolean isLocked = redisLockUtil.tryLock(lockName, lockName, 10, 1);
		if (BooleanUtils.isNotTrue(isLocked)) {
			throw new BadRequest("其他用户正在操作，请刷新后再试！");
		}
		try {
			// 查询并网审批信息
			BasicGridAcceptance basicGridAcceptanc = basicGridAcceptanceMapper.selectById(dto.getBasicGridAcceptanceId());
			String beforeAcceptanceStatus = basicGridAcceptanc.getAcceptanceStatus();
			String nextNodeKey = basicGridAcceptanc.getNextNodeKey();
			if (OK.equals(dto.getApprovalStatus())) {
				if (BasicGridAcceptancEnum.并网管理端工程审核.getCode().equals(nextNodeKey)) {
					basicGridAcceptanc.setGridStatus(GridStatusEnum.YWC.getCode());
					basicGridAcceptanc.setAcceptanceStatus(AcceptanceStatusEnum.待提交验收.getCode());
					// 并网时间
					LambdaUpdateWrapper<HygfOnGrid> upq = new LambdaUpdateWrapper();
					upq.eq(HygfOnGrid::getSequenceNbr, dto.getFonGridId());
					upq.set(HygfOnGrid::getGridConnectionTime, new Date());
					onGridMapper.update(null, upq);
					// 并网完成
					LambdaUpdateWrapper<PeasantHousehold> up = new LambdaUpdateWrapper<>();
					up.set(PeasantHousehold::getConstructionState, ArrivalStateeEnum.并网完成.getCode());
					long idsk = basicGridAcceptanc.getPeasantHouseholdId();
					up.eq(PeasantHousehold::getSequenceNbr, idsk);
					peasantHouseholdMapper.update(null, up);

				} else {
					AcceptanceStatusEnum acceptanceStatus = AcceptanceStatusEnum.getAcceptanceStatusByKey(nextNodeKey, dto.getApprovalStatus());
					if (acceptanceStatus == null) {
						// 说明工作流节点状态执行错误
						throw new BadRequest("其他用户正在操作，请刷新后再试！");
					}
					basicGridAcceptanc
							.setAcceptanceStatus(AcceptanceStatusEnum.getNodeByKey(nextNodeKey, dto.getApprovalStatus()));
				}

			} else {
				if (BasicGridAcceptancEnum.并网管理端工程审核.getCode().equals(nextNodeKey)) {
					basicGridAcceptanc.setGridStatus(GridStatusEnum.WTG.getCode());
					basicGridAcceptanc.setAcceptanceStatus(AcceptanceStatusEnum.getNodeByKey(nextNodeKey, dto.getApprovalStatus()));
				}
				// 投融/法务/工程/线下验收审核不通过
				else if (BasicGridAcceptancEnum.管理端投融审核.getCode().equals(nextNodeKey)
						|| BasicGridAcceptancEnum.管理端法务审核.getCode().equals(nextNodeKey)
						|| BasicGridAcceptancEnum.管理端工程审核.getCode().equals(nextNodeKey)
						|| BasicGridAcceptancEnum.管理端工程线下验.getCode().equals(nextNodeKey)) {
					AcceptanceRectificationOrder rectificationOrder = new AcceptanceRectificationOrder();
					try {
						WorkOrder workOrder = workOrderMapper.selectById(basicGridAcceptanc.getWorkOrderId());
						RegionalCompanies regionalCompanies = regionalCompaniesMapper
								.selectRegionName(workOrder.getRegionCompanyId());
						String code = NumberUtil.getCode(CodeEnum.整改单.getCode(), regionalCompanies.getCompanyCode(),
								regionalCompanies.getRegionalAddress());
						rectificationOrder.setRectificationOrderCode(code);
						rectificationOrder.setWorkOrderId(basicGridAcceptanc.getWorkOrderId());
						rectificationOrder.setWorkOrderPowerStationId(basicGridAcceptanc.getWorkOrderPowerStationId());
						rectificationOrder.setPeasantHouseholdId(basicGridAcceptanc.getPeasantHouseholdId());
						rectificationOrder.setProblemDescription(dto.getComment());
						rectificationOrder.setRectificationStatus(String.valueOf(RectificationStatusEnum.待整改.getCode()));
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
					acceptanceRectificationOrderMapper.insert(rectificationOrder);
					basicGridAcceptanc
							.setAcceptanceStatus(AcceptanceStatusEnum.getNodeByKey(nextNodeKey, dto.getApprovalStatus()));
				} else {
					AcceptanceStatusEnum acceptanceStatus = AcceptanceStatusEnum.getAcceptanceStatusByKey(nextNodeKey, dto.getApprovalStatus());
					if (acceptanceStatus == null) {
						// 说明工作流节点状态执行错误
						throw new BadRequest("其他用户正在操作，请刷新后再试！");
					}
					basicGridAcceptanc
							.setAcceptanceStatus(AcceptanceStatusEnum.getNodeByKey(nextNodeKey, dto.getApprovalStatus()));
				}
			}

			if (AcceptanceStatusEnum.线下验收不通过.getCode().equals(basicGridAcceptanc.getAcceptanceStatus())) {
				if (AcceptanceStatusEnum.线下验收完成.getCode().equals(beforeAcceptanceStatus)) {
					throw new BadRequest("验收状态已更改为线下验收不通过，请刷新后再试！");
				}
			}

			if (nextNodeKey.equals(BasicGridAcceptancEnum.管理端工程线下验.getCode())) {
				dto.setWorkOrderId(basicGridAcceptanc.getWorkOrderId());
				dto.setWorkOrderPowerStationId(basicGridAcceptanc.getWorkOrderPowerStationId());
				dto.setPeasantHouseholdId(basicGridAcceptanc.getPeasantHouseholdId());
				acceptanceCheckItemMapper.insert(dto);
			}
			// 执行工作流
			StandardDto standardDto = new StandardDto();
			standardDto.setComment(dto.getComment());
			standardDto.setResult(dto.getApprovalStatus());
			standardDto.setTaskId(basicGridAcceptanc.getNextTaskId());
			VariableDto variable = new VariableDto();
			variable.setApprovalStatus(dto.getApprovalStatus());
			variable.setComment(dto.getComment());
			variable.setOperationTime(dto.getOperationTime());
			variable.setOperator(dto.getOperator());
			standardDto.setVariable(variable);
			BasicGridAcceptance workBasicGridAcceptance = workflow.standard(basicGridAcceptanc, standardDto, userId);

			if (workBasicGridAcceptance.getNextNodeKey().equals(BasicGridAcceptancEnum.管理端工程线下验.getCode())) {
				// 线下验收
				LambdaUpdateWrapper<PeasantHousehold> up = new LambdaUpdateWrapper<>();
				up.set(PeasantHousehold::getConstructionState, ArrivalStateeEnum.线下验收.getCode());
				long idsk = basicGridAcceptanc.getPeasantHouseholdId();
				up.eq(PeasantHousehold::getSequenceNbr, idsk);
				peasantHouseholdMapper.update(null, up);
			}

			// 验收完成
			System.out.println("验收完成===============================" + workBasicGridAcceptance.getNextTaskId());
			System.out.println("验收完成888888===============================" + workBasicGridAcceptance.getAcceptanceStatus());

			if ("10".equals(workBasicGridAcceptance.getAcceptanceStatus())) {
				// 更新状态
				LambdaUpdateWrapper<PeasantHousehold> up = new LambdaUpdateWrapper<>();
				up.set(PeasantHousehold::getConstructionState, ArrivalStateeEnum.验收完成.getCode());
				long idsk = basicGridAcceptanc.getPeasantHouseholdId();
				up.eq(PeasantHousehold::getSequenceNbr, idsk);
				peasantHouseholdMapper.update(null, up);

			}

			basicGridAcceptanceMapper.updateById(workBasicGridAcceptance);
		} finally {
			redisLockUtil.releaseLock(lockName);
		}
	}

}
