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

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.event.elderly.ForumActionEnum;
import com.apobates.forum.member.entity.ForumScoreRole;
import com.apobates.forum.member.service.ForumScoreRoleService;
import com.apobates.forum.thrones.admin.controller.form.ForumScoreRoleForm;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.validation.BindingResult;

/**
 * 积分规则控制器
 *
 * @author xiaofanku
 * @since 20190406
 */
@Controller
@RequestMapping(value = "/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() + "");
        model.addAttribute("form", form);
        //
        model.addAttribute("actionSet", allowActionSet(data.getId()));
        return "admin/score_role/edit";
    }
    
    @PostMapping(path = "/edit")
    public String editLevelAction(
            HttpServletRequest request, 
            @Valid @ModelAttribute("form") ForumScoreRoleForm form, 
            BindingResult bindingResult,
            Model model) {
        if (bindingResult.hasErrors()) {
            model.addAttribute("form", form);
            //
            model.addAttribute("actionSet", allowActionSet(form.getIntegerRecord()));
            return "admin/score_role/edit";
        }
        Optional<ForumActionEnum> action = form.getEnumAction();
        if (!action.isPresent()) {
            model.addAttribute("errors", "动作枚举实例失败");
            model.addAttribute("form", form);
            //
            model.addAttribute("actionSet", allowActionSet(form.getIntegerRecord()));
            return "admin/score_role/edit";
        }
        ForumScoreRole data = new ForumScoreRole();
        data.setStatus(form.getBooleanStatus());
        data.setAction(action.get());
        data.setDegree(form.getIntegerDegree());
        data.setLevel(form.getIntegerLevel());
        data.setScore(form.getDoubleScore());
        
        boolean symbol;
        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();
        }
        if (symbol) {
            return "redirect:/score/role/";
        }
        model.addAttribute("errors", form.getActionTitle() + "积分规则操作失败");
        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));
    }
}