package com.goafanti.techproject.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.AdminMapper;
import com.goafanti.common.dao.ContractTaskMapper;
import com.goafanti.common.dao.TOrderMapper;
import com.goafanti.common.dao.TechProjectLogMapper;
import com.goafanti.common.dao.TechProjectMapper;
import com.goafanti.common.dao.UserMapper;
import com.goafanti.common.enums.DeleteStatus;
import com.goafanti.common.enums.NoticeReadStatus;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.enums.OrderFlowState;
import com.goafanti.common.enums.TechProjectStatus;
import com.goafanti.common.model.Admin;
import com.goafanti.common.model.Contract;
import com.goafanti.common.model.ContractTask;
import com.goafanti.common.model.Notice;
import com.goafanti.common.model.TechProject;
import com.goafanti.common.model.TechProjectLog;
import com.goafanti.common.model.User;
import com.goafanti.common.utils.MobileMessageUtils;
import com.goafanti.common.utils.StringUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.order.bo.ServiceOrderDetailBo;
import com.goafanti.techproject.bo.ProjectDetailBo;
import com.goafanti.techproject.bo.ProjectListBo;
import com.goafanti.techproject.bo.TaskDetailBo;
import com.goafanti.techproject.bo.TaskListBo;
import com.goafanti.techproject.bo.TechProjectClientListBo;
import com.goafanti.techproject.bo.TechProjectContractListBo;
import com.goafanti.techproject.bo.TechProjectDetailBo;
import com.goafanti.techproject.bo.TechProjectManageListBo;
import com.goafanti.techproject.service.TechProjectService;
import com.goafanti.user.bo.OrgUnitNames;



@Service
public class TechProjectServiceImpl extends BaseMybatisDao<TechProjectMapper> implements TechProjectService {
	@Autowired
	private TechProjectMapper		techProjectMapper;
	@Autowired
	private TechProjectLogMapper	techProjectLogMapper;
	@Autowired
	private UserMapper				userMapper;
	@Autowired
	private ContractTaskMapper 		contractTaskMapper;
	@Autowired
	private TOrderMapper	tOrderMapper;
	@Autowired
	AdminMapper		adminMapper;
	
	@Value(value = "${accessKey}")
	private String					accessKey			= null;

	@Value(value = "${accessSecret}")
	private String					accessSecret		= null;
	@Value(value = "${mobileRemindCodeTemplate}")
	private String					mobileRemindCodeTemplate	= null;
	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TechProjectClientListBo> listClientTechProject(String uid, Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<>();

		 params.put("uid", uid);

		if (pageNo == null || pageNo < 0) {
			pageNo = 1;
		}

		if (pageSize == null || pageSize < 0 || pageSize > 10) {
			pageSize = 10;
		}
		return (Pagination<TechProjectClientListBo>) findPage("findTechProjectClientListByPage",
				"findTechProjectClientCount", params, pageNo, pageSize);
	}

	@Override
	public int updateTechProject(TechProject t, TechProjectLog log, Date recordTime) {
		if (null != recordTime && null != log.getState() && null != log.getPrincipal()) {
			log.setId(UUID.randomUUID().toString());
			log.setPid(t.getId());
			log.setRecordTime(recordTime);
			if (TokenManager.getToken() instanceof Admin) {
				log.setOperator(TokenManager.getAdminId());
			}
			if (TechProjectStatus.getStatus(log.getState()) == TechProjectStatus.DELIVERD) {
				t.setCreateTime(recordTime);
			} else if (TechProjectStatus.getStatus(log.getState()) == TechProjectStatus.ACCEPT) {
				t.setAcceptDate(recordTime);
			} else if (TechProjectStatus.getStatus(log.getState()) == TechProjectStatus.APPRVOVED) {
				t.setApprovedDate(recordTime);
			}

			if (TechProjectStatus.getStatus(log.getState()) != TechProjectStatus.CIRCULATION) {
				t.setState(log.getState());
			}
			techProjectLogMapper.insert(log);
			createNotice(t, log);
		}

		return techProjectMapper.updateByPrimaryKeySelective(t);
	}

	@Override
	public TechProject saveTechProject(TechProject techProject, String salesman) {
		techProject.setState(TechProjectStatus.DELIVERD.getCode());
		techProject.setFounder(salesman);

		techProject = disposeTechProjectSave(techProject);

		TechProjectLog log = new TechProjectLog();
		log.setId(UUID.randomUUID().toString());
		log.setPid(techProject.getId());
		log.setRecordTime(techProject.getRecordTime());
		log.setPrincipal(salesman);
		log.setState(TechProjectStatus.CREATE.getCode());
		log.setOperator(salesman);
		log.setComment(techProject.getDispatchInfo());
		techProjectLogMapper.insert(log);

		createNotice(techProject, log);

		TechProjectLog l = new TechProjectLog();
		l.setId(UUID.randomUUID().toString());
		l.setPid(techProject.getId());
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		l.setRecordTime(now.getTime());
		l.setPrincipal(TokenManager.getAdminId());
		l.setState(TechProjectStatus.DELIVERD.getCode());
		l.setOperator(salesman);
		techProjectLogMapper.insert(l);

		createNotice(techProject, l);
		return techProject;
	}

	@Override
	public TechProject insertTechProject(TechProject tp, String aid) {
		tp.setState(TechProjectStatus.CREATE.getCode());
		tp = disposeTechProjectSave(tp);

		TechProjectLog l = new TechProjectLog();
		l.setId(UUID.randomUUID().toString());
		l.setPid(tp.getId());
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		l.setRecordTime(now.getTime());
		l.setPrincipal(aid);
		l.setState(TechProjectStatus.CREATE.getCode());
		l.setComment(tp.getDispatchInfo());
		techProjectLogMapper.insert(l);

		createNotice(tp, l);
		return tp;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TechProjectManageListBo> listManageTechProject(String contractId, Integer province,
			String unitName, String uid, Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<>();

		if (!TokenManager.hasRole(AFTConstants.SUPERADMIN)) {
			params.put("principal", TokenManager.getAdminId());
		}

		if (!StringUtils.isBlank(contractId)) {
			params.put("contractId", contractId);
		}

		if (null != province) {
			params.put("province", province);
		}
		if (!StringUtils.isBlank(unitName)) {
			params.put("unitName", unitName);
		}

		if (!StringUtils.isBlank(uid)) {
			params.put("uid", uid);
		}
		if (pageNo == null || pageNo < 0) {
			pageNo = 1;
		}

		if (pageSize == null || pageSize < 0 || pageSize > 10) {
			pageSize = 10;
		}
		return (Pagination<TechProjectManageListBo>) findPage("findTechProjectManageListByPage",
				"findTechProjectManageCount", params, pageNo, pageSize);
	}

	@Override
	public TechProjectDetailBo selectProjectDetail(String pid) {
		return techProjectMapper.selectProjectDetail(pid);
	}

	@Override
	public int deleteByPrimaryKey(List<String> id) {
		return techProjectMapper.batchDeleteByPrimaryKey(id);
	}

	@Override
	public TechProject selectByPrimaryKey(String id) {
		return techProjectMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<OrgUnitNames> selectWebsiteUnitNames() {
		String principal = null;
		if (!TokenManager.hasRole(AFTConstants.SUPERADMIN)) {
			principal = TokenManager.getAdminId();
		}
		return techProjectMapper.selectWebsiteUnitNames(principal);
	}

	private TechProject disposeTechProjectSave(TechProject techProject) {
		techProject.setId(UUID.randomUUID().toString());
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		techProject.setRecordTime(now.getTime());
		techProject.setDeletedSign(DeleteStatus.UNDELETE.getCode());
		techProjectMapper.insert(techProject);
		return techProject;
	}

	@Override
	public List<TechProjectContractListBo> listContractTechProjectByContractId(String contractId) {
		return techProjectMapper.listContractTechProjectByContractId(contractId);
	}

	//to update 18
	@Override
	public void batchInsertContractRecord(Contract contract) {
		/*contract.setTechProjectStatus(ContractBusinessStatus.CREATE.getCode());
		contractMapper.updateByPrimaryKeySelective(contract);

		List<TechProject> tp = new ArrayList<>();
		List<TechProjectLog> tpl = new ArrayList<>();
		TechProject p = null;
		TechProjectLog l = null;
		for (int i = 0; i < contract.getTechProjectNum(); i++) {
			p = new TechProject();
			l = new TechProjectLog();
			p.setId(UUID.randomUUID().toString());
			p.setUid(contract.getUid());
			p.setContractId(contract.getId());
			p.setDeletedSign(DeleteStatus.UNDELETE.getCode());
			p.setPrincipal(TokenManager.getAdminId());
			p.setFounder(TokenManager.getAdminId());
			p.setState(TechProjectStatus.CREATE.getCode());
			p.setContacts(contract.getContacts());
			Calendar now = Calendar.getInstance();
			now.set(Calendar.MILLISECOND, 0);
			p.setRecordTime(now.getTime());

			l.setId(UUID.randomUUID().toString());
			l.setPid(p.getId());
			l.setPrincipal(TokenManager.getAdminId());
			l.setOperator(TokenManager.getAdminId());
			l.setRecordTime(now.getTime());
			l.setState(TechProjectStatus.CREATE.getCode());

			tp.add(p);
			tpl.add(l);
		}

		techProjectMapper.batchInsert(tp);
		techProjectLogMapper.batchInsert(tpl);*/
	}

	private void createNotice(TechProject t, TechProjectLog l) {
		TechProject info = techProjectMapper.selectByPrimaryKey(t.getId());

		Notice n = new Notice();
		Calendar now = Calendar.getInstance();
		now.set(Calendar.MILLISECOND, 0);
		n.setId(UUID.randomUUID().toString());
		n.setCreateTime(now.getTime());
		n.setReaded(NoticeReadStatus.UNREAD.getCode());

		User u = userMapper.selectByPrimaryKey(t.getUid());
		if (null != u) {
			n.setPid(u.getAid());
		}

		n.setUid(t.getUid());
		n.setRid(t.getId());

		n.setAid(l.getPrincipal());
		n.setContent("编号" + info.getSerialNumber() + "  " + TechProjectStatus.getStatus(l.getState()).getDesc());
		n.setNoticeType(NoticeStatus.TECHPROJECT.getCode());
		// noticeMapper.insert(n);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<ProjectListBo> listProject(ProjectListBo bo, String depId, String orderStartDate,
			String orderEndDate, String setUpStartDate, String setUpEndDate,Integer pageNo,Integer pageSize) {
		Map<String, Object> params = new HashMap<>();
		if(StringUtils.isNotBlank(bo.getBuyerName())) params.put("buyerName", bo.getBuyerName());
		if(bo.getDeletedSign() != null) params.put("deletedSign", bo.getDeletedSign());
		if(bo.getType() != null) params.put("type", bo.getType());
		if(bo.getTaskDistribution() != null) params.put("taskDistribution", bo.getTaskDistribution());
		if(StringUtils.isNotBlank(bo.getOrderNo())) params.put("orderNo", bo.getOrderNo());
		if(StringUtils.isNotBlank(bo.getSalesmanName())) params.put("salesmanName", bo.getSalesmanName());
		if(StringUtils.isNotBlank(bo.getPrincipalName())) params.put("principalName", bo.getPrincipalName());
		if(StringUtils.isNotBlank(bo.getSerialNumber())) params.put("serialNumber", bo.getSerialNumber());
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		try {
			if(StringUtils.isNotBlank(setUpStartDate))
				params.put("setUpStartDate", DateUtils.parseDate(setUpStartDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(setUpEndDate))
				params.put("setUpEndDate", DateUtils.parseDate(setUpEndDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(orderStartDate))
				params.put("orderStartDate", DateUtils.parseDate(orderStartDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(orderEndDate))
				params.put("orderEndDate", DateUtils.parseDate(orderEndDate, AFTConstants.YYYYMMDD));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return (Pagination<ProjectListBo>)findPage("listProjectByPage", "listProjectCount", params, pageNo, pageSize);
	}



	@Override
	public ProjectDetailBo selectTechProjectDetail(String contractId,Integer buyerType) {
		
		return techProjectMapper.selectTechProjectDetail(contractId,buyerType);
	}

	@Override
	public List<TaskListBo> selectProjectTask(String contractId) {
		
		return techProjectMapper.selectProjectTask(contractId);
	}



	@Override
	public TaskDetailBo selectProjectTaskDetail(String taskId) {
		
		return contractTaskMapper.selectProjectTaskDetail(taskId);
	}

	@Override
	public int updateProjectTask(ContractTask task) {
		Admin a=adminMapper.selectByPrimaryKey(task.getTaskReceiver());
		Admin ad=null;
		String regex = "^(1[1-9][0-9])\\d{8}$";
		Pattern p = Pattern.compile(regex);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		TaskDetailBo tb= contractTaskMapper.selectProjectTaskDetail(task.getId());
		String mobile = "";
		if (null!=tb&&tb.getOrderNo()!=null) {
			ServiceOrderDetailBo t=tOrderMapper.selectServiceOrderDetail(tb.getOrderNo());
			System.out.println(t.getSalesmanId());
			if (null!=t&&t.getSalesmanId()!=null) {
				ad=adminMapper.selectByPrimaryKey(t.getSalesmanId());
				if(null!=ad&&null!=ad.getContactMobile()){
				Matcher s1 = p.matcher(ad.getContactMobile());
				if (s1.matches()) {
					mobile=ad.getContactMobile();
					}
				}
			}
		}
		if (null!=a&&null!=a.getContactMobile()) {
			Matcher m = p.matcher(a.getContactMobile());
			if ( m.matches()) {
			mobile=mobile+","+a.getContactMobile();
				}
			}
		String paramString = "{\"number\":\"" + tb.getOrderNo() 
		+ "\",\"operator\":\"" + TokenManager.getAdminToken().getName()
		+ "\",\"time\":\"" +   sdf.format(new Date())
		+ "\",\"name\":\"" +  tb.getBuyerName()
		+ "\",\"type\":\"" +  OrderFlowState.RWPD.getDesc() +
		"\"}";
		MobileMessageUtils.sendMessage(mobileRemindCodeTemplate, paramString, mobile, accessKey, accessSecret);
		return contractTaskMapper.updateByPrimaryKeySelective(task);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TaskListBo> selectMyProjectTask(String projectNo, String buyerName, String taskReceiverId, String taskReceiverName,
			String startDate,String endDate, Integer taskStatus, String categoryId,String deleteSign,String publishStatus, Integer pageNo, Integer pageSize) {
		Map<String,Object> params = new HashMap<String,Object>();
		if(StringUtils.isNotBlank(projectNo)) params.put("projectNo", projectNo);
		if(StringUtils.isNotBlank(buyerName)) params.put("buyerName", buyerName);
		if(StringUtils.isNotBlank(taskReceiverId)) params.put("taskReceiverId", taskReceiverId);
		if(StringUtils.isNotBlank(taskReceiverName)) params.put("taskReceiverName", taskReceiverName);
		try {
			if (StringUtils.isNotBlank(startDate))
				params.put("startDate", DateUtils.parseDate(startDate + " 00:00:00", AFTConstants.YYYYMMDDHHMMSS));
			if (StringUtils.isNotBlank(endDate))
				params.put("endDate", DateUtils.parseDate(endDate + " 23:59:59", AFTConstants.YYYYMMDDHHMMSS));
			} catch (ParseException e) {
		}
		if(StringUtils.isNotBlank(categoryId)) params.put("categoryId", categoryId);
		if(StringUtils.isNotBlank(deleteSign)) params.put("deleteSign", deleteSign);
		if(StringUtils.isNotBlank(publishStatus)) params.put("publishStatus", publishStatus);
		if(taskStatus != null) params.put("taskStatus", taskStatus);
		return (Pagination<TaskListBo>)findPage("selectMyProjectTaskByPage", "selectMyProjectTaskCount", params, pageNo, pageSize);
	}

	@Override
	public ContractTask selectTaskById(String taskId) {
		return contractTaskMapper.selectByPrimaryKey(taskId);
	}







	public void sendMessage(String orderNo, String mobile, String type) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String userName=tOrderMapper.selectByUserName(orderNo);
		//String message=noticeType.getDesc() + ": 订单编号-" + tOrder.getOrderNo() + ",变更内容："+noticeComment+",操作人-" + TokenManager.getAdminToken().getName();
		String paramString = "{\"number\":\"" + orderNo 
		+ "\",\"operator\":\"" + TokenManager.getAdminToken().getName()
		+ "\",\"name\":\"" +  userName
		+ "\",\"time\":\"" +  sdf.format(new Date()) 
		+ "\",\"type\":\"" +  type +
		"\"}";
		MobileMessageUtils.sendMessage(mobileRemindCodeTemplate, paramString, mobile, accessKey, accessSecret);
	}


	@SuppressWarnings("unchecked")
	@Override
	public Pagination<ProjectListBo> salesmanListProject(ProjectListBo bo, String depId, String orderStartDate,
			String orderEndDate, String setUpStartDate, String setUpEndDate, Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<>();
		if(StringUtils.isNotBlank(bo.getBuyerName())) params.put("buyerName", bo.getBuyerName());
		if(bo.getDeletedSign() != null) params.put("deletedSign", bo.getDeletedSign());
		if(bo.getTaskDistribution() != null) params.put("taskDistribution", bo.getTaskDistribution());
		if(StringUtils.isNotBlank(bo.getOrderNo())) params.put("orderNo", bo.getOrderNo());
		if(StringUtils.isNotBlank(bo.getSalesmanName())) params.put("salesmanName", bo.getSalesmanName());
		if(StringUtils.isNotBlank(bo.getPrincipalName())) params.put("principalName", bo.getPrincipalName());
		if(StringUtils.isNotBlank(bo.getSerialNumber())) params.put("serialNumber", bo.getSerialNumber());
		if(StringUtils.isNotBlank(depId)) params.put("depId", depId);
		params.put("salesmanId", TokenManager.getAdminId());
		try {
			if(StringUtils.isNotBlank(setUpStartDate))
				params.put("setUpStartDate", DateUtils.parseDate(setUpStartDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(setUpEndDate))
				params.put("setUpEndDate", DateUtils.parseDate(setUpEndDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(orderStartDate))
				params.put("orderStartDate", DateUtils.parseDate(orderStartDate, AFTConstants.YYYYMMDD));
			if(StringUtils.isNotBlank(orderEndDate))
				params.put("orderEndDate", DateUtils.parseDate(orderEndDate, AFTConstants.YYYYMMDD));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return (Pagination<ProjectListBo>)findPage("salesmanListProjectByPage", "salesmanListProjectCount", params, pageNo, pageSize);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TaskListBo> selectProjectTask(String projectNo, String buyerName, String taskReceiverId, String taskReceiverName,
			String startDate,String endDate, Integer taskStatus, String categoryId,String deleteSign,String publishStatus, Integer pageNo, Integer pageSize) {
		Map<String,Object> params = new HashMap<String,Object>();
		if(StringUtils.isNotBlank(projectNo)) params.put("projectNo", projectNo);
		if(StringUtils.isNotBlank(buyerName)) params.put("buyerName", buyerName);
		if(StringUtils.isNotBlank(taskReceiverId)) params.put("taskReceiverId", taskReceiverId);
		if(StringUtils.isNotBlank(taskReceiverName)) params.put("taskReceiverName", taskReceiverName);
		try {
			if (StringUtils.isNotBlank(startDate))
				params.put("startDate", DateUtils.parseDate(startDate + " 00:00:00", AFTConstants.YYYYMMDDHHMMSS));
			if (StringUtils.isNotBlank(endDate))
				params.put("endDate", DateUtils.parseDate(endDate + " 23:59:59", AFTConstants.YYYYMMDDHHMMSS));
			} catch (ParseException e) {
		}
		if(StringUtils.isNotBlank(categoryId)) params.put("categoryId", categoryId);
		if(StringUtils.isNotBlank(deleteSign)) params.put("deleteSign", deleteSign);
		if(StringUtils.isNotBlank(publishStatus)) params.put("publishStatus", publishStatus);
		if(taskStatus != null) params.put("taskStatus", taskStatus);
		params.put("taskReceiver", TokenManager.getAdminId()); 
		return (Pagination<TaskListBo>)findPage("selectProjectTaskByPage", "selectProjectTaskCount", params, pageNo, pageSize);
	}
	
}
