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

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
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.trident.controller.form.BoardConfigForm;
import com.apobates.forum.trident.controller.form.BoardForm;
import com.apobates.forum.trident.fileupload.ImageStorageExecutor;
import com.apobates.forum.core.api.service.BoardConfigService;
import com.apobates.forum.core.api.service.BoardGroupService;
import com.apobates.forum.core.api.service.BoardService;
import com.apobates.forum.core.api.service.BoardStatsService;
import com.apobates.forum.core.entity.Board;
import com.apobates.forum.core.entity.BoardConfig;
import com.apobates.forum.core.entity.BoardGroup;
import com.apobates.forum.core.entity.BoardStats;
import com.apobates.forum.core.entity.ForumEntityStatusEnum;
import com.apobates.forum.event.elderly.ActionEventCulpritor;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.utils.CommonBean;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.TipMessage;
import com.apobates.forum.utils.lang.EnumArchitecture;
/**
 * 版块控制器
 * 
 * @author xiaofanku@live.cn
 * @since 20190321
 */
@Controller
@RequestMapping(value = "/admin/board")
public class AdminBoardController {
	@Autowired
	private BoardService boardService;
	@Autowired
	private BoardGroupService boardGroupService;
	@Autowired
	private BoardConfigService boardConfigService;
	@Autowired
	private BoardStatsService boardStatsService;
	@Autowired
	private ImageStorageExecutor imageStorageExecutor;
	@Value("${site.pageSize}")
	private int pageSize;
	private final static Logger logger = LoggerFactory.getLogger(AdminBoardController.class);
	
	//版块
	@GetMapping(path="/")
	public String listPage(
			@RequestParam(name="volume", required=false, defaultValue="-1") int volumesId, 
			HttpServletRequest request, 
			Model model) {
		Stream<Board> rs = (volumesId>=0)?boardService.getAllByVolumesId(volumesId):boardService.getAll();
		model.addAttribute("rs", rs.collect(Collectors.toList()));
		model.addAttribute("paramVolumes", volumesId);
		//举报话题类型是否被关联了提示
		//意见反馈话题类型是否被关联了提示
		return "admin/board/index";
	}
	//编辑版块
	@GetMapping(path="/edit")
	public String boardForm(
			@RequestParam(name="id", required=false, defaultValue="0") long id, 
			@RequestParam(name="volume", required=false, defaultValue="-1") int volumesId, 
			HttpServletRequest request, 
			Model model) {
		BoardForm form = new BoardForm();
		Board b = boardService.get(id).orElse(Board.empty(id));
		form.setRecord(id);
		form.setTitle(b.getTitle());
		form.setDescription(b.getDescription());
		form.setImageAddr(b.getImageAddr()); //编码后的图标图片地址|解码由标签负责
		form.setEntityStatus(b.getStatus());
		form.setRanking(b.getRanking()+"");
		form.setVolumesId(b.getVolumesId()+"");
		if(id==0 && volumesId>0) {
			form.setVolumesId(volumesId+"");
		}
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		Map<Integer,String> boardStatusData = EnumArchitecture.getInstance(ForumEntityStatusEnum.class);
		model.addAttribute("boardStatusData", boardStatusData);
		return "admin/board/edit";
	}
	@PostMapping(path="/edit")
	public String boardAction(
			@ModelAttribute("form") BoardForm form, 
			HttpServletRequest request, 
			Model model) {
		Board b = new Board();
		b.setTitle(form.getTitle());
		b.setDescription(form.getDescription());
		b.setRanking(form.getIntegerRanking()); 
		b.setVolumesId(form.getIntegerVolumesId()); //没有选择时为默认版块组
		b.setStatus(form.getEnumEntityStatus());
		//------------------------------------------------------------编码图标图片的地址
		String icoImageAddr = form.getEncodeIcoAddr(imageStorageExecutor);
		logger.info("[AFU][B-CTL]encode image addr: "+icoImageAddr);
		if(icoImageAddr != null){
			b.setImageAddr(icoImageAddr);
		}
		//------------------------------------------------------------
		boolean symbol = false; 
		String jumpPage="/admin/board/?volume="+b.getVolumesId();
		String errMsg=null;
		try{
			if(form.isUpdate()) {
				symbol = boardService.edit(form.getLongRecord(), b).orElse(false);
			}else {
				symbol = boardService.create(b.getVolumesId(), b.getTitle(), b.getDescription(), b.getImageAddr(), b.getStatus(), b.getRanking()).isPresent();
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		if(symbol) {
			return "redirect:"+jumpPage;
		}
		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/board/edit";
	}
	//版块的配置
	@GetMapping(path="/config")
	public String boardConfigForm(
			@RequestParam("id")long boardId, 
			@RequestParam("volumes") int boardGroupId, 
			HttpServletRequest request, 
			Model model) {
		BoardConfigForm form = new BoardConfigForm();
		BoardConfig config = boardConfigService.getByBoardId(boardId).orElse(BoardConfig.defaultConfig(boardId));
		//boolean
		form.setReadWrite(config.isReadWrite());
		form.setIpFilter(config.isIpFilter());
		//读
		form.setReadMinScore(config.getReadMinScore()+"");
		form.setReadLowMemberGroup(config.getReadLowMemberGroup().getSymbol()+"");
		form.setReadLowMemberRole(config.getReadLowMemberRole().getSymbol()+"");
		form.setReadLowMemberLevel(config.getReadLowMemberLevel()+"");
		//写
		form.setEditMinute(config.getEditMinute()+"");
		form.setWriteMinInterrupt(config.getWriteMinInterrupt()+"");
		form.setWriteMinScore(config.getWriteMinScore()+"");
		form.setWriteLowMemberGroup(config.getWriteLowMemberGroup().getSymbol()+"");
		form.setWriteLowMemberRole(config.getWriteLowMemberRole().getSymbol()+"");
		form.setWriteLowMemberLevel(config.getWriteLowMemberLevel()+"");
		//
		form.setRecord(config.getId());
		form.setBoardId(boardId+"");
		form.setVolumesId(boardGroupId+"");
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
		model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
		return "admin/board/config";
	}
	@PostMapping(path="/config")
	public String boardConfigAction(
			@ModelAttribute("form")BoardConfigForm form, 
			MemberSessionBean mbean, 
			HttpServletRequest request, 
			Model model) {
		Long boardId = form.getLongBoardId();
		if(boardId==0) {
			form.setToken(Commons.randomAlphaNumeric(8));
			model.addAttribute("form", form);
			//
			model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
			model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
			//
			model.addAttribute("errors", "版块参数丢失");
			return "admin/board/config";
		}
		BoardConfig config = new BoardConfig();
		config.setBoardId(boardId);
		//boolean
		config.setReadWrite(form.getBooleanReadWrite());
		config.setIpFilter(form.getBooleanIpFileter());
		//读
		config.setReadMinScore(form.getIntegerReadMinScore());
		MemberGroupEnum rmg = EnumArchitecture.getInstance(form.getIntegerReadLowMemberGroup(), MemberGroupEnum.class).orElse(MemberGroupEnum.GUEST);
		config.setReadLowMemberGroup(rmg);
		MemberRoleEnum rmr = EnumArchitecture.getInstance(form.getIntegerReadLowMemberRole(), MemberRoleEnum.class).orElse(MemberRoleEnum.NO);
		config.setReadLowMemberRole(rmr);
		config.setReadLowMemberLevel(form.getIntegerReadLowMemberLevel());
		//写
		config.setEditMinute(form.getIntegerEditMinute());
		config.setWriteMinInterrupt(form.getIntegerWriteMinInterrupt());
		config.setWriteMinScore(form.getIntegerWriteMinScore());
		MemberGroupEnum wmg = EnumArchitecture.getInstance(form.getIntegerWriteLowMemberGroup(), MemberGroupEnum.class).orElse(MemberGroupEnum.CARD);
		config.setWriteLowMemberGroup(wmg);
		MemberRoleEnum wmr = EnumArchitecture.getInstance(form.getIntegerWriteLowMemberRole(), MemberRoleEnum.class).orElse(MemberRoleEnum.NO);
		config.setWriteLowMemberRole(wmr);
		config.setWriteLowMemberLevel(form.getIntegerWriteLowMemberLevel());
		
		Optional<Boolean> data=Optional.empty(); String errMsg=null;
		if(form.isUpdate()) {
			//long id, int boardGroupId, long configId, BoardConfig updateConfig, ActionEventCulpritor culpritor
			ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, form.getToken());
			try{
				data = boardService.editBoardConfig(
					form.getLongBoardId(), 
					form.getIntegerVolumesId(), 
					form.getLongRecord(), 
					config, 
					aec);
			}catch(IllegalStateException e){
				errMsg=e.getMessage();
			}
		}else {
			try{
				data = boardConfigService.create(config.getBoardId(), config);
			}catch(IllegalStateException e){
				errMsg=e.getMessage();
			}
		}
		if(data.orElse(false)) {
			return "redirect:/admin/board/";
		}
		model.addAttribute("errors", Commons.optional(errMsg, "版块设置操作失败"));
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
		model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
		return "admin/board/config";
	}
	//所有版块
	@GetMapping(path="/json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Long,String> getAllBoardForJson(HttpServletRequest request, Model model){
		return boardService.getAll().collect(Collectors.toMap(Board::getId, Board::getTitle));
	}
	//版块统计
	@GetMapping(path="/stats")
	public String getBoardStats(
			@RequestParam("id")long boardId, 
			@RequestParam("volume")int boardGroupId, 
			HttpServletRequest request, 
			Model model){
		BoardStats bs = boardStatsService.getByBoard(boardId).orElse(new BoardStats(boardId, boardGroupId));
		model.addAttribute("stats", bs);
		return "admin/board/stats";
	}
	//锁定
	@PostMapping(path="/lock", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public TipMessage lockBoardAction(
			@RequestParam("id")long boardId, 
			@RequestParam("volumes") int boardGroupId, 
			MemberSessionBean mbean, 
			HttpServletRequest request,
			Model model){
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, "");
		return TipMessage.Builder.take(()->boardService.lock(boardId, boardGroupId, aec)).success("成功锁定版块").error("操作失败");
	}
	//解锁
	@PostMapping(path="/lock/remove", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public TipMessage removeLockBoardAction(
			@RequestParam("id")long boardId, 
			@RequestParam("volumes") int boardGroupId, 
			MemberSessionBean mbean,
			HttpServletRequest request,
			Model model){
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, "");
		return TipMessage.Builder.take(()->boardService.releaseLock(boardId, boardGroupId, aec)).success("成功解锁版块").error("操作失败");
	}
	//删除
	@PostMapping(path="/remove", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public TipMessage removeBoardAction(
			@RequestParam("id")long boardId, 
			@RequestParam("volumes") int boardGroupId, 
			MemberSessionBean mbean,
			HttpServletRequest request,
			Model model){
		ActionEventCulpritor aec = ActionEventCulpritor.getInstance(mbean.getMid(), mbean.getNickname(), request, "");
		return TipMessage.Builder.take(()->boardService.remove(boardId, boardGroupId, aec)).success("版块删除成功").error("操作失败");
	}
	//查看指定的版块的名称
	@GetMapping(path="/list.json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Long,String> getAllForIdJson(
			@RequestParam("ids") String idString, 
			HttpServletRequest request, 
			Model model){
		return boardService.getAllById(Commons.toLongSet(idString));
	}
	@GetMapping(path="/lazy.json", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<Long,String> getBoardForBoardGroup(
			@RequestParam("parent")int boardGroupId,
			HttpServletRequest request, 
			Model model){
		Map<Long,String> data = new HashMap<>();
		//补上一个空位.大版主不用选择具体的版块
		data.put(0L, "选择版块");
		Map<Long,String> rs = boardService.getAllByVolumesId(boardGroupId).collect(Collectors.toMap(Board::getId, Board::getTitle));
		data.putAll(rs);
		return data;
	}
	//加载版块组和版块的名称
	@GetMapping(path="/load", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public Map<String,CommonBean> dynamicQueryTitleData(
			@RequestParam("volume")int boardGroupId, 
			@RequestParam("board")long boardId,
			HttpServletRequest request, 
			Model model){
		Map<String,CommonBean> data = new HashMap<>();
		//
		BoardGroup boardGroup = boardGroupService.get(boardGroupId).orElse(BoardGroup.getDefault());
		data.put("volume", new CommonBean(boardGroup.getId(), boardGroup.getTitle()));
		//
		Board board = boardService.get(boardId).orElse(Board.empty(boardId));
		data.put("board", new CommonBean(board.getId(), board.getTitle()));
		return data;
	}
	//加载版块的标题
	@GetMapping(path="/title", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public CommonBean getBoardTitle(
			@RequestParam("id")long id, 
			HttpServletRequest request,
			Model model){
		if(id == 0){
			return new CommonBean(0, "所有");
		}
		String title="版块";
		Optional<Board> board = boardService.get(id);
		if(board.isPresent()){
			title = board.get().getTitle();
		}
		return new CommonBean(id, title);
	}
}
