package com.apobates.forum.trident.controller.admin;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
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.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.apobates.forum.core.api.ImageIOMeta;
import com.apobates.forum.core.api.service.BoardGroupService;
import com.apobates.forum.core.api.service.BoardService;
import com.apobates.forum.core.api.service.TopicService;
import com.apobates.forum.core.entity.Board;
import com.apobates.forum.core.entity.BoardGroup;
import com.apobates.forum.core.entity.ForumEntityStatusEnum;
import com.apobates.forum.core.entity.Topic;
import com.apobates.forum.event.elderly.ActionEventCulpritor;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.trident.controller.form.SectionTermForm;
import com.apobates.forum.trident.controller.form.TopicPublishForm;
import com.apobates.forum.trident.exception.ResourceNotFoundException;
import com.apobates.forum.trident.controller.form.SectionForm;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.FrontPageURL;
import com.apobates.forum.utils.TipMessage;
import com.apobates.forum.utils.lang.EnumArchitecture;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.PageRequest;
import com.apobates.forum.utils.persistence.Pageable;
/**
 * 栏目(原生版块组)/子栏目(原生的版块)/文章(原生的话题)控制器
 * 
 * @author xiaofanku
 * @since 20190928
 */
@Controller
@RequestMapping(value = "/admin/section")
public class AdminSectionArticleController {
	@Autowired
	private BoardGroupService boardGroupService;
	@Autowired
	private BoardService boardService;
	@Autowired
	private TopicService topicService;
	@Autowired
	private ImageIOMeta imageIOConfig;
	@Value("${site.pageSize}")
	private int pageSize;
	
	//栏目列表
	@GetMapping(path="/")
	public String listPage(HttpServletRequest request, Model model) {
		List<BoardGroup> rs = boardGroupService.getAllOrigin().collect(Collectors.toList());
		model.addAttribute("rs", rs);
		return "admin/section/index";
	}
	//新增|编辑栏目
	@GetMapping(path="/edit")
	public String editForm(
			@RequestParam(name="section", required=false, defaultValue="0") int sectionId, 
			HttpServletRequest request, 
			Model model){
		BoardGroup section = boardGroupService.getOriginById(sectionId).orElseGet(BoardGroup::new);
		SectionForm form = new SectionForm();
		form.setRecord(section.getId()); //0
		form.setStatus((section.getId()==0)?true:section.isStatus()); //true
		form.setDirect(section.getDirectoryNames()); //""
		form.setTitle(section.getTitle());
		form.setDescription(section.getDescription());
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		return "admin/section/edit";
	}
	@PostMapping(path="/edit")
	public String editAction(
			@ModelAttribute("form")SectionForm form,
			HttpServletRequest request, 
			Model model){
		String directName = Commons.getAlphaNumberCharacter(form.getDirect());
		if(!Commons.isNotBlank(directName) || directName.length() < 4){
			model.addAttribute("errors", "目录名不可用或名称小于4个字符");
			//
			form.setDirect(directName);
			form.setToken(Commons.randomAlphaNumeric(8));
			model.addAttribute("form", form);
			return "admin/section/edit";
		}
		boolean symbol=false;String errMsg=null;
		try{
			if(form.isUpdate()){
				symbol = boardGroupService.editSection(form.getIntegerRecord(), form.getTitle(), form.getDescription(), directName, form.getBooleanStatus()).orElse(false);
			}else{
				symbol = boardGroupService.buildOrigin(form.getTitle(), form.getDescription(), directName, form.getBooleanStatus())>0;
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		if(symbol) {
			return "redirect:/admin/section/";
		}
		model.addAttribute("errors", Commons.optional(errMsg, form.getActionTitle()+"栏目操作失败"));
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		return "admin/section/edit";
	}
	//所有栏目
	@GetMapping(path="/list/json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Integer,String> getAllForJson(
			@RequestParam(name="ids", required=false, defaultValue="") String idString, 
			HttpServletRequest request, 
			Model model){
		Set<Integer> idList = Commons.toIntegerSet(idString);
		return boardGroupService.getAllOriginById(idList).collect(Collectors.toMap(BoardGroup::getId, BoardGroup::getTitle));
	}
	// 栏目目录名称唯一性检查
	@GetMapping(path = "/direct/unique")
	public ResponseEntity<String> checkSectionDirectNames(
			@RequestParam("direct")String directoryNames, 
			@RequestParam("record")int sectionId, 
			HttpServletRequest request, 
			Model model){
		String errMsg=null; boolean symbol = false;
		try{
			Optional<Boolean> result = boardGroupService.checkOriginDirectNameUnique(directoryNames, sectionId);
			if(result.orElse(false)){
				errMsg = result.get()?"可以使用":"未知的错误";
				symbol = true;
			}
		}catch(IllegalStateException e){
			errMsg= e.getMessage();
		}
		//
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.set("Content-Type", "text/plain; charset=UTF-8"); 
		HttpStatus hs = symbol?HttpStatus.OK:HttpStatus.BAD_REQUEST;
		return new ResponseEntity<>(Commons.optional(errMsg, "目录名称唯一性检测失败"), responseHeaders, hs);
	}
	
	
	//子栏目
	@GetMapping(path="/term")
	public String termPage(
			@RequestParam(name="s", required=false, defaultValue="0")int sectionId, 
			HttpServletRequest request, 
			Model model){
		List<Board> rs = boardService.getAllTermByOriginId(sectionId);
		model.addAttribute("rs", rs); 
		model.addAttribute("paramSection", sectionId); //页面这个值等于0不能新增子栏目
		return "admin/section/term";
	}
	//新增|编辑子栏目
	@GetMapping(path="/term/edit")
	public String termEditForm(
			@RequestParam(name="s", required=false, defaultValue="0")int sectionId, 
			@RequestParam(name="term", required=false, defaultValue="0") long termId, 
			HttpServletRequest request, 
			Model model){
		Board term = boardService.getTermById(termId).orElseGet(Board::new);
		SectionTermForm form = new SectionTermForm();
		form.setSection(term.getVolumesId()+""); //sectionId+""
		form.setDirect(term.getDirectoryNames()); //""
		form.setTitle(term.getTitle());
		form.setDescription(term.getDescription());
		form.setRecord(term.getId());
		try{
			form.setEntityStatus(term.getStatus());
		}catch(NullPointerException e){
			form.setEntityStatus(ForumEntityStatusEnum.ACTIVE);
		}
		//补刀
		if(0 == termId && sectionId>0){
			form.setSection(sectionId+"");
		}
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		Map<Integer,String> boardStatusData = EnumArchitecture.getInstance(ForumEntityStatusEnum.class);
		model.addAttribute("boardStatusData", boardStatusData);
		return "admin/section/term_edit";
	}
	@PostMapping(path="/term/edit")
	public String termEditAction(
			@ModelAttribute("form")SectionTermForm form,
			HttpServletRequest request, 
			Model model){
		String directName = Commons.getAlphaNumberCharacter(form.getDirect());
		if(!Commons.isNotBlank(directName) || directName.length() < 4){
			model.addAttribute("errors", "目录名不可用或名称小于4个字符");
			//
			form.setDirect(directName);
			form.setToken(Commons.randomAlphaNumeric(8));
			model.addAttribute("form", form);
			//
			Map<Integer,String> boardStatusData = EnumArchitecture.getInstance(ForumEntityStatusEnum.class);
			model.addAttribute("boardStatusData", boardStatusData);
			return "admin/section/term_edit";
		}
		boolean symbol=false;String errMsg=null;
		try{
			if(form.isUpdate()){
				symbol = boardService.editTerm(form.getLongRecord(), form.getTitle(), form.getDescription(), directName, form.getEnumEntityStatus()).orElse(false);
			}else{
				symbol = boardService.buildOrigin(form.getIntegerSection(), form.getTitle(), form.getDescription(), directName, form.getEnumEntityStatus())>0;
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		if(symbol) {
			return "redirect:/admin/section/term?s="+form.getSection();
		}
		model.addAttribute("errors", Commons.optional(errMsg, form.getActionTitle()+"子栏目操作失败"));
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		Map<Integer,String> boardStatusData = EnumArchitecture.getInstance(ForumEntityStatusEnum.class);
		model.addAttribute("boardStatusData", boardStatusData);
		return "admin/section/term_edit";
	}
	//指定栏目的所有子栏目
	@GetMapping(path="/term/all/json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Long,String> getAllTermForJson(
			@RequestParam("parent")int sectionId, 
			HttpServletRequest request, 
			Model model){
		return boardService.getAllTermByOriginId(sectionId).stream().collect(Collectors.toMap(Board::getId, Board::getTitle));
	}
	//指定的子栏目
	@GetMapping(path="/term/list/json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Long,String> getAllTermForIdJson(
			@RequestParam("ids") String termIdString, 
			HttpServletRequest request, 
			Model model){
		Set<Long> idList = Commons.toLongSet(termIdString);
		return boardService.getAllTermById(idList).collect(Collectors.toMap(Board::getId, Board::getTitle));
	}
	// 子栏目目录名称唯一性检查
	@GetMapping(path = "/term/direct/unique")
	public ResponseEntity<String> checkTermDirectNames(
			@RequestParam("direct")String termDirectoryNames, 
			@RequestParam("record")long termId, 
			HttpServletRequest request, 
			Model model){
		String errMsg=null; boolean symbol = false;
		try{
			Optional<Boolean> result = boardService.checkTermDirectNameUnique(termDirectoryNames, termId);
			if(result.orElse(false)){
				errMsg = result.get()?"可以使用":"未知的错误";
				symbol = true;
			}
		}catch(IllegalStateException e){
			errMsg = e.getMessage();
		}
		//
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.set("Content-Type", "text/plain; charset=UTF-8"); 
		HttpStatus hs = symbol?HttpStatus.OK:HttpStatus.BAD_REQUEST;
		return new ResponseEntity<>(Commons.optional(errMsg, "目录名称唯一性检测失败"), responseHeaders, hs);
	}
	
	
	
	//子栏目最近的文章
	@GetMapping(path="/article")
	public String articlePage(
			HttpServletRequest request, 
			Model model){
		List<Topic> rs = topicService.getRecentTermArticle(pageSize).collect(Collectors.toList());
		model.addAttribute("rs", rs);
		return "admin/section/article";
	}
	//子栏目下的文章
	@GetMapping(path="/article/list/{id}.xhtml")
	public String articleListPage(
			@PathVariable("id") long termId,
			@RequestParam(value = "p", required = false, defaultValue = "1") int page,
			HttpServletRequest request, 
			Model model){
		Board term = boardService.get(termId).orElseThrow(()->new ResourceNotFoundException("子栏目不存在或暂时无法访问"));
		FrontPageURL fpbuild = new FrontPageURL(request.getContextPath() + "/admin/section/article/list/"+termId+".xhtml").addPageSize("number", pageSize);
		Pageable pr = new PageRequest(page, fpbuild.getPageSize());
		Page<Topic> rs = topicService.getTermArticle(termId, pr);
		model.addAttribute("rs", rs.getResult().collect(Collectors.toList()));
		model.addAttribute("pageData", pr.toData(fpbuild, rs.getTotalElements()));
		model.addAttribute("term", term);
		return "admin/section/article_list";
	}
	//文章内容页
	@GetMapping(path="/article/{id}.xhtml")
	public String articleViewPage(
			@PathVariable("id") long articleId,
			HttpServletRequest request,
			Model model){
		Topic article = topicService.getTermArticleContent(articleId, imageIOConfig);
		if (article==null) {
			throw new ResourceNotFoundException("文章不存在或暂时无法访问");
		}
		model.addAttribute("article", article);
		return "admin/section/article_view";
	}
	
	
	//新文章
	@GetMapping(path="/article/publish")
	public String createArticleForm(
			@RequestParam(name="section", required=false, defaultValue="-1") int sectionId,
			@RequestParam(name="term", required=false, defaultValue="0") long termId,
			HttpServletRequest request, 
			Model model){
		TopicPublishForm form = new TopicPublishForm();
		form.setBoard(termId+"");
		form.setVolumes(sectionId+"");
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		return "admin/section/article_create";
	}
	@PostMapping(path="/article/publish")
	public String createArticleAction(
			@ModelAttribute("form")TopicPublishForm form, 
			MemberSessionBean mbean,
			HttpServletRequest request, 
			Model model){
		int sectionId=form.getIntegerVolumes();
		long termId=form.getLongBoard();
		String errMsg=null;
		//
		if(termId>0 && sectionId>0) { //有可能在默认分组中
			ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, form.getToken());
			try{
				long data = topicService.createTermArticle(
					sectionId, 
					termId, 
					form.getTitle(), 
					form.getContent(), 
					imageIOConfig, 
					aec);
				if(data>0) {
					return "redirect:/admin/section/article/"+data+".xhtml";
				}
			}catch(IllegalStateException e){
				errMsg=e.getMessage();
			}
		}
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("errors", Commons.optional(errMsg, "发布文章操作失败"));
		return "admin/section/article_create";
	}
	//编辑文章
	@GetMapping(path="/article/modify")
	public String modifyArticleForm(
			@RequestParam("id") long articleId,
			HttpServletRequest request, 
			Model model){
		Topic article = topicService.getTermArticleContent(articleId, imageIOConfig);
		if (article==null) {
			throw new ResourceNotFoundException("文章不存在或暂时无法访问");
		}
		TopicPublishForm form = new TopicPublishForm();
		form.setBoard(article.getBoardId()+"");
		form.setVolumes(article.getVolumesId()+"");
		form.setRecord(article.getId());
		//只允许编辑这个项
		form.setTitle(article.getTitle());
		form.setContent(article.getContent().getContent());
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		return "admin/section/article_modify";
	}
	@PostMapping(path="/article/modify")
	public String modifyArticleAction(
			@ModelAttribute("form")TopicPublishForm form, 
			MemberSessionBean mbean,
			HttpServletRequest request, 
			Model model){
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, form.getToken());
		String errMsg=null;
		try{
			boolean symbol = topicService.editTermArticle(
				form.getLongRecord(), 
				form.getTitle(), 
				form.getContent(), 
				imageIOConfig, 
				aec).orElse(false);
			if(symbol){
				return "redirect:/admin/section/article/"+form.getLongRecord()+".xhtml";
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("errors", Commons.optional(errMsg, "编辑文章操作失败"));
		return "admin/section/article_modify";
	}
	
	//删除文章
	@PostMapping(path="/article/remove", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public TipMessage removeArticleAction(
			@RequestParam("id")long articleId,
			@RequestParam("term")long termId, 
			MemberSessionBean mbean,
			HttpServletRequest request,
			Model model){
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, "");
		return TipMessage.Builder.take(()->topicService.removeTermArticle(articleId, termId, aec)).success("文章删除成功").error("操作失败");
	}
}
