package cms.web.action.question;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.util.concurrent.AtomicLongMap;

import cms.bean.question.AppendQuestionItem;
import cms.bean.question.Question;
import cms.bean.question.QuestionTagAssociation;
import cms.bean.setting.EditorTag;
import cms.bean.staff.SysUsers;
import cms.bean.user.User;
import cms.service.question.AnswerService;
import cms.service.question.QuestionService;
import cms.service.staff.StaffService;
import cms.service.user.UserService;
import cms.utils.FileUtil;
import cms.utils.JsonUtils;
import cms.web.action.TextFilterManage;
import cms.web.action.fileSystem.FileManage;
import cms.web.action.setting.SettingManage;
/**
 * 问题管理
 *
 */
@Component("questionManage")
public class QuestionManage {

	@Resource QuestionManage questionManage;
	@Resource TextFilterManage textFilterManage;
	@Resource QuestionService questionService;
	@Resource StaffService staffService;
	@Resource UserService userService;
	@Resource SettingManage settingManage;
	@Resource AnswerService answerService;
	@Resource FileManage fileManage;
	
	//key: 问题Id value:展示次数
    private AtomicLongMap<Long> countMap = AtomicLongMap.create();
	
	/**
	 * 增加问题展示次数
	 * @param questionId 问题Id
	 * @param ip 
	 */
	public void addView(Long questionId,String ip){
		
		Long time = new Date().getTime();
		Long oldTime = questionManage.ipRecord(questionId+"_"+ip, time);
		if(oldTime != null &&  time.equals(oldTime)){
			//增加
			countMap.incrementAndGet(questionId);
		}
	}
	
	/**
	 * 读取问题本地展示次数
	 * @param questionId 问题Id
	 */
	public Long readLocalView(Long questionId){
		Long count = countMap.asMap().get(questionId);
		if(count != null){
			return count;
		}
		return 0L;
	}
	
	/**
	 * 提交问题展示次数到数据库(定时提交)
	 */
	@Scheduled(fixedDelay=600000)//10分钟
	public void commitCount(){
		//计数
		int i = 0;
		
		Map<Long,Long> batchCount = new HashMap<Long,Long>();
		
		for (Map.Entry<Long, Long> entry : countMap.asMap().entrySet()) {
			Long questionId = entry.getKey();
			Long count = entry.getValue();
			
			i++;
			if(count > 0L){
				batchCount.put(questionId, count);
				countMap.addAndGet(questionId, count * -1L);//减少
			}
			if(i== 100){//每100条提交一次到数据库
				if(batchCount.size() >0){
					questionService.addViewCount(batchCount);
					batchCount.clear();
				}
				i = 0;
			}
		}
		
		//将剩余的展示次数提交到数据库
		if(batchCount.size() >0){
			questionService.addViewCount(batchCount);
		}

		//删除所有计数器值为零的映射
		countMap.removeAllZeros();
	}
	
	
	
	/**
	 * 话题展示IP记录(每话题每IP 24小时内只统计一次点击次数)
	 * @param key 话题Id_用户IP
	 * @param time 当前时间
	 * @return
	 */
	@Cacheable(value="questionManage_cache_ipRecord",key="#key")
	public Long ipRecord(String key,Long time){
		return time;
	}
	
	
	/**
	 * 生成上传文件编号
	 * @param userName 用户名称
	 * @param isStaff 是否是员工   true:员工   false:会员
	 * @return
	 */
	public String generateFileNumber(String userName, Boolean isStaff){
		String number = "";

		if(isStaff != null && userName != null && !"".equals(userName.trim())){
			if(isStaff == true){//员工
				
				SysUsers sysUsers = staffService.findByUserAccount(userName.trim());
				if(sysUsers != null){
					number = "a"+sysUsers.getUserId();
				}
			}else{//会员
				User user = userService.findUserByUserName(userName.trim());
				if(user != null){
					number = "b"+user.getId();
				}
			}
		}
		return number;
	}
	/**
	 * 根据文件名获取文件编号
	 * @param fileName 文件名称(不含后缀)
	 * @return
	 */
	public String getFileNumber(String fileName){
		String number = "";

		if(fileName != null && !"".equals(fileName.trim())){
			fileName = fileName.trim();
			if(fileName.length() >33){
				String isStaff = fileName.substring(32,33);
				if(isStaff.equals("a") || isStaff.equals("b")){
					number = fileName.substring(32, fileName.length());
				}
			}
		}
		return number;
	}
	
	
	
	/**
	 * 根据用户名称删除用户下的所有问题文件
	 * @param userName 用户名称
	 * @param isStaff 是否为员工
	 */
	public void deleteQuestionFile(String userName, boolean isStaff){
		int firstIndex = 0;//起始页
		int maxResult = 100;// 每页显示记录数
		
		String fileNumber = questionManage.generateFileNumber(userName, isStaff);
		
		while(true){
			List<Question> questionContentList = questionService.findQuestionContentByPage(firstIndex, maxResult,userName,isStaff);
			if(questionContentList == null || questionContentList.size() == 0){
				break;
			}
			firstIndex = firstIndex+maxResult;
			for (Question question :questionContentList) { 
				Long questionId = question.getId();
				String questionContent = question.getContent();
				
				
				//删除最后一个逗号
				String _appendContent = StringUtils.substringBeforeLast(question.getAppendContent(), ",");//从右往左截取到相等的字符,保留左边的

				List<AppendQuestionItem> appendQuestionItemList = JsonUtils.toGenericObject(_appendContent+"]", new TypeReference< List<AppendQuestionItem> >(){});
				if(appendQuestionItemList != null && appendQuestionItemList.size() >0){
					for(AppendQuestionItem appendQuestionItem : appendQuestionItemList){
						questionContent += appendQuestionItem.getContent();
					}
				}
				
				if(questionContent != null && !"".equals(questionContent.trim())){
					Object[] obj = textFilterManage.readPathName(questionContent,"question");
					
					if(obj != null && obj.length >0){
						List<String> filePathList = new ArrayList<String>();
						
						
						//删除图片
						List<String> imageNameList = (List<String>)obj[0];		
						for(String imageName :imageNameList){
							filePathList.add(imageName);
						}
						//删除Flash
						List<String> flashNameList = (List<String>)obj[1];		
						for(String flashName :flashNameList){
							filePathList.add(flashName);
						}
						//删除影音
						List<String> mediaNameList = (List<String>)obj[2];		
						for(String mediaName :mediaNameList){
							filePathList.add(mediaName);
						}
						//删除文件
						List<String> fileNameList = (List<String>)obj[3];		
						for(String fileName :fileNameList){
							filePathList.add(fileName);
						}
						
						for(String filePath :filePathList){
							
							
							 //如果验证不是当前用户上传的文件，则不删除
							 if(!questionManage.getFileNumber(FileUtil.getBaseName(filePath.trim())).equals(fileNumber)){
								 continue;
							 }
							
							//替换路径中的..号
							filePath = FileUtil.toRelativePath(filePath);
							filePath = FileUtil.toSystemPath(filePath);
							//删除旧路径文件
							Boolean state = fileManage.deleteFile(filePath);
							if(state != null && state == false){
								 //替换指定的字符，只替换第一次出现的
								filePath = StringUtils.replaceOnce(filePath, "file"+File.separator+"question"+File.separator, "");
								
								//创建删除失败文件
								fileManage.failedStateFile("file"+File.separator+"question"+File.separator+"lock"+File.separator+FileUtil.toUnderline(filePath));
							}
						}
						
					}
				}
				//清空目录
				Boolean state_ = fileManage.removeDirectory("file"+File.separator+"answer"+File.separator+questionId+File.separator);
				if(state_ != null && state_ == false){
					//创建删除失败目录文件
					fileManage.failedStateFile("file"+File.separator+"answer"+File.separator+"lock"+File.separator+"#"+questionId);
				}
			}
			
		}
	}
	
	
	
	/**
	 * 根据用户名称删除用户下的所有答案文件
	 * @param userName 用户名称
	 * @param isStaff 是否为员工
	 */
	public void deleteAnswerFile(String userName, boolean isStaff){
		int firstIndex = 0;//起始页
		int maxResult = 100;// 每页显示记录数
		
		String fileNumber = questionManage.generateFileNumber(userName, isStaff);
		
		while(true){
			List<String> contentList = answerService.findAnswerContentByPage(firstIndex, maxResult,userName,isStaff);
			if(contentList == null || contentList.size() == 0){
				break;
			}
			firstIndex = firstIndex+maxResult;
			for (String content: contentList) { 
				if(content != null && !"".equals(content.trim())){
					//删除图片
					List<String> imageNameList = textFilterManage.readImageName(content,"answer");
					if(imageNameList != null && imageNameList.size() >0){
						for(String imagePath : imageNameList){
							//如果验证不是当前用户上传的文件，则不删除锁
							 if(!questionManage.getFileNumber(FileUtil.getBaseName(imagePath.trim())).equals(fileNumber)){
								 continue;
							 }
							
							
							//替换路径中的..号
							imagePath = FileUtil.toRelativePath(imagePath);
							
							imagePath = FileUtil.toSystemPath(imagePath);
							
							Boolean state = fileManage.deleteFile(imagePath);
							if(state != null && state == false){	
								//替换指定的字符，只替换第一次出现的
								imagePath = StringUtils.replaceOnce(imagePath, "file"+File.separator+"answer"+File.separator, "");
								
								//创建删除失败文件
								fileManage.failedStateFile("file"+File.separator+"answer"+File.separator+"lock"+File.separator+FileUtil.toUnderline(imagePath));
							
							}
						}
					}
				}
			}
		}
	}
	
	
	
	
	
	

	
	/**
	 * 问题编辑器允许使用标签
	 * @return List<String> 类型json格式
	*/
	public String availableTag(){
		List<String> tag = new ArrayList<String>();
		EditorTag editor = settingManage.readQuestionEditorTag();
		if(editor != null){
			//标签区域1
			boolean area_1 = false;
			//标签区域2
			boolean area_2 = false;
			//标签区域3
			boolean area_3 = false;
			
			tag.add("source");
		//	tag.add("|");
			if(editor.isCode()){//代码
				tag.add("code");
				area_1 = true;
			}
			if(editor.isFontname()){//字体
				tag.add("fontname");
				area_1 = true;
			}
			if(editor.isFontsize()){//文字大小
				tag.add("fontsize");
				area_1 = true;
			}
			if(area_1 == true){
		//		tag.add("|");
			}
			
			if(editor.isForecolor()){//文字颜色
				tag.add("forecolor");
				area_2 = true;
			}
			if(editor.isHilitecolor()){//文字背景
				tag.add("hilitecolor");
				area_2 = true;
			}
			if(editor.isBold()){//粗体
				tag.add("bold");
				area_2 = true;
			}
			if(editor.isItalic()){//斜体
				tag.add("italic");
				area_2 = true;
			}
			if(editor.isUnderline()){//下划线
				tag.add("underline");
				area_2 = true;
			}
			if(editor.isRemoveformat()){//删除格式
				tag.add("removeformat");
				area_2 = true;
			}
			if(editor.isLink()){//超级链接
				tag.add("link");
				area_2 = true;
			}
			if(editor.isUnlink()){//取消超级链接
				tag.add("unlink");
				area_2 = true;
			}
			if(area_2 == true){
			//	tag.add("|");
			}
			
			if(editor.isJustifyleft()){//左对齐
				tag.add("justifyleft");
				area_3 = true;
			}
			if(editor.isJustifycenter()){//居中
				tag.add("justifycenter");
				area_3 = true;
			}
			if(editor.isJustifyright()){//右对齐
				tag.add("justifyright");
				area_3 = true;
			}
			if(editor.isInsertorderedlist()){//编号
				tag.add("insertorderedlist");
				area_3 = true;
			}
			if(editor.isInsertunorderedlist()){//项目符号
				tag.add("insertunorderedlist");
				area_3 = true;
			}
			if(area_3 == true){
			//	tag.add("|");
			}
			
			if(editor.isEmoticons()){//插入表情
				tag.add("emoticons");
			}
			if(editor.isImage()){//图片
				tag.add("image");
			}
			/**
			if(editor.isFile()){//文件
				tag.add("insertfile");
			}**/
			if(editor.isMention()){//提及
				tag.add("mention");
			}
			if(editor.isAi()){//人工智能
				tag.add("ai");
			}
			if(editor.isFullscreen()){//全屏显示
				tag.add("fullscreen");
			}
		}
		return JsonUtils.toJSONString(tag);
	}
	
	
	/**
	 * 查询缓存 根据Id查询问题
	 * @param questionId 问题Id
	 * @return
	 */
	@Cacheable(value="questionManage_cache_findById",key="#questionId")
	public Question query_cache_findById(Long questionId){
		return questionService.findById(questionId);
	}
	/**
	 * 删除缓存 根据Id查询问题
	 * @param questionId 问题Id
	 * @return
	 */
	@CacheEvict(value="questionManage_cache_findById",key="#questionId")
	public void delete_cache_findById(Long questionId){
	}
	
	/**
	 * 查询缓存 根据问题Id查询问题标签关联
	 * @param questionId 问题Id
	 * @return
	 */
	@Cacheable(value="questionManage_cache_findQuestionTagAssociationByQuestionId",key="#questionId")
	public List<QuestionTagAssociation> query_cache_findQuestionTagAssociationByQuestionId(Long questionId){
		return questionService.findQuestionTagAssociationByQuestionId(questionId);
	}
	/**
	 * 删除缓存 根据问题Id查询问题标签关联
	 * @param questionId 问题Id
	 * @return
	 */
	@CacheEvict(value="questionManage_cache_findQuestionTagAssociationByQuestionId",key="#questionId")
	public void delete_cache_findQuestionTagAssociationByQuestionId(Long questionId){
	}

	
}
