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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
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 org.springframework.web.bind.annotation.ResponseBody;
import com.apobates.forum.core.entity.BoardModerator;
import com.apobates.forum.core.entity.BoardModeratorRoleHistory;
import com.apobates.forum.core.entity.ModeratorLevelEnum;
import com.apobates.forum.core.entity.proxy.BoardModeratorReplica;
import com.apobates.forum.core.service.BoardModeratorActionIndexService;
import com.apobates.forum.core.service.BoardModeratorRoleHistoryService;
import com.apobates.forum.core.service.BoardModeratorService;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.service.MemberService;
import com.apobates.forum.thrones.admin.controller.form.BoardModeratorForm;
import com.apobates.forum.thrones.admin.controller.form.BoardModeratorPermissionForm;
import com.apobates.forum.thrones.admin.controller.helper.AdminUtils;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.lang.CommonBean;
import com.apobates.forum.utils.TipMessage;
import com.apobates.forum.utils.lang.EnumArchitecture;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Function;

/**
 * 版块版主控制器
 *
 * @author xiaofanku@live.cn
 * @since 20190322
 */
@Controller
@RequestMapping(value = "/board/moderator")
public class AdminBoardModeratorController {
    @Autowired
    private BoardModeratorService boardModeratorService;
    @Autowired
    private BoardModeratorActionIndexService boardModeratorActionIndexService;
    @Autowired
    private BoardModeratorRoleHistoryService boardModeratorRoleHistoryService;
    @Autowired
    private MemberService memberService;
    
    //所有版主|某版块的版主
    @GetMapping(path = "/")
    public String boardModeratorPage(
            @RequestParam(name = "board", required = false, defaultValue = "0") long boardId,
            @RequestParam(name = "volume", required = false, defaultValue = "0") int volumesId,
            HttpServletRequest request,
            Model model) {
        Stream<BoardModeratorReplica> rs = (boardId > 0) ? boardModeratorService.getAllUsedByBoardId(volumesId, boardId) : boardModeratorService.getAll();
        model.addAttribute("rs", rs.collect(Collectors.toList()));
        
        model.addAttribute("paramBoard", boardId);
        model.addAttribute("paramVolumes", volumesId);
        return "admin/board_moderator/index";
    }
    //编辑版主
    @GetMapping(path = "/edit")
    public String boardModeratorForm(
            @RequestParam(name = "id", required = false, defaultValue = "0") long id,
            @RequestParam(name = "board", required = false, defaultValue = "0") long boardId,
            @RequestParam(name = "volume", required = false, defaultValue = "0") int volumesId,
            HttpServletRequest request,
            Model model) {
        BoardModeratorForm form = new BoardModeratorForm();
        BoardModerator bm = boardModeratorService.get(id).orElse(BoardModerator.empty());
        form.setRecord(bm.getId());
        form.setStatus(bm.isStatus());
        //大版主
        form.setBoardId(bm.getBoardId() + "");
        form.setVolumesId(bm.getVolumesId() + "");
        form.setMemberId(bm.getMemberId() + "");
        form.setMemberNames(bm.getMemberNickname());
        form.setLevel(bm.getLevel());
        if (id == 0 && boardId > 0) {
            form.setBoardId(boardId + "");
        }
        if (id == 0 && volumesId > 0) {
            form.setVolumesId(volumesId + "");
        }
        model.addAttribute("form", form);
        //
        Map<Integer, String> levelData = EnumArchitecture.getInstance(ModeratorLevelEnum.class);
        model.addAttribute("levelData", levelData);
        return "admin/board_moderator/edit";
    }
    
    @PostMapping(path = "/edit")
    public String boardModeratorAction(
            @ModelAttribute("form") BoardModeratorForm form,
            HttpServletRequest request,
            Model model) {
        BoardModerator bm = new BoardModerator();
        bm.setVolumesId(form.getIntegerVolumes());
        bm.setBoardId(form.getLongBoard());
        bm.setMemberId(form.getLongMember());
        bm.setMemberNickname(form.getMemberNames());
        bm.setStatus(form.getBooleanStatus());
        bm.setLevel(form.getEnumLevel());
        
        boolean symbol=false;
        String jumpLink = "/board/moderator/?board=" + bm.getBoardId() + "&volume=" + bm.getVolumesId();
        if (form.isUpdate()) {
            symbol = boardModeratorService.edit(form.getLongRecord(), bm).orElse(false);
        } else {
            Member m = memberService.get(bm.getMemberId()).orElse(Member.empty(bm.getMemberId()));
            Optional<BoardModerator> rObj = boardModeratorService.create(bm.getVolumesId(), bm.getBoardId(), m, bm.getLevel());
            if (rObj.isPresent()) {
                symbol = true;
                jumpLink = "/board/moderator/permission?id=" + rObj.get().getId(); //进行授权
            }
        }
        if (symbol) {
            return "redirect:" + jumpLink;
        }
        model.addAttribute("errors", form.getActionTitle() + "版主操作失败");
        model.addAttribute("form", form);
        //
        Map<Integer, String> levelData = EnumArchitecture.getInstance(ModeratorLevelEnum.class);
        model.addAttribute("levelData", levelData);
        return "admin/board_moderator/edit";
    }
    //指定版块下的
    @GetMapping(path = "/json", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Map<Long, String> getAllOfBoardForJson(@RequestParam(name = "board", required = false, defaultValue = "0") long boardId, HttpServletRequest request, Model model) {
        if(boardId > 0){
            return boardModeratorService.getAllByBoardId(boardId).collect(Collectors.toMap(BoardModerator::getId, BoardModerator::getMemberNickname));
        }
        return boardModeratorService.getAll().collect(Collectors.toMap(BoardModeratorReplica::getId, BoardModeratorReplica::getMemberNickname));
    }
    
    @GetMapping(path = "/permission")
    public String permissionForm(@RequestParam("id") long moderatorId, HttpServletRequest request, Model model) {
        model.addAttribute("rs", getModeratorAllAction());
        String[] existsEnumSymbolArrayString = boardModeratorActionIndexService.getAllByBoardId(moderatorId).map(ForumActionEnum::getSymbol).map(Object::toString).toArray(String[]::new);
        //
        BoardModeratorPermissionForm form = new BoardModeratorPermissionForm();
        form.setModeratorId(moderatorId + "");
        form.setActions(existsEnumSymbolArrayString);
        form.setRecord(AdminUtils.isNotEmpty(existsEnumSymbolArrayString) ? 10 : 0);
        model.addAttribute("form", form);
        return "admin/board_moderator/permission";
    }
    
    @PostMapping(path = "/permission")
    public String permissionAction(@ModelAttribute("form") BoardModeratorPermissionForm form, HttpServletRequest request, Model model) {
        List<ForumActionEnum> actions = new ArrayList<>();
        for (String enumSymbol : form.getActions()) {
            ForumActionEnum tmp = EnumArchitecture.getInstance(Commons.stringToInteger(enumSymbol, 0), ForumActionEnum.class).orElse(null);
            if(null!=tmp){
                actions.add(tmp);
            }
        }
        Optional<Boolean> symbol = Optional.empty();
        if (form.isUpdate()) {
            if (!actions.isEmpty()) {
                symbol = boardModeratorActionIndexService.edit(Long.valueOf(form.getModeratorId()), actions);
            }
        } else {
            if (!actions.isEmpty()) {
                symbol = boardModeratorActionIndexService.grantModeratorActions(Long.valueOf(form.getModeratorId()), actions);
            }
        }
        if (symbol.orElse(false)) {
            return "redirect:/board/moderator/";
        }
        model.addAttribute("errors", form.getActionTitle() + "版主权限操作失败");
        model.addAttribute("form", form);
        //
        model.addAttribute("rs", getModeratorAllAction());
        return "admin/board_moderator/permission";
    }
    
    @GetMapping(path = "/roles")
    public String getModeratorRoleHistory(
            @RequestParam("member") long memberId,
            HttpServletRequest request,
            Model model) {
        List<BoardModeratorRoleHistory> data = boardModeratorRoleHistoryService.getByMember(memberId).collect(Collectors.toList());
        model.addAttribute("rs", data);
        //
        Member member = memberService.get(memberId).orElse(Member.robotMember());
        model.addAttribute("moderator", member);
        return "admin/board_moderator/role_history";
    }
    //board|topic|posts
    private Map<String, List<CommonBean>> getModeratorAllAction() {
        final Set<ForumActionEnum> data = ForumActionEnum.getModeratorActions();
        Map<String, List<ForumActionEnum>> rs = data.stream().collect(Collectors.groupingBy(ForumActionEnum::getSection));
        Function<Entry<String,List<ForumActionEnum>>, List<CommonBean>> valueMapper = entry->{
            return entry.getValue().stream().map(fa->new CommonBean(fa.getSymbol(), fa.getTitle())).collect(Collectors.toList());
        };
        Function<Entry<String,List<ForumActionEnum>>, String> keyMapper = entry->entry.getKey();
        return rs.entrySet().stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }
    //版主卸任
    @PostMapping(path = "/quit", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public TipMessage leaveJob(
            @RequestParam(name = "member", required = false, defaultValue = "0") long memberId,
            @RequestParam(name = "board", required = false, defaultValue = "0") long boardId,
            @RequestParam(name = "volume", required = false, defaultValue = "0") int volumesId,
            HttpServletRequest request,
            Model model) {
        return TipMessage.Builder.take(()->boardModeratorService.remove(volumesId, boardId, memberId)).success("版主卸任成功").error("操作失败");
    }
}