package com.apobates.forum.trident.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.UriComponentsBuilder;
import com.apobates.forum.core.ad.ActiveDirectoryConnectorFactory;
import com.apobates.forum.core.api.service.TopicService;
import com.apobates.forum.core.api.service.TopicTagService;
import com.apobates.forum.core.entity.Topic;
import com.apobates.forum.event.elderly.ActionEventCulpritor;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.strategy.Strategy;
import com.apobates.forum.strategy.StrategyEntityParam;
import com.apobates.forum.strategy.exposure.impl.TopicDetectionStrategy;
import com.apobates.forum.trident.OnlineDescriptor;
import com.apobates.forum.utils.CommonBean;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.StringSeekUtils;
import com.apobates.forum.utils.TipMessage;
import com.apobates.forum.utils.TipMessageLevelEnum;
/**
 * 话题标签控制器
 * 
 * @author xiaofanku
 * @since 20200115
 */
@Controller
@RequestMapping(value = "/topic/tag")
public class TopicTagController {
	@Autowired
	private TopicTagService topicTagService;
	@Autowired
	private TopicService topicService;
	@Value("${site.domain}")
	private String siteDomain;
	
	//删除(版主和管理员)
	@PostMapping(path = "/delete", produces = "application/json;charset=UTF-8")
	@ResponseBody
	@OnlineDescriptor(action=ForumActionEnum.TOPIC_TAG_DEL, isAjax=true)
	@Strategy(action=ForumActionEnum.TOPIC_TAG_DEL, param=StrategyEntityParam.REFERER, allowRoles={MemberRoleEnum.ADMIN, MemberRoleEnum.MASTER, MemberRoleEnum.BM}, handler=TopicDetectionStrategy.class)
	public TipMessage deleteTagAction(
			@RequestParam("id")long tagId, 
			@RequestHeader(value = "referer", required = false, defaultValue = "") final String referer, 
			@RequestParam(value = "token", required = false, defaultValue = "0")String token, 
			MemberSessionBean mbean, 
			HttpServletRequest request, 
			Model model) {
		//------------------------------来源的话题
		Topic tpObj = ActiveDirectoryConnectorFactory.parseRefererToTopic(referer, siteDomain).orElse(null);
		if(null == tpObj || tpObj.getId() < 1){
			return TipMessage.ofError("因参数丢失操作被中断");
		}
		//------------------------------权限检查
		//  迁至StrategyInterceptorAdapter
		//------------------------------
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, token);
		return TipMessage.Builder.take(()->topicTagService.deleteForTopic(tpObj.getId(), tagId, aec)).success("标签成功删除").error("操作失败");
	}
	
	//添加(并统计词频)(版主和管理员)
	@PostMapping(path = "/add", produces = "application/json;charset=UTF-8")
	@ResponseBody
	@OnlineDescriptor(action=ForumActionEnum.TOPIC_TAG_ADD, isAjax=true)
	@Strategy(action=ForumActionEnum.TOPIC_TAG_ADD, param=StrategyEntityParam.REFERER, allowRoles={MemberRoleEnum.ADMIN, MemberRoleEnum.MASTER, MemberRoleEnum.BM}, handler=TopicDetectionStrategy.class)
	public TipMessage createTagAction(
			@RequestParam("names")String tagNames, 
			@RequestHeader(value = "referer", required = false, defaultValue = "") final String referer, 
			@RequestParam(value = "token", required = false, defaultValue = "0")String token, 
			MemberSessionBean mbean, 
			HttpServletRequest request, 
			Model model) {
		//------------------------------过滤一下
		String newTagNames = Commons.htmlPurifier(tagNames).trim();
		//------------------------------来源的话题
		Optional<Topic> tpObj = ActiveDirectoryConnectorFactory.parseRefererToTopic(referer, siteDomain);
		if(!tpObj.isPresent()){
			return TipMessage.ofError("因参数丢失操作被中断");
		}
		//------------------------------权限检查
		//  迁至StrategyInterceptorAdapter
		//------------------------------获取话题的内容以便词频统计
		Topic topic = topicService.getTopicContent(tpObj.get().getId(), null);
		if(null == topic){
			return TipMessage.ofError("因异常操作被中断");
		}
		int rates = StringSeekUtils.queryWordCountByBM(topic.getTitle()+" "+topic.getContent().getContent(), newTagNames);
		//
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, token);
		long id = topicTagService.create(topic.getId(), newTagNames, rates, aec);
		if(id>0){
			return new TipMessage("标签添加成功", TipMessageLevelEnum.ACC, id+"");
		}
		return TipMessage.ofError("操作失败");
	}
	
	//相关的关键词(从搜索历史上找)
	@GetMapping(path = "/relate.json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public List<CommonBean> getRelateSearchResult(
			@RequestHeader(value = "referer", required = false, defaultValue = "") final String referer, 
			HttpServletRequest request,
			Model model){
		List<String> toggleWords = new ArrayList<>();
		if(Commons.isNotBlank(referer)){
			//从中提取search word
			String decodeURL = "";
			try{
				decodeURL = URLDecoder.decode(referer, "UTF8");
			}catch (UnsupportedEncodingException e) {
				return Collections.emptyList();
			}
			MultiValueMap<String, String> parameters = UriComponentsBuilder.fromUriString(decodeURL).build().getQueryParams();
			List<String> qw = parameters.get("word");
			if(null != qw && !qw.isEmpty()){
				toggleWords.addAll(qw);
			}
		}
		return Collections.emptyList();
	}
	
	//热点标签(从Tag中找出现最多的标签)
	@GetMapping(path = "/hot.json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public List<CommonBean> getHotTopicTag(
			HttpServletRequest request,
			Model model){
		return topicTagService.groupTagForNames(10).entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(entry->new CommonBean(entry.getValue(), entry.getKey())).collect(Collectors.toList());
	}
}
