package com.palmnest.service.dinner.manager.impl;

import com.palmnest.application.bean.Page;
import com.palmnest.application.core.util.RegularPattern;
import com.palmnest.application.core.util.StringUtil;
import com.palmnest.application.dto.ConsumerDto;
import com.palmnest.application.dto.output.ElementDto;
import com.palmnest.dao.ElementGroupDao;
import com.palmnest.dao.dinner.*;
import com.palmnest.dao.estateserve.AppUserDao;
import com.palmnest.dao.estateserve.VirtualArchDao;
import com.palmnest.model.dinner.*;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.model.property.VirtualArchitecture;
import com.palmnest.service.ElementGroupManager;
import com.palmnest.service.dinner.manager.ConsumerManager;
import com.palmnest.service.estateserve.AppUserManager;
import com.palmnest.service.impl.GenericManagerImpl;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 订餐用户manager实现类
 *
 * @author longmeizhen
 */
@Slf4j
@Service("consumerManager")
public class ConsumerManagerImpl extends GenericManagerImpl<Consumer, Long> implements ConsumerManager {


	private ConsumerDao consumerDao;

	@Autowired
	public void setConsumerDao(ConsumerDao consumerDao) {
		this.consumerDao = consumerDao;
		this.dao = consumerDao;
	}

	@Autowired
	private OrderDinnerDao        orderDinnerDao;
	@Autowired
	private MealCarDao            mealCarDao;
	@Autowired
	private VirtualArchDao        virtualArchDao;
	@Autowired
	private IntegralRecodeInfoDao integralRecodeInfoDao;
	@Autowired
	private OrderDinnerInfoDao    orderDinnerInfoDao;
	@Autowired
	private AppUserDao            appUserDao;
	@Autowired
	private ElementGroupManager elementGroupManager;
	@Autowired
	private AppUserManager        appUserManager;
	@Autowired
	private DeptDao               deptDao;

	/**
	 * 根据openId获取用户
	 *
	 * @param orgId
	 * @param openId
	 * @return
	 */
	@Override
	public Consumer getConsumerByOpenId(String orgId, String openId) {
		return consumerDao.getConsumerByOpenId(orgId, openId);
	}
	/**
	 * 根据用户名密码查找相应的用户
	 * @param orgId
	 * @param loginName
	 * @param password
	 * @return
	 */
//	@Override
//	public Consumer getConsumerByLoginName(String orgId, String loginName,
//			String password) {
//		return consumerDao.getConsumerByLoginName(orgId, loginName, password);
//	}

	/**
	 * 导入
	 */
	@Override
	public Map<String, Object> importConsumer(InputStream ins, String orgId, String virId) {
		Map<String, Object> retMap    = new HashMap<String, Object>();
		List<Object>        userList  = new ArrayList<Object>();
		List<Object>        usersList = new ArrayList<Object>();
		int                 bugCount  = 0;
		StringBuffer        bugStr    = new StringBuffer("");
		StringBuffer        countStr  = new StringBuffer("");
		List<String>        mobiles   = new ArrayList<String>();
		Sheet               sheet     = null;
		try {
			Workbook workbook = WorkbookFactory.create(ins);
			sheet = workbook.getSheet("Consumer");
		} catch (Exception e) {
			bugCount++;
			bugStr.append("模板格式有问题，请下载最新的模板");
		}
		try {
			if (sheet == null) {
				bugCount++;
				bugStr.append("模板格式有问题，请下载最新的模板");
			} else {
				int rows = sheet.getLastRowNum();
				//如果大于2000行数据
				if (rows > 20000) {
					bugCount++;
					bugStr.append("数据量太大，不能大于2w行");
				} else if (rows < 1) {
					bugCount++;
					bugStr.append("数据为空，请录入账单信息");
				} else {
					for (int i = 1; i <= rows; i++) {
						if (sheet.getRow(i) == null) {
							continue;
						}
						if (sheet.getRow(i).getCell(0) == null) {
							bugStr.append("第" + i + "行第1列数据有问题，请检查，问题：姓名必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(0).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(0).getStringCellValue())) {
							bugStr.append("第" + i + "行第1列数据有问题，请检查，问题：姓名必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String userName = sheet.getRow(i).getCell(0).getStringCellValue();


						if (sheet.getRow(i).getCell(1) == null) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：手机号码必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(1).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(1).getStringCellValue())) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：手机号码必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String  mobile = sheet.getRow(i).getCell(1).getStringCellValue();
						boolean bool   = RegularPattern.isMobileNO(mobile);//验证手机格式是否正确
						if (StringUtils.isNotEmpty(mobile) && !bool) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "手机号码格式有问题，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						AppUser cons = appUserDao.getAppUsersByPhoneAndOrg(mobile, orgId, "");
						if (cons != null && !"-1".equals(cons.getUserType())) {
							countStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "该手机号码已存在账号，请导出系统模板匹配录入<br/>");
							mobiles.add(mobile);
						}

						String email = "";
						if (sheet.getRow(i).getCell(2) != null) {
							sheet.getRow(i).getCell(2).setCellType(Cell.CELL_TYPE_STRING);
							email = sheet.getRow(i).getCell(2).getStringCellValue();
						}
						//检验邮箱格式

						if (StringUtil.isNotEmpty(email) && !RegularPattern.checkEmail(email)) {
							bugStr.append("第" + i + "行第3列数据有问题，请检查，问题：邮箱格式有误，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}


						String sex = "";
						if (sheet.getRow(i).getCell(3) != null) {
							sheet.getRow(i).getCell(3).setCellType(Cell.CELL_TYPE_STRING);
							sex = sheet.getRow(i).getCell(3).getStringCellValue();
							if ("男".equals(sex)) {
								sex = "1";
							} else if ("女".equals(sex)) {
								sex = "2";
							}
						}

						Integer    virtualArchId = null;
						String     virName       = "";
						String     deptName      = "";
						Department dept          = null;


						if (sheet.getRow(i).getCell(4) == null) {
							bugStr.append("第" + i + "行第5列数据有问题，请检查，问题：企业名称必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(4).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(4).getStringCellValue())) {
							bugStr.append("第" + i + "行第5列数据有问题，请检查，问题：企业名称必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						virName = sheet.getRow(i).getCell(4).getStringCellValue();
						List<VirtualArchitecture> virList = virtualArchDao.getVirByName(virName, orgId);
						if (null != virList && virList.size() > 0 && null != virList.get(0)) {
							virtualArchId = virList.get(0).getId();
							if (sheet.getRow(i).getCell(5) != null) {
								sheet.getRow(i).getCell(5).setCellType(Cell.CELL_TYPE_STRING);
								deptName = sheet.getRow(i).getCell(5).getStringCellValue();
							}
							if (StringUtil.isNotEmpty(deptName)) {
								dept = deptDao.getDeptByName(virtualArchId + "", deptName);
								if (dept == null || dept.getId() == null) {
									bugStr.append("第" + i + "行第6列数据有问题，请检查，问题：找不到该部门，请导出系统模板匹配录入<br/>");
									bugCount++;
									continue;
								}
							}
						} else {
							bugStr.append("第" + i + "行第5列数据有问题，请检查，问题：找不到该企业，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}

						if (cons != null && "-1".equals(cons.getUserType())) {
							if (StringUtils.isNotEmpty(orgId)) {
								cons.setOrganizationId(Integer.parseInt(orgId));
							}
							cons.setIsEnabled("1");
							cons.setDepartmentName(deptName);
							cons.setUserName(userName);
							cons.setUserMobile(mobile);
							cons.setEmail(email);
							cons.setUserSex(sex);
							cons.setWxUserId(null);
							cons.setVirtualArchId(virtualArchId);
							cons.setVirtualArchName(virName);
							if (null != dept) {
								cons.setDepartmentId(Integer.parseInt(dept.getId().toString()));
							}

							int count = 0;
							if (userList != null && userList.size() > 0) {
								for (int k = 0; k < userList.size(); k++) {
									AppUser users = (AppUser) userList.get(k);
									if (users != null) {
										if (mobile.equals(users.getUserMobile())) {
											count++;
										}
									}
								}
							}
							if (count > 0) {
								bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "手机号码在文件中重复，请导出系统模板匹配录入<br/>");
								bugCount++;
								continue;
							} else if (!mobiles.contains(mobile)) {
								userList.add(cons);
							} else if (mobiles.contains(mobile)) {
								usersList.add(cons);
							}
						} else {
							AppUser user = new AppUser();
							if (StringUtils.isNotEmpty(orgId)) {
								user.setOrganizationId(Integer.parseInt(orgId));
							}
							user.setVirtualArchId(virtualArchId);
							user.setVirtualArchName(virName);
							if (null != dept) {
								user.setDepartmentId(Integer.parseInt(dept.getId().toString()));
							}
							user.setIsEnabled("1");
							user.setDepartmentName(deptName);
							user.setUserName(userName);
							user.setUserMobile(mobile);
							user.setUserSex(sex);
							user.setEmail(email);
							int count = 0;
							if (userList != null && userList.size() > 0) {
								for (int k = 0; k < userList.size(); k++) {
									AppUser users = (AppUser) userList.get(k);
									if (users != null) {
										if (mobile.equals(users.getUserMobile())) {
											count++;
										}
									}
								}
							}
							if (count > 0) {
								bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "手机号码在文件中重复，请导出系统模板匹配录入<br/>");
								bugCount++;
								continue;
							} else if (!mobiles.contains(mobile)) {
								userList.add(user);
							} else if (mobiles.contains(mobile)) {
								usersList.add(user);
							}
						}
					}
				}
			}
			retMap.put("bugCount", bugCount);
			retMap.put("countStr", countStr);
			retMap.put("bugStr", bugStr.toString());
			retMap.put("userList", userList);
			retMap.put("usersList", usersList);
			retMap.put("okCount", userList.size());
			return retMap;

		} catch (Exception e) {
			log.error(e.getMessage());
			retMap.put("bugCount", bugCount);
			retMap.put("countStr", countStr);
			retMap.put("bugStr", bugStr.toString());
			retMap.put("userList", userList);
			retMap.put("usersList", usersList);
			retMap.put("okCount", userList.size());
			e.printStackTrace();
			return retMap;
		}
	}
//	@Override
//	public List<Consumer> getUserByLoginName(String orgId, String loginName) {
//		return consumerDao.getUserByLoginName(orgId, loginName);
//	}

	@Transactional
	public String saveImportUser(List<AppUser> list, String userId)
			throws Exception {
		String res = "";
		try {
			for (int i = 0; i < list.size(); i++) {
				AppUser cust = list.get(i);
				if (cust.getId() == null) {
					cust.setCreateTime(new Date());
					cust.setCreator(userId);
					cust.setIsEnabled("1");
					cust.setStatus("1");
					cust.setIsBinding(0);
					cust.setIsLogin(0);
					cust.setUserNumber(String.format("%08d", appUserManager.getUserNumer()));
				} else {
					cust.setModifier(userId);
//					AppUser user=appUserManager.get(cust.getId());
					if (!StringUtil.isNotEmpty(cust.getUserNumber())) {
						cust.setUserNumber(String.format("%08d", appUserManager.getUserNumer()));
					}
				}
				cust.setUserType("0");
				appUserManager.saveOrUpdateAppUser(cust);
				if (null != cust.getIntegral() && 0 != cust.getIntegral().intValue()) {
					String exchangeIntegral = String.valueOf(cust.getIntegral());
					IntegralRecodeInfo recode = new IntegralRecodeInfo(userId, 1, cust.getUserName(), cust.getUserMobile()
							, 0, cust.getIntegral(), new Date(), exchangeIntegral, cust.getOrganizationId().toString(), cust.getId().toString());
					integralRecodeInfoDao.save(recode);
				}
			}
			res = "SUCCESS";
		} catch (Exception e) {
			log.error("ConsumerManagerImpl/saveImportUser:" + e.getMessage());
			e.printStackTrace();
			res = "ConsumerManagerImpl/saveImportUser:" + e.getMessage();
			throw new Exception(e);
		}
		return res;
	}

	/**
	 * 判断该用户还能否提交订单
	 *
	 * @param cons
	 * @return
	 */
	@Override
	public int isConsPower(Consumer cons, int type) {
		if ("2".equals(cons.getRoleType())) {//如果是普通用户，就需要查询是否有下过订单
			List<OrderDinner> list = orderDinnerDao.findByCons(cons.getId().toString(), cons.getOrgId(), "1,2,3");
			if (list != null && list.size() > 0) {
				return 0;
			}
			if (type == 1) {//加入购物车的时候才需要加这个判断
				List<MealCar> mealcarList = mealCarDao.findMealCarListByConsId(cons.getId().toString(), "");
				if (mealcarList != null && mealcarList.size() > 0) {
					return 0;
				}
			}
		}
		return 1;
	}

	/**
	 * @param loginName登录名
	 * @param userName姓名
	 * @param roleType类型1管理员2普通用户
	 * @return
	 */
	@Override
	public Page findList(Map<String, Object> paramets, int pageSize, int pageNo) {
		return consumerDao.findList(paramets, pageSize, pageNo);
	}
	
	
	/**
	 * @param loginName登录名
	 * @param userName姓名
	 * @param roleType类型1管理员2普通用户
	 * @return
	 */
	@Override
	public List<Map<String, Object>> findListForReport(Map<String, Object> paramets) {
		return consumerDao.findListForReport(paramets);
	}
	

	@Override
	public Page findEmployeeList(Map<String, Object> paramets, int pageSize, int pageNo) {
		return consumerDao.findEmployeeList(paramets, pageSize, pageNo);
	}

	@Override
	public Consumer getConsumerByMobile(String orgId, String mobile) {

		return consumerDao.getConsumerByMobile(orgId, mobile);
	}

	/**
	 * 获取所有有效的代订类型的账号以及管理员账号
	 *
	 * @param orgId
	 * @return
	 */
	@Override
	public Map<String, List<ConsumerDto>> getConsByOrgId(String orgId, String time) {
		Map<String, List<ConsumerDto>> mapList    = new HashMap<String, List<ConsumerDto>>();
		List<ConsumerDto>              haveDto    = new ArrayList<ConsumerDto>();
		List<ConsumerDto>              notHaveDto = new ArrayList<ConsumerDto>();
		List<Consumer>                 list       = consumerDao.getConsByOrgId(orgId);
		mapList.put("haveOrderList", haveDto);
		mapList.put("notHaveOrderList", notHaveDto);
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Consumer    cons = list.get(i);
				ConsumerDto dto  = new ConsumerDto(cons.getId().toString(), cons.getUserName(), cons.getMobile());
				if (cons != null) {
					List<Map<String, Object>> orderList = orderDinnerInfoDao.getOrderInfoByTime(String.valueOf(cons.getId()), time);
					if (orderList != null && orderList.size() > 0) {
						dto.setIsOrdering(1);
						haveDto.add(dto);
					} else {
						dto.setIsOrdering(0);
						notHaveDto.add(dto);
					}
				}
			}
			mapList.put("haveOrderList", haveDto);
			mapList.put("notHaveOrderList", notHaveDto);
		}
		return mapList;
	}

	private List<ElementDto>  getAddress(Integer orgId){
		List<ElementDto> addressDtoList = elementGroupManager.getOrgElementGroupInfo(orgId, "dinnerAddress");
		Collections.sort(addressDtoList, new Comparator<ElementDto>() {
			@Override
			public int compare(ElementDto o1, ElementDto o2) {
				String name1 = o1.getId().toString();
				String name2 = o2.getId().toString();
				return name1.compareTo(name2);
			}
		});
		return addressDtoList;
	}

	@Override
	public Map<String, Object> importUserAddress(InputStream ins, String orgId) {
		Map<String, Object> retMap    = new HashMap<String, Object>();
		List<Object>        userList  = new ArrayList<Object>();
		int                 bugCount  = 0;
		StringBuffer        bugStr    = new StringBuffer("");
		StringBuffer        countStr  = new StringBuffer("");
		List<String>        mobiles   = new ArrayList<String>();
		Sheet               sheet     = null;

		try {
			Workbook workbook = WorkbookFactory.create(ins);
			sheet = workbook.getSheet("ConsumerAddress");
		} catch (Exception e) {
			bugCount++;
			bugStr.append("模板格式有问题，请下载最新的模板");
		}
		try {
			if (sheet == null) {
				bugCount++;
				bugStr.append("模板格式有问题，请下载最新的模板");
			} else {
				int rows = sheet.getLastRowNum();
				//如果大于2000行数据
				if (rows > 20000) {
					bugCount++;
					bugStr.append("数据量太大，不能大于2w行");
				} else if (rows < 1) {
					bugCount++;
					bugStr.append("数据为空，请录入账单信息");
				} else {

					List<ElementDto> addressList = getAddress(Integer.parseInt(orgId));

					for (int i = 1; i <= rows; i++) {
						if (sheet.getRow(i) == null) {
							continue;
						}
						if (sheet.getRow(i).getCell(0) == null) {
							bugStr.append("第" + i + "行第1列数据有问题，请检查，问题：姓名必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(0).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(0).getStringCellValue())) {
							bugStr.append("第" + i + "行第1列数据有问题，请检查，问题：姓名必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String userName = sheet.getRow(i).getCell(0).getStringCellValue();


						if (sheet.getRow(i).getCell(1) == null) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：手机号码必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(1).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(1).getStringCellValue())) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：手机号码必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String  mobile = sheet.getRow(i).getCell(1).getStringCellValue();
						boolean bool   = RegularPattern.isMobileNO(mobile);//验证手机格式是否正确
						if (StringUtils.isNotEmpty(mobile) && !bool) {
							bugStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "手机号码格式有问题，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						AppUser cons = appUserDao.getAppUsersByPhoneAndOrg(mobile, orgId, "1");
						if (cons != null && !"-1".equals(cons.getUserType())) {
							countStr.append("第" + i + "行第2列数据有问题，请检查，问题：" + mobile + "该手机号码已存在账号，请导出系统模板匹配录入<br/>");
							mobiles.add(mobile);
						}

						if (sheet.getRow(i).getCell(3) == null) {
							bugStr.append("第" + i + "行第4列数据有问题，请检查，问题：送餐地址必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(3).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(3).getStringCellValue())) {
							bugStr.append("第" + i + "行第4列数据有问题，请检查，问题：送餐地址必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String address = sheet.getRow(i).getCell(3).getStringCellValue();
						Long addressId = null;
						//判断该地址在不在系统内
						for(ElementDto el : addressList){
							if(!address.equals(el.getItemname())){
								continue;
							}
							addressId = el.getId();
							break;
						}
						if(null == addressId){
							bugStr.append("第" + i + "行第4列数据有问题，请检查，问题：送餐地址不在系统中，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						if (sheet.getRow(i).getCell(4) == null) {
							bugStr.append("第" + i + "行第5列数据有问题，请检查，问题：账户类型必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						sheet.getRow(i).getCell(4).setCellType(Cell.CELL_TYPE_STRING);
						if (StringUtils.isBlank(sheet.getRow(i).getCell(4).getStringCellValue())) {
							bugStr.append("第" + i + "行第5列数据有问题，请检查，问题：账户类型必填，请导出系统模板匹配录入<br/>");
							bugCount++;
							continue;
						}
						String roleTypeStr = sheet.getRow(i).getCell(4).getStringCellValue();
						Integer roleType = 2;
						if("个人账号".equals(roleTypeStr)){
							roleType=2;
						}else if("管理员".equals(roleTypeStr)){
							roleType=1;
						}else if("可被代订".equals(roleTypeStr)){
							roleType=3;
						}

						cons.setAddress(addressId.toString());
						cons.setRoleType(roleType.toString());
						userList.add(cons);
					}
				}
			}
			retMap.put("bugCount", bugCount);
			retMap.put("countStr", countStr);
			retMap.put("bugStr", bugStr.toString());
			retMap.put("userList", userList);
			retMap.put("okCount", userList.size());
			return retMap;

		} catch (Exception e) {
			log.error(e.getMessage());
			retMap.put("bugCount", bugCount);
			retMap.put("countStr", countStr);
			retMap.put("bugStr", bugStr.toString());
			retMap.put("userList", userList);
			retMap.put("okCount", userList.size());
			e.printStackTrace();
			return retMap;
		}
	}

}
