package me.qwq.doghouse.controller.admin;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.wrapper.MPJLambdaWrapper;

import jakarta.validation.Valid;
import me.qwq.doghouse.controller.common.BaseController;
import me.qwq.doghouse.entity.Cate;
import me.qwq.doghouse.entity.Meta;
import me.qwq.doghouse.enums.MetaTypeEnum;
import me.qwq.doghouse.exception.RException;
import me.qwq.doghouse.pojo.dto.LayPageReq;
import me.qwq.doghouse.pojo.dto.LayPageResp;
import me.qwq.doghouse.pojo.dto.R;
import me.qwq.doghouse.service.MetaService;

@Controller
@RequestMapping("/admin/v2/category")
public class CategoryController extends BaseController {
    
    @Autowired
    MetaService metaService;
    
    @GetMapping({"", "/"})
    private String index() {
        request.setAttribute("title", "分类管理");
        return "admin/category/index";
    }

    @GetMapping("/list")
    @ResponseBody
    private LayPageResp<Cate> getCategoryList(
            LayPageReq<Cate> pageReq,
            @RequestParam(required=false) Long parentId,
            @RequestParam(name="unfolded[]", required=false) Long[] unfolded){
        List<Long> unfoldedId;
        if (unfolded != null && unfolded.length > 0) {
            unfoldedId = Arrays.asList(unfolded);
        }
        else {
            unfoldedId = new ArrayList<>();
        }
        if (parentId == null) {
            IPage<Cate> page = metaService.pageTreeViewMetaWithChildren(Cate.class, pageReq, unfoldedId);
            return new LayPageResp<Cate>(page);
        }
        else {
            List<Cate> listCate = metaService.listTreeViewMetaWithChildren(Cate.class, parentId, unfoldedId);
            return new LayPageResp<Cate>().setData(listCate).setCount(listCate.size());
        }
    }

    /**
     * 新增或编辑分类
     * @param id
     * @return
     */
    @PostMapping("/update")
    @ResponseBody
    private R<?> update(@Valid Cate cate, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new RException(HttpStatus.BAD_REQUEST, bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        if (cate == null) {
            throw new RException(HttpStatus.BAD_REQUEST, "分类不允许为空");
        }
        if (StringUtils.isEmpty(cate.getFriendlyName())) {
            cate.setFriendlyName(cate.getName().toLowerCase(Locale.ENGLISH));
        }
        // 查询友好名称是否重复
            // 新增
        long count = metaService.count(new MPJLambdaWrapper<Meta>()
                .eq(Meta::getType, MetaTypeEnum.CATEGORY)
                .eq(Meta::getFriendlyName, cate.getFriendlyName()));
        if (count >= 1) {
            if (cate.getMid() == null) {
                throw new RException(HttpStatus.BAD_REQUEST, "分类友好名称与其他分类重复");
            }
            else {
                Cate existCate = metaService.getOneJoin(Cate.class,
                        new MPJLambdaWrapper<Cate>(Cate.class).eq(Cate::getFriendlyName, cate.getFriendlyName()));
                if (!existCate.getMid().equals(cate.getMid())) {
                    throw new RException(HttpStatus.BAD_REQUEST, "分类友好名称与其他分类重复");
                }
            }
        }
        if(cate.insertOrUpdate()) {
            return R.ok();
        }
        throw new RException(HttpStatus.BAD_REQUEST);
    }

    /**
     * 批量操作，支持批量删除、批量移动
     * @param ids
     * @param op 操作
     * @param to 移动到
     * @return
     */
    @PostMapping("/batchOp")
    @ResponseBody
    private R<?> batchOp(
            @RequestParam(value="ids[]", required=true) Long[] ids,
            @RequestParam(value="op", required=false) String op,
            @RequestParam(value="to", required=false) Long to) {
        List<Long> idArray = Arrays.asList(ids);
        if (op == null) {
            // 批量删除
            metaService.removeByIds(idArray);
            return R.ok();
        }
        else if (to == null) {
            // 批量移动到顶层
            LambdaUpdateWrapper<Meta> uw = new UpdateWrapper<Meta>()
                    .lambda().in(Meta::getMid, idArray)
                    .set(Meta::getParentId, 0L);
            metaService.update(uw);
            return R.ok();
        }
        else {
            // 批量移动到指定分类下
            // 检查父子从属关系
            List<Meta> childToParent = metaService.listFromChildToParent(to);
            if (childToParent.isEmpty()) {
                throw RException.badRequest("指定移动至的目标分类不存在");
            }
            // 如果传过来的 ids 中有 id 处在父子从属列表中
            // 则表明是想将父类移动到子类，或者想将自己移动到自己
            if (childToParent.stream().mapToLong(Meta::getMid).anyMatch(id -> idArray.contains(id))) {
                throw RException.badRequest("不允许将父级或本级移动到子级或本级");
            }
            LambdaUpdateWrapper<Meta> uw = new UpdateWrapper<Meta>()
                    .lambda().in(Meta::getMid, idArray)
                    .set(Meta::getParentId, to);
            metaService.update(uw);
            return R.ok();
        }
    }
    
    /**
     * 删除指定 id 的分类
     * @param id
     * @return
     */
    @PostMapping("/delete")
    @ResponseBody
    private R<?> delete(Long id) {
        metaService.removeById(id);
        return R.ok();
    }

}
