package com.palmnest.service.notice.impl;

import cn.superdesk.libs.common.json.JsonUtils;

import com.alibaba.fastjson.JSON;
import com.palmnest.application.CodeConstants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.bean.Page;
import com.palmnest.application.core.util.AppResultUtil;
import com.palmnest.application.core.util.ExcelUtils;
import com.palmnest.application.core.util.HttpKit;
import com.palmnest.application.core.util.PropertiesKit;
import com.palmnest.application.dto.AppNoticeRecordVo;
import com.palmnest.application.dto.DeptUserVo;
import com.palmnest.application.dto.NoticeRecordVo;
import com.palmnest.dao.estateserve.AppUserDao;
import com.palmnest.dao.estateserve.ScWxuserDao;
import com.palmnest.dao.notice.AppNoticeDao;
import com.palmnest.dao.notice.AppNoticeDetailDao;
import com.palmnest.dao.notice.AppNoticeRecordDao;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.model.estateserve.WxUser;
import com.palmnest.model.notice.AppNoticeDetailModel;
import com.palmnest.model.notice.AppNoticeModel;
import com.palmnest.model.notice.AppNoticeRecordModel;
import com.palmnest.service.impl.GenericManagerImpl;
import com.palmnest.service.notice.AppNoticeManager;
import com.palmnest.service.notice.AppNoticeRecordManager;
import com.palmnest.service.notice.AppNoticeReminderRecordManager;
import com.palmnest.service.redis.BaseRedisService;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Slf4j
@Service("appNoticeRecordManager")
public class AppNoticeRecordManagerImpl extends GenericManagerImpl<AppNoticeRecordModel, Integer> implements AppNoticeRecordManager {
    public static final String clientNo  = PropertiesKit.readPropertiesValue("clientNo", "wechat.properties");
    public static final String wxMessageUrl  = PropertiesKit.readPropertiesValue("wxMessageUrl", "wechat.properties");

    @Autowired
    private AppNoticeRecordDao appNoticeRecordDao;

    @Autowired
    private AppNoticeManager      appNoticeManager;

    @Autowired
    private BaseRedisService baseRedisService;
    
    @Autowired
    private AppNoticeDetailDao appNoticeDetailDao;
    @Autowired
    private ScWxuserDao scWxuserDao;
    @Autowired
    private AppUserDao appUserDao;

    @Autowired
    private AppNoticeReminderRecordManager appNoticeReminderRecordManager;

    /**
     * 废弃
     * @param map
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     */
    public AppNoticeRecordVo getRecordList1(Map<String, Object> map, int pageNo, int pageSize) throws Exception {
    	 AppNoticeRecordVo appNoticeRecordVo=new AppNoticeRecordVo();
    	Integer id=Integer.parseInt(map.get("id").toString());
    	AppNoticeModel model=appNoticeManager.get(id);
    	if(null == model){
    		return appNoticeRecordVo;
    	}
        if(null != model.getPublicObj() && 1 == model.getPublicObj().intValue()){
        	String  recordVo= baseRedisService.get(CodeConstants.NOTICE_REDIS_ORDERID+id);
            if(recordVo!=null){
            	int readCount=0;
            	int count=0;
                JSONArray jsonArray = JSONArray.fromObject(recordVo);
                //Java集合
                List<NoticeRecordVo> noticeRecordVoList = (List<NoticeRecordVo>) jsonArray.toCollection(jsonArray, NoticeRecordVo.class);
                if(!CollectionUtils.isEmpty(noticeRecordVoList)){
                	for(NoticeRecordVo vo:noticeRecordVoList){
                		readCount=readCount+vo.getReadCount();
                		count=count+vo.getSumCount();
                	}
                }
                appNoticeRecordVo.setRead(readCount);
                appNoticeRecordVo.setCount(count);
            }else{
            	appNoticeRecordVo.setRead(0);
            	appNoticeRecordVo.setCount(0);
            }
        	Page page=appNoticeRecordDao.getRecordList(map, pageNo, pageSize);
        	if(null != page && !CollectionUtils.isEmpty( page.getItems())){
                List<Map<String, Object>> list  = page.getItems() ;
                if(list!=null && list.size()>0){
                    appNoticeRecordVo.setItems(list);
                }
        	}
        }else{
        	Page page=appNoticeRecordDao.getRecordList(map, pageNo, pageSize);
        	if(null != page){
        		appNoticeRecordVo.setRead(appNoticeRecordDao.getRecordCount(id));
                appNoticeRecordVo.setCount(page.getTotalCount());
                List<Map<String, Object>> list  = page.getItems() ;
                if(list!=null && list.size()>0){
                    appNoticeRecordVo.setItems(list);
                }
        	}
        }
        return appNoticeRecordVo;
    }
    @Override
    public AppNoticeRecordVo getRecordList(Map<String, Object> map, int pageNo, int pageSize) throws Exception {
        AppNoticeRecordVo appNoticeRecordVo=new AppNoticeRecordVo();
        Integer id=Integer.parseInt(map.get("id").toString());
        AppNoticeModel model=appNoticeManager.get(id);
        if(null == model){
            return appNoticeRecordVo;
        }
        Page page=appNoticeRecordDao.getRecordList(map, pageNo, pageSize);
        if(null != page){
            appNoticeRecordVo.setRead(appNoticeRecordDao.getRecordCount(id));
            appNoticeRecordVo.setCount(page.getTotalCount());
            List<Map<String, Object>> list  = page.getItems() ;
            if(list!=null && list.size()>0){
                appNoticeRecordVo.setItems(list);
            }
        }
        return appNoticeRecordVo;
    }
    @Override
    public AppResultDto exportReportList(Map<String, Object> params) throws Exception {
        List<Map<String, Object>> list       = appNoticeRecordDao.recordFind(params,1);
        HSSFWorkbook wb         = new HSSFWorkbook();
        String                    sheetName  = "阅读情况报表";
        String[]                  titles     = {"部门", "用户姓名","电话", "是否已读"};
        String[]                  fieldNames = {"department", "name","telephone", "typeName"};
        try {
            File file = file();
            ExcelUtils.exportExcel(file, wb, sheetName, list, titles, fieldNames);
            return AppResultUtil.createSuccesDto(file.getPath());
        } catch (Exception e) {
            log.info("AppNoticeRecordManagerImpl exportReportList ======");
            e.printStackTrace();
            return AppResultUtil.createErrorDto("100", "导出数据失败");
        }
    }

    /**
     * 废弃不用
     * @param params
     * @return
     * @throws Exception
     */
    public AppResultDto updateRecord1(Map<String, Object> params) throws Exception {
        try {
        	Integer id=Integer.parseInt(params.get("id").toString());
        	int sourceTypes=1;
        	if(params.containsKey("sourceType") && null != params.get("sourceType") && StringUtils.isNotEmpty(params.get("sourceType").toString())){
        		String sourceType=params.get("sourceType").toString();
        		if("2".equals(sourceType)){
        			sourceTypes=2;
        		}
        	}
        	Integer noticeId=null;
        	if(2 == sourceTypes && appNoticeDetailDao.exists(id)){
        		AppNoticeDetailModel deModel=appNoticeDetailDao.get(id);
        		if(null != deModel){
        			noticeId=deModel.getSourceId();
        		}
        		
        	}else if(1 == sourceTypes && appNoticeManager.exists(id)){
        		noticeId=id;
        	}
        	log.info("updateRecord-noticeId:{}",noticeId);
        	if(null == noticeId){
        		return AppResultUtil.createErrorDto("500", "订单不存在");
        	}
        	AppNoticeModel appNotice = appNoticeManager.get(noticeId);
        	if(null == appNotice){
        		 return AppResultUtil.createErrorDto("500", "订单不存在");
        	}
        	params.put("id", noticeId);
        	
        	String openId=params.get("openId").toString();
        	if(null != appNotice && null != appNotice.getPublicObj() && 1 == appNotice.getPublicObj().intValue()){
        		String  recordVo= baseRedisService.get(CodeConstants.NOTICE_REDIS_ORDERID+noticeId);
        		if(StringUtils.isNotEmpty(recordVo)){
        			WxUser wxUser=scWxuserDao.getScWxuserByOpenId(openId);
        			String developId="";
        			if(null != wxUser && StringUtils.isNotEmpty(wxUser.getDevelopId())){
        				developId=wxUser.getDevelopId();
        			}
        			
        			JSONArray jsonArray = JSONArray.fromObject(recordVo);
                    //Java集合
                    List<NoticeRecordVo> noticeRecordVoList = (List<NoticeRecordVo>) jsonArray.toCollection(jsonArray, NoticeRecordVo.class);
                    for (NoticeRecordVo noticeRecordVo : noticeRecordVoList) {
                    	if(StringUtils.isNotEmpty(developId) && developId.equals(noticeRecordVo.getDevelopId())){
                    		int readCount=noticeRecordVo.getReadCount();
                        	log.info("updateRecord-------------noticeRecordVo.getDevelopId():{}----------readCount:{}",noticeRecordVo.getDevelopId(),readCount);
                        	List<String> readOpenIds=noticeRecordVo.getReadOpenids();
                        	if(CollectionUtils.isEmpty(readOpenIds)){
                        		readOpenIds=new ArrayList<String>();
                        	}
                        	if(params.containsKey("openId") && null != params.get("openId") && StringUtils.isNotEmpty(params.get("openId").toString()) 
                        			&& !readOpenIds.contains(params.get("openId").toString())){
                        		readOpenIds.add(params.get("openId").toString());
                        		noticeRecordVo.setReadCount(readCount+1);
                        	}
                        	noticeRecordVo.setReadOpenids(readOpenIds);
                        	if(null != wxUser && null != wxUser.getOrganizationId() && StringUtils.isNotEmpty(wxUser.getOpenId())){
                        		AppUser user=appUserDao.findLoginUserByOpenId(wxUser.getOrganizationId(), wxUser.getOpenId());
                        		if(null != user){
                        			List<AppNoticeRecordModel> list=appNoticeRecordDao.findByPublicObj(noticeId, 1, user.getId());
                        			if(CollectionUtils.isEmpty(list)){
                        				List<Map<String, Object>> maps=new ArrayList<Map<String,Object>>();
                            			Map<String, Object> valueMap=new HashMap<String, Object>();
                            			valueMap.put("userId", user.getId());
                            			valueMap.put("userName", user.getUserName());
                            			valueMap.put("userMobile", user.getUserMobile());
                            			valueMap.put("organizationId", wxUser.getOrganizationId());
                            			maps.add(valueMap);
                            			appNoticeRecordDao.insertRecord(maps, noticeId, 1);
                        			}else{
                        				params.put("id", noticeId);
                        				params.put("userId", user.getId());
                        				params.put("orgId", wxUser.getOrganizationId());
                        				appNoticeRecordDao.updateRecord(params);
                        			}
                        			
                        		}
                        	}
                    	}else if(StringUtils.isEmpty(developId)){
                    		int readCount=noticeRecordVo.getReadCount();
                        	log.info("updateRecord-------------noticeRecordVo.getDevelopId():{}----------readCount:{}",noticeRecordVo.getDevelopId(),readCount);
                        	List<String> readOpenIds=noticeRecordVo.getReadOpenids();
                        	if(CollectionUtils.isEmpty(readOpenIds)){
                        		readOpenIds=new ArrayList<String>();
                        	}
                        	if(params.containsKey("openId") && null != params.get("openId") && StringUtils.isNotEmpty(params.get("openId").toString()) 
                        			&& !readOpenIds.contains(params.get("openId").toString())){
                        		readOpenIds.add(params.get("openId").toString());
                        		noticeRecordVo.setReadCount(readCount+1);
                        	}
                        	noticeRecordVo.setReadOpenids(readOpenIds);
                    	}
                    }
                    baseRedisService.set(CodeConstants.NOTICE_REDIS_ORDERID+noticeId, JSON.toJSONString(noticeRecordVoList));
        		}
        	}else{
	       		 String orgIds="";
	       		 if(StringUtils.isNotEmpty(appNotice.getOrgIds())){
	       			 orgIds=appNotice.getOrgIds();
	       		 }else{
	       			 orgIds=appNotice.getOrgId().toString();
	       		 }
       			String [] orgArr=orgIds.split(",");
       			for(int i=0;i<orgArr.length;i++){
       				Integer orgId=Integer.parseInt(orgArr[i]);
       				AppUser user=appUserDao.findLoginUserByOpenId(orgId, openId);
       				if(null != user){
       					params.put("userId", user.getId());
       					params.put("orgId", orgId);
       					List<Map<String, Object>>list = appNoticeRecordDao.recordFind(params,1);
       	                if(list!=null && list.size()>0){
       	                    appNoticeRecordDao.updateRecord(params);
       	                }
       				}
       			}
        		
        	}
            return AppResultUtil.createSuccesDto("成功");
        } catch (Exception e) {
            log.info("AppNoticeRecordManagerImpl updateRecord ======error:{}",e.getMessage());
            e.printStackTrace();
            return AppResultUtil.createErrorDto("500", "失败");
        }
    }
    @Override
    public AppResultDto updateRecord(Map<String, Object> params) throws Exception {
        try {
            Integer id=Integer.parseInt(params.get("id").toString());
            int sourceTypes=1;
            if(params.containsKey("sourceType") && null != params.get("sourceType") && StringUtils.isNotEmpty(params.get("sourceType").toString())){
                String sourceType=params.get("sourceType").toString();
                if("2".equals(sourceType)){
                    sourceTypes=2;
                }
            }
            Integer noticeId=null;
            if(2 == sourceTypes && appNoticeDetailDao.exists(id)){
                AppNoticeDetailModel deModel=appNoticeDetailDao.get(id);
                if(null != deModel){
                    noticeId=deModel.getSourceId();
                }

            }else if(1 == sourceTypes && appNoticeManager.exists(id)){
                noticeId=id;
            }
            log.info("updateRecord-noticeId:{}",noticeId);
            if(null == noticeId){
                return AppResultUtil.createErrorDto("500", "订单不存在");
            }
            AppNoticeModel appNotice = appNoticeManager.get(noticeId);
            if(null == appNotice){
                return AppResultUtil.createErrorDto("500", "订单不存在");
            }
            params.put("id", noticeId);

            String openId=params.get("openId").toString();

            WxUser wxUser=scWxuserDao.getScWxuserByOpenId(openId);
            if(null != wxUser && null != wxUser.getOrganizationId() && StringUtils.isNotEmpty(wxUser.getOpenId())){
                AppUser user=appUserDao.findLoginUserByOpenId(wxUser.getOrganizationId(), wxUser.getOpenId());
                if(null != user){
                        params.put("id", noticeId);
                        params.put("userId", user.getId());
                        params.put("orgId", wxUser.getOrganizationId());
                        appNoticeRecordDao.updateRecord(params);
                }
            }
            return AppResultUtil.createSuccesDto("成功");
        } catch (Exception e) {
            log.info("AppNoticeRecordManagerImpl updateRecord ======error:{}",e.getMessage());
            e.printStackTrace();
            return AppResultUtil.createErrorDto("500", "失败");
        }
    }
    @Override
    public AppResultDto recordNotice(Map<String, Object> params) {
        try {
            List<Map<String, Object>> list = appNoticeRecordDao.recordFind(params,0);
            if(list!=null && list.size()>0){
                AppNoticeModel appNoticeModel = appNoticeManager.get(Integer.parseInt(params.get("id").toString()));
                String url=appNoticeModel.getUrl_address();
                if(-1 == url.indexOf("http")){
                    url="http:"+url;
                }
                sendWxCusmonMsg(list,params.get("content").toString(),url);
            }
            appNoticeReminderRecordManager.addReminderRecord(params);
            return AppResultUtil.createSuccesDto("成功");
        } catch (Exception e) {
            e.printStackTrace();
            return AppResultUtil.createErrorDto("500", "失败");
        }
    }





    /**
     * 发送客服消息
     *
     * @return
     * @throws Exception
     */
    public void sendWxCusmonMsg( List<Map<String, Object>> list,String content,String url) {
        // 构建接口地址
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.execute(new Runnable() {
            public void run() {
                try {
                    log.info("sendWxCusmonMsg=======>>>>>>>>>开始发送消息模板");
                    StringBuffer sb = new StringBuffer();
                    for (Map<String, Object> emp : list) {
                        sb.append(emp.get("userId").toString() ).append(",");
                    }
                    sb.deleteCharAt(sb.length()-1);
                    Map<String,Object>map=new HashMap<>();
                    map.put("orgId",list.get(0).get("orgId").toString());
                    map.put("userIds",sb.toString().split(","));
                    map.put("content",content);
                    map.put("url",url);
                    String params=com.alibaba.fastjson.JSONObject.toJSONString(map);
                    String result=HttpKit.HttpClientPost(params,wxMessageUrl);
                    System.out.println(result);
                    log.info("sendWxCusmonMsg result===>"+  JsonUtils.toJson(result));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        executorService.shutdown();
    }

    @Override
    public void saveOrUpdateAppNoticeRecordModel(List<NoticeRecordVo> list,Integer id,Integer publicObj) {

        if(CollectionUtils.isEmpty(list)){
        	return;
        }
        log.info("saveOrUpdateAppNoticeRecordModel id:{},listsize:{}",id,list.size());
        appNoticeRecordDao.deleteRecord(id);
        for(NoticeRecordVo vo:list){
        	appNoticeRecordDao.insertRecord(vo.getUserList(),id,publicObj);
        }
        
    }


    public File file() throws IOException {
        String classpath = getClass().getResource("/").getPath();
        log.info("begin exportExcel  classpath:" + classpath);
        if (StringUtils.isNotEmpty(classpath)) {
            log.info("begin exportExcel  CLIENTNO:" + clientNo);
            if ("dev".equals(clientNo)) {
                String str = classpath.substring(0, 1);
                if ("/".equals(str)) {
                    classpath = classpath.replaceFirst("/", "");
                }
            }
        }
        log.info("path:" + classpath);
        String webappRoot = classpath.replaceAll("WEB-INF/classes", "");
        log.info("path:" + webappRoot);
        String path = webappRoot + "upload/RecordFindList.xls";
        if (StringUtils.isNotEmpty(path)) {
            path = path.replace("//", "/");
        }

        log.info("path:" + path);
        File file = new File(new ExcelUtils().getPath(path));
        System.out.println("path:" + path);
        return file;
    }



}
