package com.xjrsoft.module.system.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.system.dto.AddDictionaryItemDto;
import com.xjrsoft.module.system.dto.DictionaryItemDetailDto;
import com.xjrsoft.module.system.dto.DictionaryItemDetailPageDto;
import com.xjrsoft.module.system.dto.DictionaryItemPageDto;
import com.xjrsoft.module.system.dto.UpdateDictionaryItemDto;
import com.xjrsoft.module.system.entity.DictionaryDetail;
import com.xjrsoft.module.system.entity.DictionaryItem;
import com.xjrsoft.module.system.service.IDictionarydetailService;
import com.xjrsoft.module.system.service.IDictionaryitemService;
import com.xjrsoft.module.system.vo.DictionaryItemDetailVo;
import com.xjrsoft.module.system.vo.DictionaryItemPageVo;
import com.xjrsoft.module.system.vo.DictionaryItemVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

/**
 * <p>
 * 数据字典项目 前端控制器
 * </p>
 *
 * @author tzx
 * @since 2022-03-17
 */
@RestController
@RequestMapping(GlobalConstant.SYSTEM_MODULE_PREFIX + "/dictionary-item")
@Api(value = GlobalConstant.SYSTEM_MODULE_PREFIX + "/dictionary-item",tags = "数据字典项目")
@AllArgsConstructor
public class DictionaryitemController {

    private final IDictionaryitemService dictionaryitemService;

    private final IDictionarydetailService dictionarydetailService;


    @GetMapping("/list")
    @ApiOperation(value = "获取 数据字典项目列表（不分页）")
    public R list(@Valid DictionaryItemPageDto dto){

        LambdaQueryWrapper<DictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(dto.getName()), DictionaryItem::getName,dto.getName())
                .like(StrUtil.isNotBlank(dto.getCode()), DictionaryItem::getCode,dto.getCode())
                .select(DictionaryItem.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryItemPageVo.class).contains(x.getProperty()));

        List<DictionaryItem> list = dictionaryitemService.list(queryWrapper);
        List<DictionaryItemVo> dictionaryItemVos = BeanUtil.copyToList(list, DictionaryItemVo.class);
        return R.ok(dictionaryItemVos);
    }

    @GetMapping("/page")
    @ApiOperation(value = "获取所有数据字典项目（分页）")
    public R page(@Valid DictionaryItemPageDto dto){

        LambdaQueryWrapper<DictionaryItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotBlank(dto.getName()), DictionaryItem::getName,dto.getName())
                    .like(StrUtil.isNotBlank(dto.getCode()), DictionaryItem::getCode,dto.getCode())
                    .select(DictionaryItem.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryItemPageVo.class).contains(x.getProperty()))
                    .orderByAsc(DictionaryItem::getSortCode);

        IPage<DictionaryItem> page = dictionaryitemService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<DictionaryItemPageVo> pageOutput = ConventPage.getPageOutput(page, DictionaryItemPageVo.class);

        return R.ok(pageOutput);
    }

    @GetMapping("/info")
    @ApiOperation(value = "根据id获取项目详情")
    public R info(@RequestParam Long id){
        DictionaryItem dictionaryItem = dictionaryitemService.getById(id);
        if (dictionaryItem == null){
            R.error("找不到此字典项目!");
        }

        return R.ok(BeanUtil.toBean(dictionaryItem, DictionaryItemVo.class));
    }

    @GetMapping("/detail")
    @ApiOperation(value = "获取当前数据字典项目下所有字典详情")
    public R detail(@Valid DictionaryItemDetailDto dto){
        List<String> values = StrUtil.split(dto.getValues(), StringPool.COMMA);
        LambdaQueryWrapper<DictionaryDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DictionaryDetail::getItemId,dto.getId())
                    .in(CollectionUtils.isNotEmpty(values), DictionaryDetail::getValue, values)
                    .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryItemDetailVo.class).contains(x.getProperty()));

        List<DictionaryDetail> list = dictionarydetailService.list(queryWrapper);

        List<DictionaryItemDetailVo> dictionaryItemDetailVos = BeanUtil.copyToList(list, DictionaryItemDetailVo.class);
        return R.ok(dictionaryItemDetailVos);
    }

    @GetMapping("/detail/tree")
    @ApiOperation(value = "获取数据字典项目 + 详情  树结构")
    public R tree(){
        return R.ok(dictionaryitemService.getTree());
    }


    @GetMapping("/detail/page")
    @ApiOperation(value = "获取当前数据字典项目下所有字典详情(分页)")
    public R detail(@Valid DictionaryItemDetailPageDto dto){

        LambdaQueryWrapper<DictionaryDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DictionaryDetail::getItemId,dto.getId())
                .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryItemDetailVo.class).contains(x.getProperty()));

        IPage<DictionaryDetail> page = dictionarydetailService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<DictionaryItemDetailVo> pageOutput = ConventPage.getPageOutput(page, DictionaryItemDetailVo.class);
        return R.ok(pageOutput);
    }

    @PostMapping
    @ApiOperation(value = "新增数据字典项")
    public R add(@Valid @RequestBody AddDictionaryItemDto dto){

        long count = dictionaryitemService.count(Wrappers.<DictionaryItem>query().lambda().eq(DictionaryItem::getCode, dto.getCode()).or().eq(DictionaryItem::getName,dto.getName()));
        if(count > 0){
            return R.error("项目名或者编码已经存在！");
        }

        DictionaryItem dictionaryItem = BeanUtil.toBean(dto, DictionaryItem.class);

        boolean isSuccess = dictionaryitemService.save(dictionaryItem);
        if (isSuccess) dictionaryitemService.loadCaches();
        return R.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "更新数据字典项")
    public R update(@Valid @RequestBody UpdateDictionaryItemDto dto){

        long count = dictionaryitemService.count(Wrappers.<DictionaryItem>query().lambda()
                .eq(DictionaryItem::getCode, dto.getCode())
                .ne(DictionaryItem::getId,dto.getId())
                .or()
                .eq(DictionaryItem::getName, dto.getName())
                .ne(DictionaryItem::getId,dto.getId()));
        if(count > 0){
            return R.error("项目名或者编码已经存在！");
        }
        DictionaryItem dictionaryItem = BeanUtil.toBean(dto, DictionaryItem.class);

        boolean isSuccess = dictionaryitemService.updateById(dictionaryItem);
        if (isSuccess) dictionaryitemService.loadCaches();
        return R.ok(isSuccess);
    }

    @DeleteMapping
    @ApiOperation(value = "删除数据字典项")
    @Transactional(rollbackFor = Exception.class)
    public R delete(@RequestBody List<Long> ids){
        //删除字典详情
        dictionaryitemService.removeBatchByIds(ids);
        //删除字典项
        dictionarydetailService.remove(Wrappers.lambdaQuery(DictionaryDetail.class).in(DictionaryDetail::getItemId,ids));
        return R.ok();
    }

}
