package com.sy.coinage.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sy.coinage.core.annotation.CurrentUser;
import com.sy.coinage.core.aop.annotation.Operation;
import com.sy.coinage.core.aop.annotation.Permission;
import com.sy.coinage.core.constants.Constants;
import com.sy.coinage.core.controller.BaseController;
import com.sy.coinage.core.interceptor.Create;
import com.sy.coinage.core.interceptor.Update;
import com.sy.coinage.core.req.IdReq;
import com.sy.coinage.core.vo.CacheUserVO;
import com.sy.coinage.core.vo.OptVO;
import com.sy.coinage.sys.model.Dict;
import com.sy.coinage.sys.req.AdminDictListReq;
import com.sy.coinage.sys.req.DictBatchAddReq;
import com.sy.coinage.sys.req.DictBatchUpdateReq;
import com.sy.coinage.sys.req.DictListReq;
import com.sy.coinage.sys.req.AdminDictAddReq;
import com.sy.coinage.sys.req.DictReq;
import com.sy.coinage.sys.service.IDictService;
import com.sy.coinage.sys.vo.DictListVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 字典Controller
 */
@Api(value = "字典接口", tags = "017_字典")
@RestController
@RequestMapping(value = "/dict")
public class DictController extends BaseController {

    @Autowired
    private IDictService dictService;

    /**
     * 根据标识获取字典选项
     */
    @ApiOperation(value = "根据标识获取字典选项")
    @GetMapping(value = "/opt/{tag}")
    public List<OptVO> opt(@PathVariable String tag, @CurrentUser CacheUserVO user) {
        List<OptVO> data = this.dictService.opt(tag, user.getTenantId());
        return data;
    }

    /**
     * 根据标识获取级联字典一级选项
     */
    @ApiOperation(value = "根据标识获取级联字典一级选项")
    @GetMapping(value = "/cascadeOpt/{tag}")
    public List<OptVO> cascadeOpt(@PathVariable String tag, @CurrentUser CacheUserVO user) {
        List<OptVO> data = this.dictService.cascadeOpt(tag, 0, user.getTenantId());
        return data;
    }

    /**
     * 根据标识和id获取级联字典下级选项
     */
    @ApiOperation(value = "根据标识和id获取级联字典下级选项")
    @GetMapping(value = "/cascadeOpt/{tag}/{id}")
    public List<OptVO> cascadeOpt(@PathVariable String tag, @PathVariable Integer id, @CurrentUser CacheUserVO user) {
        List<OptVO> data = this.dictService.cascadeOpt(tag, id, user.getTenantId());
        return data;
    }

    /**
     * 根据标识获取树型字典
     */
    @ApiOperation(value = "根据标识获取树型字典选项")
    @GetMapping(value = "/treeOpt/{tag}")
    public List<OptVO> treeOpt(@PathVariable String tag, @CurrentUser CacheUserVO user) {
        List<OptVO> data = this.dictService.treeOpt(tag, user.getTenantId());
        return data;
    }

    /**
     * 字典树形列表
     */
    @ApiOperation(value = "字典树形列表")
    @PostMapping("/treeList")
    public List<DictListVO> treeList(@RequestBody DictListReq req, @CurrentUser CacheUserVO user) {
        List<DictListVO> data = this.dictService.treeList(req.getTag(), user.getTenantId());
        return data;
    }

    /**
     * 子级字典列表
     */
    @ApiOperation(value = "子级字典列表")
    @PostMapping("/children")
    public List<Dict> children(@RequestBody @Valid IdReq req) {
        LambdaQueryWrapper<Dict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dict::getPid, req.getId());
        return this.dictService.list(queryWrapper);
    }

    /**
     * 字典详情
     */
    @ApiOperation(value = "字典详情")
    @PostMapping("/get")
    public Dict get(@RequestBody @Valid IdReq req) {
        Dict data = this.dictService.getById(req.getId());
        return data;
    }

    /**
     * 修改字典
     */
    @ApiOperation(value = "修改字典")
    @Operation(value = "修改字典")
//    @Permission("dict:update")
    @PostMapping("/update")
    public Object update(@RequestBody @Validated({Update.class}) DictReq req, @CurrentUser CacheUserVO user) {
        Dict model = this.dictService.getById(req.getId());
        // 验证是否相同租户
        this.validTenant(user, model.getTenantId());
        BeanUtils.copyProperties(req, model);
        this.dictService.updateById(model);
        return "";
    }

    /**
     * 新增字典
     */
    @ApiOperation(value = "新增字典")
    @Operation(value = "新增字典")
//    @Permission("dict:add")
    @PostMapping("/add")
    public Object add(@RequestBody @Validated({Create.class}) DictReq req, @CurrentUser CacheUserVO user) {
        Dict model = new Dict();
        BeanUtils.copyProperties(req, model);
        model.setTenantId(user.getTenantId());
        if (null != model.getPid() && model.getPid().intValue() != 0) {
            Dict p = this.dictService.getById(model.getPid());
            model.setTag(p.getTag());
            model.setLevels(null == p.getLevels() ? 1 : p.getLevels() + 1);
        } else {
            model.setLevels(1);
            model.setPid(0);
        }
        if (null == model.getSorted()) {
            model.setSorted(0);
        }
        model.setStatus(Constants.STATUS_USABLE);
        this.dictService.save(model);
        return "";
    }

    @ApiOperation(value = "批量新增字典")
    @Operation(value = "批量新增字典")
    @PostMapping("/batchAdd")
    public Object batchAdd(@RequestBody @Valid DictBatchAddReq req, @CurrentUser CacheUserVO user) {
        Dict model = this.dictService.getById(req.getId());
        // 验证是否相同租户
        this.validTenant(user, model.getTenantId());
        this.dictService.batchAdd(req);
        return "";
    }

    @ApiOperation(value = "批量修改字典")
    @Operation(value = "批量修改字典")
    @PostMapping("/batchUpdate")
    public Object batchUpdate(@RequestBody @Valid DictBatchUpdateReq req, @CurrentUser CacheUserVO user) {
        Dict model = this.dictService.getById(req.getId());
        // 验证是否相同租户
        this.validTenant(user, model.getTenantId());
        this.dictService.batchUpdate(req);
        return "";
    }

    /**
     * 修改字典状态
     */
    @ApiOperation(value = "修改字典状态")
    @Operation(value = "修改字典状态")
//    @Permission("dict:update")
    @PostMapping("/status")
    public Integer status(@RequestBody @Valid IdReq req, @CurrentUser CacheUserVO user) {
        Dict model = this.dictService.getById(req.getId());
        // 验证是否相同租户
        this.validTenant(user, model.getTenantId());
        if (model.getStatus() != null && model.getStatus().intValue() == Constants.STATUS_FORBIDDEN) {
            model.setStatus(Constants.STATUS_USABLE);
        } else {
            model.setStatus(Constants.STATUS_FORBIDDEN);
        }
        this.dictService.updateById(model);
        return model.getStatus();
    }

    /**
     * 租户管理员-字典树形列表
     */
    @ApiOperation(value = "租户管理员-字典树形列表")
    @PostMapping("/admin/treeList")
    public List<DictListVO> adminTreeList(@RequestBody @Valid AdminDictListReq req) {
        List<DictListVO> data = this.dictService.treeList(req.getTag(), req.getTenantId());
        return data;
    }

    /**
     * 租户管理员-新增父级字典
     *
     * @param req
     * @param user
     * @return
     */
    @ApiOperation(value = "管理员新增父级字典")
    @Operation(value = "管理员新增父级字典")
    @PostMapping("/admin/add")
    public Object adminaAdd(@RequestBody @Valid AdminDictAddReq req, @CurrentUser CacheUserVO user) {
        // 验证是否租户管理员
        this.validAdmin(user);
        this.dictService.adminaAdd(req);
        return "";
    }

}
