package com.palmnest.service.repair.impl;

import com.palmnest.application.CodeConstants;
import com.palmnest.application.bean.Page;
import com.palmnest.application.core.util.*;
import com.palmnest.application.dto.CommonDto;
import com.palmnest.application.dto.OrgDto;
import com.palmnest.application.dto.RepairUserDto;
import com.palmnest.application.dto.UserDto;
import com.palmnest.application.dto.input.RepairBillInputDto;
import com.palmnest.application.dto.output.*;
import com.palmnest.model.Element;
import com.palmnest.model.User;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.model.repair.*;
import com.palmnest.service.AppUserService;
import com.palmnest.service.ElementGroupManager;
import com.palmnest.service.UserManager;
import com.palmnest.service.estateserve.ScWxuserManager;
import com.palmnest.service.redis.BaseRedisService;
import com.palmnest.service.repair.*;
import com.palmnest.service.wechat.WeChatApiManager;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.InputStream;
import java.util.*;

@Service("repairBillService")
public class RepairBillServiceImpl implements RepairBillService {


	private static final String GCWX = "gcwx";

	@Autowired
	private ElementGroupManager        elementGroupManager;
	@Autowired
	private RepairBillManager          repairBillManager;
	@Autowired
	private RepairOperateRecordManager repairOperateRecordManager;
	@Autowired
	private BaseRedisService           baseRedisService;
	@Autowired
	private UserManager                userManager;
	@Autowired
	private ScWxuserManager            scWxuserManager;
	@Autowired
	private UserRepairTypeManager      userRepairTypeManager;
	@Autowired
	private RepairBillMaterialManager  repairBillMaterialManager;
	@Autowired
	private RepairBillCommentManager   repairBillCommentManager;
	@Autowired
	private RepairReturnVisitManager   repairReturnVisitManager;
	@Autowired
	private WeChatApiManager           weChatApiManager;
	@Autowired
	private AppUserService             appUserService;
	@Autowired
	private RepairConfigManager        repairConfigManager;

	public static String haveReceivingBillTempleteId    = PropertiesKit.readPropertiesValue("haveReceivingBillTempleteId", "wechat.properties");
	public static String billPaidTempleteId             = PropertiesKit.readPropertiesValue("billPaidTempleteId", "wechat.properties");
	public static String billCompletedCommentTempleteId = PropertiesKit.readPropertiesValue("billCompletedCommentTempleteId", "wechat.properties");
	public static String wechatDevelopId                = PropertiesKit.readPropertiesValue("wechatDevelopId", "wechat.properties");
	public static String host                           = PropertiesKit.readPropertiesValue("hostUrl", "wechat.properties");
	public static String wxCommentUrl                   = PropertiesKit.readPropertiesValue("wxCommentUrl", "wechat.properties");
	public static String wxRepairBillDetailUrl          = PropertiesKit.readPropertiesValue("wxRepairBillDetailUrl", "wechat.properties");

	public static String inprocessIndoorBillLimit  = PropertiesKit.readPropertiesValue("inprocessIndoorBillLimit", "app.properties");
	public static String inprocessOutdoorBillLimit = PropertiesKit.readPropertiesValue("inprocessOutdoorBillLimit", "app.properties");

	@Override
	@Transactional(rollbackFor = Exception.class)
	public RepairBill repair(RepairBillInputDto dto, MultipartHttpServletRequest request) throws Exception {
		String           picUrl     = "";
		Iterator<String> fileNames  = request.getFileNames();
		RepairBill       repairBill = new RepairBill();
		BeanUtils.copyProperties(repairBill, dto);
		while (fileNames.hasNext()) {
			MultipartFile multipartFile = request.getFile(fileNames.next());

			//获得文件原始名称
			InputStream stream   = null;
			String      fileExt  = null;
			String      fileName = "";
			if (multipartFile != null) {
				stream = multipartFile.getInputStream();
				fileName = multipartFile.getOriginalFilename();
				fileName = new String(fileName.getBytes(), "utf-8");
				fileExt = StringUtils.isNotEmpty(fileName) ? fileName
						.substring(fileName.lastIndexOf("."))
						: StringUtils.EMPTY;
			}

			FileUploadUtils fileUploadUtils = new FileUploadUtils();
			fileUploadUtils.init();
			String url = fileUploadUtils.uploadFile(stream, fileExt);
			picUrl += ";" + fileUploadUtils.fullVisitPath(url);
		}
		if (picUrl.length() > 1) {
			repairBill.setPicUrl(picUrl.substring(1));
		}
		//设置维修单状态：室内的单无审核，空置和公共区域的待审核
		//微信下单
		System.out.println("---------billFrom:" + request.getParameter("billFrom"));
		Integer billFrom = Integer.parseInt(request.getParameter("billFrom"));
		repairBill.setBillFrom(billFrom);
		if (billFrom.equals(CodeConstants.WECHAT)) {
			Element element  = elementGroupManager.getByItemCode(CodeConstants.INDOOR);
			Element element1 = elementGroupManager.getByItemCode(CodeConstants.WECHATREPAIR);
			repairBill.setRepairArea(element.getId());
			repairBill.setRepairWay(element1.getId());
			repairBill.setStatus(Integer.parseInt("2"));
		} else {
			Element element = elementGroupManager.getElementId(dto.getRepairArea());
			if (element.getItemcode().equals("indoor")) {

				repairBill.setStatus(Integer.parseInt("2"));
			} else {
				repairBill.setStatus(Integer.parseInt("1"));
			}
		}
		String userName = "";
		User   user     = null;
		WxUser wxUser   = null;
		if (billFrom.equals(CodeConstants.PC)) {
			user = (User) request.getSession().getAttribute("UserCache");
			userName = user.getUsername();
			repairBill.setBillUserId(user.getId());
			repairBill.setCreator(userName);
			repairBill.setModifier(userName);
			repairBill.setUserId(Integer.parseInt(user.getId().toString()));
		} else if (billFrom.equals(CodeConstants.ANDROID) || billFrom.equals(CodeConstants.iOS)) {
			userName = baseRedisService.get(request.getHeader("token"));
			user = userManager.getUserByUsername2(userName);
			repairBill.setBillUserId(user.getId());
			repairBill.setCreator(userName);
			repairBill.setModifier(userName);
			repairBill.setUserId(Integer.parseInt(user.getId().toString()));
		} else if (billFrom.equals(CodeConstants.WECHAT)) {
			String openId = request.getParameter("openId");
			wxUser = scWxuserManager.getScWxuserByOpenId(openId);
			if(StringUtils.isNotBlank(dto.getUserId())){
				repairBill.setUserId(Integer.parseInt(dto.getUserId()));
			}
			if (wxUser != null) {
				repairBill.setBillUserId(Long.parseLong(wxUser.getId() + ""));
				repairBill.setCreator(wxUser.getNickName());
				repairBill.setModifier(wxUser.getNickName());
				if (dto.getOrgId() == null) {
					repairBill.setOrgId(wxUser.getOrganizationId());
				}
				if((null == repairBill.getUserId() || (null != repairBill.getUserId() && 0 == repairBill.getUserId().intValue())) && null != wxUser.getUserId()){
					repairBill.setUserId(wxUser.getUserId());
				}
			}
		}
		String code = "";//编号不可重复
		while (true) {
			code = CodeGenerateUtils.generate(GCWX);
			RepairBill b = repairBillManager.findByCode(code);
			if (b == null) {
				break;
			}
		}
		repairBill.setCode(code);
		repairBill.setCreateTime(new Date());
		repairBill.setModifyTime(new Date());
		repairBill.setHasComment(1);
		repairBill.setHasReturnVisit(1);
		repairBill.setHasPaid(1);
		repairBill.setVersion(1);
		if (StringUtils.isNotEmpty(dto.getMeettingTime())) {
			Date meetingTime = DateHelper.parseToDate(dto.getMeettingTime(), DateHelper.DATE_STRING);
			repairBill.setMeetingTime(meetingTime);
		}
		//add dz 1030
		if (repairBill.getStatus() == 2) {
			RepairConfig s_con = repairConfigManager.getByOrgId(repairBill.getOrgId());
			if (s_con != null) {
				if (s_con.getRepair_type() == 2) {
					//派单模式
					repairBill.setStatus(22);
				}
			}
		}

		RepairBill          bill          = repairBillManager.save(repairBill);
		RepairOperateRecord operateRecord = new RepairOperateRecord(bill.getId(), userName, new Date());
		if (user != null) {
			operateRecord.setUserId(user.getId());
		} else if (wxUser != null) {
			operateRecord.setUserId(Long.parseLong(wxUser.getId() + ""));
		}
		operateRecord.setOperateType(CodeConstants.REPAIR);
//		operateRecord.setDescription("客户报修维修单");
		operateRecord.setDetail("客户报修维修单");
		repairOperateRecordManager.saveModel(operateRecord);
		//push(bill);
		return bill;
	}


	@Async
	public void push(RepairBill bill) throws Exception {
		//推送
		//需要审核的单 给有审核权限的人 推送
		if (bill != null && bill.getStatus().equals(CodeConstants.TO_AUDIT)) {
			List<User> users   = userManager.findByFunction(bill.getOrgId(), CodeConstants.AUDIT_PERMISSION);
			String     title   = "您有一个新的维修单待审核，请及时处理！";
			String     content = getPushContent(bill);
			PushMessageHelper helper=new PushMessageHelper();
			helper.pushMessage(bill.getId(), CodeConstants.AUDIT_PUSH_CODE, users, title, content);
		}
		//dz add 1108 待派单消息
		if (bill != null && bill.getStatus().equals(CodeConstants.TO_SEND)) {
			List<User> users   = userManager.findByFunction(bill.getOrgId(), CodeConstants.AUDIT_PERMISSION);
			String     title   = "您有一个维修单需要派单，请及时处理！";
			String     content = getPushContent(bill);
			PushMessageHelper helper=new PushMessageHelper();
			helper.pushMessage(bill.getId(), CodeConstants.AUDIT_PUSH_CODE, users, title, content);
		}
		//如果单不需要审核，则给工程人员推送可抢单消息
		if (bill != null && bill.getStatus().equals(CodeConstants.IS_SINGLE)) {
			List<User> users     = userRepairTypeManager.findBy(bill.getRepairType(), bill.getOrgId());
			//去除判断多少单在处理判断限制  2020-8-11 wuchangfu
			/*
			List<User> grabUsers = new ArrayList<User>();
			for (User user : users) {
				if (canGrabBillPush(user.getId())) {
					grabUsers.add(user);
				}
			}*/
			if (users != null && users.size() > 0) {
				String title   = "您有一个维修单可以抢单，快来抢单吧！";
				String content = getPushContent(bill);
				PushMessageHelper helper=new PushMessageHelper();
				helper.pushMessage(bill.getId(), CodeConstants.COMMON_PUSH_CODE, users, title, content);
			}
		}
	}

	private boolean canGrabBillPush(Long userId) {
		User user = userManager.findByFunctionAndUser(CodeConstants.GRAB_PERMISSION, userId);
		if (user == null) {
			return false;
		}
		Element          e1               = elementGroupManager.getByItemCode(CodeConstants.INDOOR);
		Element          e2               = elementGroupManager.getByItemCode(CodeConstants.PUBLIC);
		Element          e3               = elementGroupManager.getByItemCode(CodeConstants.VACANCYRATE);
		List<RepairBill> indoorBills      = repairBillManager.findBy(userId, e1.getId());
		List<RepairBill> publicBills      = repairBillManager.findBy(userId, e2.getId());
		List<RepairBill> vacancyRateBills = repairBillManager.findBy(userId, e3.getId());
		if (indoorBills.size() >= Integer.parseInt(inprocessIndoorBillLimit)) {
			return false;
		}
		if (publicBills.size() + vacancyRateBills.size() >= Integer.parseInt(inprocessOutdoorBillLimit)) {
			return false;
		}
		return true;
	}


	@Override
	public RepairBillDto convert(RepairBill bill) {
		RepairBillDto d = new RepairBillDto();
		RepairBillBaseDto dto = new RepairBillBaseDto(bill.getId(), bill.getCode(), bill.getRepairUser(), bill.getContactWay(),
				bill.getAddress(), bill.getDescription());
		dto.setCreateTime(DateHelper.formatDate(bill.getCreateTime(), DateHelper.DATE_STRING));
		Element e  = elementGroupManager.getElementId(bill.getRepairArea());
		Element e1 = elementGroupManager.getElementId(bill.getRepairType());
		Element e2 = elementGroupManager.getElementId(bill.getRepairWay());
		Element e3 = elementGroupManager.getElementId(bill.getRepairTypeDetail());
		dto.setRepairAreaName(e.getItemname());
		dto.setRepairTypeName(e1.getItemname());
		dto.setRepairWayName(e2.getItemname());
		dto.setRepairTypeId(e1.getId());
		if (e3 != null) {
			dto.setRepairTypeDetailId(e3.getId());
			dto.setRepairTypeDetailName(e3.getItemname());
		}
		dto.setPicUrl(bill.getPicUrl() == null ? "" : bill.getPicUrl());
		dto.setStatus(bill.getStatus());
		Long keepTime = DateHelper.getDateDiff(bill.getCreateTime(), bill.getEndTime() == null ? new Date() : bill.getEndTime(), 1);
		dto.setKeepTime(keepTime);
		if(null != bill.getMeetingTime()){
			dto.setMeetingTime(DateHelper.formatDate(bill.getMeetingTime(), DateHelper.DATE_STRING));
		}

		dto.setCompleteDesc(bill.getCompleteDesc());
		dto.setCompletePhotoUrl(bill.getCompletePhotoUrl());
		d.setBaseDto(dto);
		RepairDetailDto dDto = new RepairDetailDto();
		if (bill.getServiceUser() != null) {
			String[] us       = bill.getServiceUser().split(",");
			String   username = "";
			for (int i = 0; i < us.length; i++) {
				User user = userManager.get(Long.parseLong(us[i]));
				if (user != null) {
					username += user.getFullName() + ",";
				}
			}
			dDto.setServerUser(username);

		}
		Set<User> users = bill.getSupportUsers();
		if (users != null) {
			String supportUserNames = "";
			for (User u : users) {
				supportUserNames += "、" + u.getFullName();
			}
			if (supportUserNames.length() > 0) {
				dDto.setSupportUserNames(supportUserNames.substring(1));
			}
		}
		String                   materialName = "";
		List<RepairBillMaterial> materials    = repairBillMaterialManager.findBy(bill.getId());
		for (RepairBillMaterial material : materials) {
			materialName += "、" + material.getMaterialName() + "*" + material.getAmount();
		}
		if (materialName.length() > 0) {
			dDto.setMaterialName(materialName.substring(1));
		}
		dDto.setHasComment(bill.getHasComment());
		RepairBillComment comment = repairBillCommentManager.findBy(bill.getId());
		if (comment != null) {
			dDto.setStar(comment.getStar());
			if(StringUtils.isNotEmpty(comment.getServiceImpression())){
				String[] ids = comment.getServiceImpression().split(",");
				if(null != ids && ids.length > 0){
					String   im  = "";
					for (String id : ids) {
						if(StringUtils.isEmpty(id)){
							continue;
						}
						Element e5 = elementGroupManager.getElementId(Long.parseLong(id));
						im += "," + e5.getItemname();
					}
					if (im.length() > 0) {
						dDto.setServiceImpression(im.substring(1));
					}
				}
			}
			dDto.setDescription(comment.getDescription() == null ? "" : comment.getDescription());
		}
		RepairReturnVisit visit = repairReturnVisitManager.findBy(bill.getId());
		if (visit != null) {
			dDto.setVisitStar(visit.getStar());
			dDto.setVisitDescription(visit.getDescription() == null ? "" : visit.getDescription());
		}

		if (bill.getStatus().equals(CodeConstants.IN)) {
			RepairOperateRecord operateRecord = repairOperateRecordManager.findBy(bill.getId(), CodeConstants.PENDING);
			if (operateRecord != null) {
				String pendReason = "";
				if (StringUtils.isNotEmpty(operateRecord.getPendBillReason())) {
					String[] ids = operateRecord.getPendBillReason().split(",");
					if(null != ids && ids.length > 0){
						for (String id : ids) {
							if(StringUtils.isEmpty(id)){
								continue;
							}
							Element e6 = elementGroupManager.getElementId(Long.parseLong(id));
							pendReason += "," + e6.getItemname();
						}
					}
					if (StringUtils.isNotEmpty(pendReason)) {
						dDto.setPendReason(pendReason.substring(1));
					}
					dDto.setRemark(operateRecord.getDescription());
				}
				dDto.setExpectedTime(operateRecord.getExpectedTime());

			}
		}
		if (bill.getStatus().equals(CodeConstants.COMPLETED)) {
			//http://wx.palmnest.com/wechat/dist/index.html?id=45#/Evaluate
			dDto.setCommentUrl(host + wxCommentUrl.replaceAll("@id", bill.getId().toString()));
		}
		dDto.setHasPaid(bill.getHasPaid());
		if (bill.getHasPaid() != null && bill.getHasPaid().intValue() == 2) {
			dDto.setRepairCost(bill.getRepairCost());
		}
		d.setDetailDto(dDto);

		//操作记录

		List<RepairOperateRecord> records = repairOperateRecordManager.findBy(bill.getId());
		List<RepairOperateDto>    dtos    = new ArrayList<RepairOperateDto>();
		for (RepairOperateRecord record : records) {
			String detail = "";
			if (StringUtils.isNotEmpty(record.getDetail())) {
				detail = record.getDetail();
			}
			if (StringUtils.isNotEmpty(record.getDescription()) && !"null".equals(record.getDescription())) {
				detail = detail + ";" + record.getDescription();
			}

			RepairOperateDto dt = new RepairOperateDto(DateHelper.formatDate(record.getCreateTime(), DateHelper.DATE_TIME_STRING), detail, record.getDescription(),record.getIsConfirm());
			dtos.add(dt);
		}
		d.setOperateDto(dtos);
		return d;
	}

	@Override
	public RepairBillDto findById(Long id) {
		return this.convert(repairBillManager.get(id));
	}

	@Override
	public Page findPageByStatus(Integer status, String repairTypeIds, Long serviceUser, int pageSize, int pageNo, Integer orgId) {
		return repairBillManager.findPageByStatus(status, repairTypeIds, serviceUser, pageSize, pageNo, orgId);
	}

	@Override
	public Page findPageBy(Map<String, Object> params, int pageSize, int pageNo) {
		return repairBillManager.findPageBy(params, pageSize, pageNo);
	}

	@Override
	public List<CommonDto> findByTypeId(Long repairTypeId) {
		List<User>      users = userRepairTypeManager.findBy(repairTypeId);
		List<CommonDto> dtos  = new ArrayList<CommonDto>();
		for (User user : users) {
			dtos.add(new CommonDto(user.getId(), user.getFullName()));
		}
		return dtos;
	}

	@Override
	public List<CommonDto> findByTypeId(Long repairTypeId, Integer orgId) {
		List<User>      users = userRepairTypeManager.findBy(repairTypeId, orgId);
		List<CommonDto> dtos  = new ArrayList<CommonDto>();
		if (null != orgId) {
			for (User user : users) {
				dtos.add(new CommonDto(user.getId(), user.getFullName()));
			}
		}
		return dtos;
	}

	//add dz 1030
	@Override
	public List<RepairUserDto> getRepairUsers(Long repairTypeId, Integer orgId) {

		List<User>          users = userRepairTypeManager.findBy(repairTypeId, orgId);
		List<RepairUserDto> ls    = new ArrayList<>();

		if (null != orgId) {
			RepairConfig s_con   = repairConfigManager.getByOrgId(orgId);
			int          maxpass = 3;
			if (s_con != null) {
				maxpass = s_con.getMax_bills();
			}

			for (User user : users) {
				Integer c    = repairBillManager.findCountBy(CodeConstants.IN_PROGRESS, null, user.getId(), null);
				int     pass = 0;
				if (maxpass - c > 0) {
					pass = 1;
				}
				ls.add(new RepairUserDto(user.getId(), user.getFullName(), c, pass));
			}



			return ls;
		}
		return null;
	}

	@Override
	public Page findPageByRepairUser(Map<String, Object> params, int pageSize, int pageNo) {
		return repairBillManager.findPageByRepairUser(params, pageSize, pageNo);
	}

	@Override
	public void cancelOrder(String id, WxUser wxUser) {
	 RepairBill repairBill=	repairBillManager.get(Long.parseLong(id));
	 if(null != repairBill){
	 	//当订单为待审核、待取消、待派单的时候订单可以取消
	 	if(CodeConstants.IS_SINGLE.intValue() == repairBill.getStatus().intValue() ||
				CodeConstants.TO_SEND.intValue() == repairBill.getStatus().intValue()||
				CodeConstants.TO_AUDIT.intValue() == repairBill.getStatus().intValue()){
			repairBill.setStatus(CodeConstants.CANCEL);
			repairBill.setModifier(wxUser.getNickName());
			repairBill.setModifyTime(new Date());
			repairBillManager.updateModel(repairBill);
			RepairOperateRecord operateRecord = new RepairOperateRecord(Long.parseLong(id), wxUser.getNickName(), new Date());
			operateRecord.setOperateType(CodeConstants.CANCEL_ORDER);
			operateRecord.setDetail( wxUser.getNickName()+"(微信端)取消订单");
			repairOperateRecordManager.saveModel(operateRecord);
		}
	 }
	}

	@Override
	public void cancelOrder(String id, User user) {
		RepairBill repairBill = repairBillManager.get(Long.parseLong(id));
		if (null != repairBill) {
			//当订单为待审核、待取消、待派单的时候订单可以取消
			if (CodeConstants.IS_SINGLE.intValue() == repairBill.getStatus().intValue() ||
					CodeConstants.TO_SEND.intValue() == repairBill.getStatus().intValue() ||
					CodeConstants.TO_AUDIT.intValue() == repairBill.getStatus().intValue()) {

				repairBill.setStatus(CodeConstants.CANCEL);
				repairBill.setModifier(user.getFullName());
				repairBill.setModifyTime(new Date());
				repairBillManager.updateModel(repairBill);
				RepairOperateRecord operateRecord = new RepairOperateRecord(Long.parseLong(id), user.getId(), user.getFullName(), new Date());
				operateRecord.setOperateType(CodeConstants.CANCEL_ORDER);
				operateRecord.setDetail(user.getFullName() + "(PC端)取消订单");
				repairOperateRecordManager.saveModel(operateRecord);

			}
		}
	}

	@Override
	public void audit(Long id, Integer operateType, User user) throws Exception {
		RepairBill bill = repairBillManager.get(id);
		if (operateType.intValue() == 1) {//接受
			bill.setStatus(CodeConstants.IS_SINGLE);//审核成功设置状态为可抢单
			//add dz 1101 
			RepairConfig s_con = repairConfigManager.getByOrgId(bill.getOrgId());
			if (s_con != null) {
				if (s_con.getRepair_type() == 2) {
					bill.setStatus(CodeConstants.TO_SEND);//审核成功设置状态为待派单
				}
			}

		} else if (operateType.intValue() == 2) {//拒绝
			bill.setStatus(CodeConstants.UNAUDIT);//审核拒绝设置状态为取消
			bill.setEndTime(new Date());//表示单已经完结
		}
		repairBillManager.updateModel(bill);
		RepairOperateRecord operateRecord = new RepairOperateRecord(id, user.getId(), user.getFullName(), new Date());
		operateRecord.setOperateType(CodeConstants.AUDIT);
		operateRecord.setDetail(user.getFullName() + "审核单");
		repairOperateRecordManager.saveModel(operateRecord);
		//auditPush(operateType, bill);

	}


	@Async
	public void auditPush(Integer operateType, RepairBill bill) throws Exception {
		//给发起人推送消息
		Thread.sleep(3000);
		Long userId = bill.getBillUserId();
		if (userId != null) {
			User sendUser = userManager.get(userId);
			if (sendUser != null) {
				String title = "您的维修单已审核通过";
				if (operateType.intValue() == 2) {
					title = "您的维修单申请已被拒绝";
				}
				String content = getPushContent(bill);
				PushMessageHelper helper=new PushMessageHelper();
				helper.pushMessage(bill.getId(), CodeConstants.COMMON_PUSH_CODE, Arrays.asList(sendUser), title, content);
			}
		}
		//add dz 1101 
		RepairConfig s_con = repairConfigManager.getByOrgId(bill.getOrgId());
		int          ot    = 1;
		if (s_con != null) {
			ot = s_con.getRepair_type();
		}
		//给对应维修类型人员推送可抢单消息
		if (operateType.intValue() == 1 && ot == 1) {
			List<User> users     = userRepairTypeManager.findBy(bill.getRepairType(), bill.getOrgId());
			//去除抢单通知 判断限制 2020-8-11 wuchangfu
			/*
			List<User> grabUsers = new ArrayList<User>();
			for (User user : users) {
				if (canGrabBillPush(user.getId())) {
					grabUsers.add(user);
				}
			}*/
			if (users != null && users.size() > 0) {
				String title   = "有维修单可以抢";
				String content = getPushContent(bill);
				PushMessageHelper helper=new PushMessageHelper();
				helper.pushMessage(bill.getId(), CodeConstants.COMMON_PUSH_CODE, users, title, content);
			}
		}
		if (operateType.intValue() == 1 && ot == 2) {
			List<User> users   = userManager.findByFunction(bill.getOrgId(), CodeConstants.AUDIT_PERMISSION);
			String     title   = "您有一个维修单需要派单，请及时处理！";
			String     content = getPushContent(bill);
			PushMessageHelper helper=new PushMessageHelper();
			helper.pushMessage(bill.getId(), CodeConstants.AUDIT_PUSH_CODE, users, title, content);
		}
	}

	@Override
	public String getPushContent(RepairBill bill) {
		Element e  = elementGroupManager.getElementId(bill.getRepairArea());
		Element e1 = elementGroupManager.getElementId(bill.getRepairType());

		return e.getItemname() + e1.getItemname() + "," + bill.getDescription();
	}


	@Override
	public String pendBillOvertimePush() throws Exception {
		List<RepairBill> bills = repairBillManager.findPendOvertime();
		if (bills != null && bills.size() > 0) {
			for (RepairBill bill : bills) {
				if (bill.getStatus().equals(CodeConstants.IN)) {

					String[] us = bill.getServiceUser().split(",");
					for (int i = 0; i < us.length; i++) {
						User user = userManager.get(Long.parseLong(us[i]));

						String title   = "您的单即将超时，请尽快处理";
						String content = getPushContent(bill);
						PushMessageHelper helper=new PushMessageHelper();
						helper.pushMessage(bill.getId(), CodeConstants.COMMON_PUSH_CODE, Arrays.asList(user), title, content);
					}

				}
			}
		}
		return null;
	}


	@Override
	public String grabBillOvertimePush() throws Exception {

		List<RepairBill> bills = repairBillManager.findSingleOvertime();

		if (bills != null && bills.size() > 0) {
			for (RepairBill bill : bills) {
				if (bill.getStatus().equals(CodeConstants.IS_SINGLE)) {
					//有管理维修单功能的人
					List<User> users = userManager.findByFunction(10, CodeConstants.MANAGE_PERMISSION);
//					System.out.println("管理抢单:"+users);
					//过滤对应维修类型的人
					List<User> users1 = userRepairTypeManager.findBy(bill.getRepairType(), bill.getOrgId());
//					System.out.println("管理抢单类型:"+users1);
					List<User> resultUsers = new ArrayList<User>();
					List<Long> ids         = new ArrayList<Long>();
					for (User user : users) {
						ids.add(user.getId());
					}
					for (User user1 : users1) {
						if (ids.contains(user1.getId())) {
							resultUsers.add(user1);
						}
					}
//					System.out.println("抢单超时:"+resultUsers);
					String title   = "有维修单已抢单超时，请尽快处理。";
					String content = getPushContent(bill);
					PushMessageHelper helper=new PushMessageHelper();
					helper.pushMessage(bill.getId(), CodeConstants.AUDIT_PUSH_CODE, resultUsers, title, content);
				}
			}
		}
		return null;
	}

	@Override
	public String automaticHighPraise() throws Exception {

		List<Integer> list  = repairBillManager.getAutomaticHighPraiseRepairData();
		for(Integer repairId : list){

			//看是否有评论记录
			RepairBillComment repairBillComment =  repairBillCommentManager.findBy(Long.parseLong(repairId.toString()));
			if(null != repairBillComment){
				repairBillComment.setStar(5); //工程维修工单完成状态24*7小时后自动五星好评
				repairBillCommentManager.updateModel(repairBillComment);
			}else{
				RepairBillComment saveRepairBillComment = new RepairBillComment();

				saveRepairBillComment.setBillId(Long.parseLong(repairId.toString()));
				saveRepairBillComment.setStar(5);
				saveRepairBillComment.setCreateTime(new Date());
				repairBillCommentManager.saveModel(saveRepairBillComment);
			}
			RepairBill repairBill=	repairBillManager.get(Long.parseLong(repairId.toString()));
			repairBill.setHasComment(2); //是否有评论
			repairBillManager.updateModel(repairBill);
		}

		return null;
	}


	@Override
	public String managePendBillPush() throws Exception {
		List<RepairBill> bills = repairBillManager.findManagePendOvertime();

		if (bills != null && bills.size() > 0) {
			for (RepairBill bill : bills) {
				if (bill.getStatus().equals(CodeConstants.IN)) {
					//有管理维修单功能的人
					List<User> users = userManager.findByFunction(10, CodeConstants.MANAGE_PERMISSION);
//					System.out.println("管理挂单超时:"+users);
					//过滤对应维修类型的人
					List<User> users1 = userRepairTypeManager.findBy(bill.getRepairType(), bill.getOrgId());
//					System.out.println("管理挂单类型:"+users1);
					List<User> resultUsers = new ArrayList<User>();
					List<Long> ids         = new ArrayList<Long>();
					for (User user : users) {
						ids.add(user.getId());
					}
					for (User user1 : users1) {
						if (ids.contains(user1.getId())) {
							resultUsers.add(user1);
						}
					}
//					System.out.println("管理挂单:"+resultUsers);
					String title   = "有维修单已挂单即将超时，请尽快处理。";
					String content = getPushContent(bill);
					PushMessageHelper helper=new PushMessageHelper();
					helper.pushMessage(bill.getId(), CodeConstants.AUDIT_PUSH_CODE, resultUsers, title, content);
				}
			}
		}
		return null;
	}

	@Override
	public RepairSumIndexDto findBy(String userName) {
		//如果是可抢单，则查找同维修类型的单
		//如果是其他状态，则查找自己名下的单
		User          user          = userManager.getUserByUsername2(userName);
		Long          userId        = user.getId();
		String        repairTypeIds = "";
		List<Element> types         = userRepairTypeManager.findByUser(userId);
		for (Element e : types) {
			if (e != null) {
				repairTypeIds += "," + e.getId();
			}
		}
		List<OrgDto> dtos  = appUserService.getUserOrgs(user.getId());
		Integer      orgId = null;
		if (null != dtos && dtos.size() > 0) {
			orgId = dtos.get(0).getId();
		}
		if (repairTypeIds.length() > 1) {
			repairTypeIds = repairTypeIds.substring(1);
		}
		Integer isSingleTotal   = repairBillManager.findCountBy(CodeConstants.IS_SINGLE, repairTypeIds, null, orgId);//可抢单
		Integer inProgressTotal = repairBillManager.findCountBy(CodeConstants.IN_PROGRESS, null, userId, orgId);//进行中
		Integer pendingTotal    = repairBillManager.findCountBy(CodeConstants.IN, null, userId, orgId);//挂单中
		//Integer pendingTotal    = repairBillManager.findCountBy(CodeConstants.TRANSFERED, null, userId, orgId);//转单中

		//200 --管理待处理去除已完成和已取消
		//300 --管理权限去除已完成和已取消,待审核

		Integer manageTotal     = 0;//管理
		UserDto userDto         = appUserService.convertDto(user);
		if (userDto.getAuditPermission().intValue() == 1 && userDto.getManagePermission().intValue() == 2) {
			manageTotal = repairBillManager.findCountBy(300, repairTypeIds, null, orgId);//管理;
		}
		if (userDto.getAuditPermission().intValue() == 2 && userDto.getManagePermission().intValue() == 1) {
			manageTotal = repairBillManager.findCountBy(CodeConstants.TO_AUDIT, repairTypeIds, null, orgId);//待审核;
		}
		if (userDto.getAuditPermission().intValue() == 2 && userDto.getManagePermission().intValue() == 2) {
			manageTotal = repairBillManager.findCountBy(200, repairTypeIds, null, orgId);//管理和审核;
		}
		RepairSumIndexDto dto = new RepairSumIndexDto();
		dto.setIsSingleTotal(isSingleTotal); //可抢单
		dto.setInProgressTotal(inProgressTotal);//进行中
		dto.setPendingTotal(pendingTotal);//挂单中
		dto.setManageTotal(manageTotal);//管理
		//待完成= 进行中(转单中和进行中)+挂单中 "当前登录账号的" 待完成维修工单，进行中、挂单中、转单中的工单数量

		//1-抢单模式 2-派单模式
		Integer waitCompleteTotal = inProgressTotal + pendingTotal; //默认派单模式
		RepairConfig s_con = repairConfigManager.getByOrgId(orgId);
		if(s_con.getRepair_type().equals(1)){
			waitCompleteTotal =  waitCompleteTotal+isSingleTotal; //进行中+可抢单;
		}
		dto.setWaitCompleteTotal(waitCompleteTotal);

		return dto;
	}

	@Override
	public RepairSendUserDataDto getSendUserData(String userName) {

		User          user          = userManager.getUserByUsername2(userName);
		Long          userId        = user.getId();
		List<Map<String,Object>> list = repairBillManager.getSendUserData(userId.intValue());

		RepairSendUserDataDto dto = new RepairSendUserDataDto();
		if(null != list && list.size()>=1){
			Map<String,Object>  map =  list.get(0);
			if(map.containsKey("sendBillIds") && null != map.get("sendBillIds") && StringUtils.isNotEmpty(map.get("sendBillIds").toString())){
				dto.setSendBillIds(map.get("sendBillIds").toString());
			}

			if(map.containsKey("sendCount")){
				dto.setSendCount(Integer.valueOf(map.get("sendCount").toString()));
			}
		}

		return  dto;
	}


	@Async
	@Override
	public void pushMessage(Long id, String code, String title, String content, List<User> users) throws Exception {
		PushMessageHelper helper=new PushMessageHelper();
		helper.pushMessage(id, code, users, title, content);
	}


	@Async
	@Override
	public void pushWechatTemplateMsg(RepairBill bill, Integer type) {
		//推送模板消息 type类型 1.抢单后给发起维修人推送消息  2.付款成功后给发起维修人推送消息 3.单完成后给维修人员推送消息
		if (bill.getBillFrom() != null && bill.getBillFrom().intValue() != 2) {
			return;
		}
		Map<String, String> params     = new HashMap<String, String>();
		String              developId  = wechatDevelopId;
		String              templateId = "";
		Integer             wxUserId   = null;
		String              url        = "";
		if (bill.getBillUserId() != null) {
			wxUserId = Integer.valueOf(bill.getBillUserId() + "");
		}
		String   username  = "";
		String   userphone = "";
		String[] us        = bill.getServiceUser().split(",");
		for (int i = 0; i < us.length; i++) {
			User user = userManager.get(Long.parseLong(us[i]));
			if (user != null) {
				username += user.getFullName() + ",";
				userphone += user.getTelephone() + ",";
			}
		}

		String content = "";
		if (type.intValue() == 1) {
			templateId = haveReceivingBillTempleteId;
			params.put("first", "您的维修单已接收到啦！请稍等喔！");
			params.put("keyword1", DateHelper.formatDate(bill.getModifyTime(), DateHelper.DATE_STRING));
			params.put("keyword2", username);
			params.put("keyword3", userphone);
			params.put("remark", "工程小哥正排除万难赶过去了喔！");
			url = host + wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
			content = "温馨提示，您的维修单已收到，工程小哥：" + username
					+ "  将为您服务，联系电话：" + userphone
					+ "，查看详情请<a href='" + url + "'>点击这里</a>";
		} else if (type.intValue() == 2) {
			templateId = billPaidTempleteId;
			params.put("first", "尊敬的客户，您的工程维修单已付款成功！");
			params.put("keyword1", this.getPushContent(bill));
			params.put("keyword2", bill.getRepairCost().toString());
			params.put("keyword3", DateHelper.formatDate(bill.getModifyTime(), DateHelper.DATE_STRING));
			params.put("remark", "您的满意是我们孜孜不倦的追求！");
			url = host + wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
			content = "温馨提示，您的维修单已付款成功！付款金额：<a color=#70DB93>" + bill.getRepairCost().toString()
					+ "</a>，感谢您的支持"
					+ "</a>，查看详情请<a href='" + url + "'>点击这里</a>";
		} else if (type.intValue() == 3) {
			templateId = billCompletedCommentTempleteId;
			params.put("first", "您的报修问题，已经为您处理完毕");
			params.put("keyword1", this.getPushContent(bill));
			params.put("keyword2", bill.getDescription());
			params.put("remark", "请您对此次工程小哥进行评价！");
			url = host + wxCommentUrl.replaceAll("@id", bill.getId().toString());
			//如果已经评价完成则到详情页
			if (bill.getHasComment() != null && bill.getHasComment().intValue() == 2) {
				url = host + wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
			}
			content = "温馨提示，您的维修单已为您处理完毕！请您对此次工程小哥进行评价！"
					+ "<a href='" + url + "'>点击这里评价</a>";
		}
		//weChatApiManager.sendTemplateWithOpenId(developId, templateId, url, wxUserId, params);
		weChatApiManager.sendServiceWithOpenId(developId, wxUserId, content);
	}

	@Async
	@Override
	public void pushServiceMsg(RepairBill bill, Integer type) {
		//推送模板消息 type类型 1.抢单后给发起维修人推送消息  2.付款成功后给发起维修人推送消息 3.单完成后给维修人员推送消息
		if (bill.getBillFrom() != null && bill.getBillFrom().intValue() != 2) {
			return;
		}
		Map<String, String> params     = new HashMap<String, String>();
		String              developId  = wechatDevelopId;
		String              templateId = "";
		Integer             wxUserId   = null;
		String              url        = "";
		if (bill.getBillUserId() != null) {
			wxUserId = Integer.valueOf(bill.getBillUserId() + "");
		}
		//User user = userManager.get(bill.getServiceUser());
//		if(type.intValue() == 1) {
//			templateId = haveReceivingBillTempleteId;
//			params.put("first", "您的维修单已接收到啦！请稍等喔！");
//			params.put("keyword1", DateHelper.formatDate(bill.getModifyTime(), DateHelper.DATE_STRING));
//			params.put("keyword2", user.getFullName());
//			params.put("keyword3", user.getTelephone());
//			params.put("remark", "工程小哥正排除万难赶过去了喔！");
//			url=host+wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
//		}else if(type.intValue() == 2) {
//			templateId = billPaidTempleteId;
//			params.put("first", "尊敬的客户，您的工程维修单已付款成功！");
//			params.put("keyword1", this.getPushContent(bill));
//			params.put("keyword2", bill.getRepairCost().toString());
//			params.put("keyword3", DateHelper.formatDate(bill.getModifyTime(), DateHelper.DATE_STRING));
//			params.put("remark", "您的满意是我们孜孜不倦的追求！");
//			url=host+wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
//		}else if(type.intValue() == 3) {
//			templateId = billCompletedCommentTempleteId;
//			params.put("first", "您的报修问题，已经为您处理完毕");
//			params.put("keyword1", this.getPushContent(bill));
//			params.put("keyword2", bill.getDescription());
//			params.put("remark", "请您对此次工程小哥进行评价！");
//			url=host+wxCommentUrl.replaceAll("@id", bill.getId().toString());
//			//如果已经评价完成则到详情页
//			if(bill.getHasComment() != null && bill.getHasComment().intValue() == 2) {
//				url =  host+wxRepairBillDetailUrl.replaceAll("@id", bill.getId().toString());
//			}
//		}
		//weChatApiManager.sendServiceWithOpenId(developId, wxUserId);
	}


}
