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

import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
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 com.apobates.forum.trident.controller.form.ForumScoreRoleForm;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.member.api.service.ForumScoreRoleService;
import com.apobates.forum.member.entity.ForumScoreRole;
import com.apobates.forum.utils.Commons;
/**
 * 积分规则控制器
 * 
 * @author xiaofanku
 * @since 20190406
 */
@Controller
@RequestMapping(value = "/admin/score/role")
public class AdminForumScoreRoleController {
	@Autowired
	private ForumScoreRoleService forumScoreRoleService;
	
	@GetMapping(path="/")
	public String listPage(HttpServletRequest request, Model model) {
		//所有规则
		Stream<ForumScoreRole> rs = forumScoreRoleService.getAll();
		model.addAttribute("rs", rs.collect(Collectors.toList()));
		return "admin/score_role/index";
	}
	//新增|编辑
	@GetMapping(path="/edit")
	public String editLevelForm(@RequestParam(name="id", required=false, defaultValue="0")int id, HttpServletRequest request, Model model) {
		ForumScoreRole data = forumScoreRoleService.get(id).orElse(ForumScoreRole.empty());
		ForumScoreRoleForm form = new ForumScoreRoleForm();
		form.setStatus(data.isStatus());
		form.setRecord(data.getId());
		form.setAction(data.getAction());
		form.setDegree(data.getDegree()+"");
		form.setLevel(data.getLevel()+"");
		form.setScore(data.getScore()+"");
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("actionSet", allowActionSet(form.getIntegerRecord()));
		return "admin/score_role/edit";
	}
	@PostMapping(path="/edit")
	public String editLevelAction(@ModelAttribute("form")ForumScoreRoleForm form, HttpServletRequest request, Model model) {
		ForumScoreRole data = new ForumScoreRole();
		data.setStatus(form.getBooleanStatus());
		//
		ForumActionEnum action = form.getEnumAction();
		if(action == null) {
			model.addAttribute("errors", "不被接受的操作类型");
			//
			form.setToken(Commons.randomAlphaNumeric(8));
			model.addAttribute("form", form);
			//
			model.addAttribute("actionSet", allowActionSet(form.getIntegerRecord()));
			return "admin/score_role/edit";
		}
		data.setAction(action);
		data.setDegree(form.getIntegerDegree());
		data.setLevel(form.getIntegerLevel());
		data.setScore(form.getDoubleScore());
		
		boolean symbol = false;String errMsg=null;
		try{
			if(form.isUpdate()) {
				symbol = forumScoreRoleService.edit(form.getIntegerRecord(), data).orElse(false);
			}else {
				symbol = forumScoreRoleService.create(data.getAction(), data.getDegree(), data.getLevel(), data.getScore(), data.isStatus()).isPresent();
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		if(symbol) {
			return "redirect:/admin/score/role/";
		}
		model.addAttribute("errors", Commons.optional(errMsg, form.getActionTitle()+"积分规则操作失败"));
		//
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		//
		model.addAttribute("actionSet", allowActionSet(form.getIntegerRecord()));
		return "admin/score_role/edit";
	}

	// 内置的积分动作定义
	private EnumSet<ForumActionEnum> nativeScoreActionSet() {
		List<ForumActionEnum> all = Arrays.asList(ForumActionEnum.TOPIC_PUBLISH, ForumActionEnum.POSTS_REPLY,
				ForumActionEnum.TOPIC_TOP, ForumActionEnum.TOPIC_BEST, ForumActionEnum.TOPIC_DEL,
				ForumActionEnum.TOPIC_SHARE, ForumActionEnum.POSTS_DEL, ForumActionEnum.MEMBER_LOGIN,
				ForumActionEnum.MEMBER_REGISTER);
		return EnumSet.copyOf(all);
	}

	private Map<Integer, String> allowActionSet(final int modifyScoreId) {
		// 已经定义的|忽略现在编辑的积分规则记录
		EnumSet<ForumActionEnum> existsActions = forumScoreRoleService.getAll()
				.filter(srs -> srs.getId() != modifyScoreId).map(ForumScoreRole::getAction)
				.collect(Collectors.toCollection(() -> EnumSet.noneOf(ForumActionEnum.class)));
		EnumSet<ForumActionEnum> definedActions = nativeScoreActionSet();
		// 两者的差集为未定义的
		// 编辑时当前的值不丢了吗?
		definedActions.removeAll(existsActions);
		return definedActions.stream().collect(Collectors.toMap(ForumActionEnum::getSymbol, ForumActionEnum::getTitle));
	}
}
