package com.xjrsoft.module.material.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.annotation.XjrLog;
import com.xjrsoft.common.enums.MaterialCategoryEnum;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.app.dto.UpdateEnableMarkDto;
import com.xjrsoft.module.form.dto.FormExecuteInfoDto;
import com.xjrsoft.module.form.entity.FormTemplate;
import com.xjrsoft.module.form.service.IFormExecuteService;
import com.xjrsoft.module.form.service.IFormTemplateService;
import com.xjrsoft.module.material.dto.*;
import com.xjrsoft.module.material.entity.MaterialType;
import com.xjrsoft.module.material.entity.MaterialTypeAssign;
import com.xjrsoft.module.material.service.IMaterialTypeAssignService;
import com.xjrsoft.module.material.service.IMaterialTypeService;
import com.xjrsoft.module.material.vo.MaterialTypeAssignVo;
import com.xjrsoft.module.material.vo.MaterialTypePageVo;
import com.xjrsoft.module.material.vo.MaterialTypeVo;
import com.xjrsoft.module.organization.entity.Department;
import com.xjrsoft.module.organization.entity.UserDeptRelation;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.system.service.IFileService;
import com.xjrsoft.module.teacher.entity.XjrUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
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 org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* @title: 材料提交任务类型
* @Author baicai
* @Date: 2023-10-31
* @Version 1.0
*/
@RestController
@RequestMapping("/material" + "/materialtype")
@Api(value = "/material"  + "/materialtype",tags = "材料提交任务类型代码")
@AllArgsConstructor
public class MaterialTypeController {


    private final IMaterialTypeService materialTypeService;

    private final IMaterialTypeAssignService materialTypeAssignService;

    @GetMapping(value = "/page")
    @ApiOperation(value="材料提交任务类型列表(分页)")
    @SaCheckPermission("materialtype:detail")
    public RT<PageOutput<MaterialTypePageVo>> page(@Valid MaterialTypePageDto dto){
        PageOutput<MaterialTypePageVo> pageOutput = materialTypeService.getPage(dto);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/list")
    @ApiOperation(value="材料提交任务类型列表(权限)")
    public RT<List<MaterialTypeVo>> list() {
        return RT.ok(materialTypeService.listMaterialTypeVo());
    }

    @GetMapping(value = "/info")
    @ApiOperation(value="根据id查询材料提交任务类型信息")
    @SaCheckPermission("materialtype:detail")
    public RT<MaterialTypeVo> info(@RequestParam Long id){
        MaterialTypeVo materialTypeVo = materialTypeService.getInfoById(id);
        if (materialTypeVo == null) {
           return RT.error("找不到此数据！");
        }
        return RT.ok(materialTypeVo);
    }

    @PostMapping
    @ApiOperation(value = "新增材料提交任务类型")
    @SaCheckPermission("materialtype:add")
    public RT<Boolean> add(@Valid @RequestBody AddMaterialTypeDto dto){
        MaterialType materialType = BeanUtil.toBean(dto, MaterialType.class);
        boolean isSuccess = materialTypeService.add(materialType);
    return RT.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改材料提交任务类型")
    @SaCheckPermission("materialtype:edit")
    public RT<Boolean> update(@Valid @RequestBody UpdateMaterialTypeDto dto){

        MaterialType materialType = BeanUtil.toBean(dto, MaterialType.class);
        return RT.ok(materialTypeService.update(materialType));

    }

    @DeleteMapping
    @ApiOperation(value = "删除材料提交任务类型")
    @SaCheckPermission("materialtype:delete")
    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
        return RT.ok(materialTypeService.delete(ids));

    }
    @PostMapping("/import")
    @ApiOperation(value = "导入")
    public RT<Boolean> importData(@RequestParam MultipartFile file) throws IOException {
        List<MaterialTypePageVo> savedDataList = EasyExcel.read(file.getInputStream()).head(MaterialTypePageVo.class).sheet().doReadSync();
        Boolean result = materialTypeService.saveBatch(BeanUtil.copyToList(savedDataList, MaterialType.class));
        return RT.ok(result);
    }

    @GetMapping("/export")
    @ApiOperation(value = "导出")
    public ResponseEntity<byte[]> exportData(@Valid MaterialTypePageDto dto, @RequestParam(defaultValue = "false") Boolean isTemplate) {
        List<MaterialTypePageVo> customerList = isTemplate != null && isTemplate ? new ArrayList<>() : ((PageOutput<MaterialTypePageVo>) page(dto).getData()).getList();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, MaterialTypePageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);

        return RT.fileStream(bot.toByteArray(), "MaterialType" + ExcelTypeEnum.XLSX.getValue());
    }

    @GetMapping(value = "/assign-page")
    @ApiOperation(value="材料提交任务类型权限列表(分页)")
    @SaCheckPermission("materialtype:detail")
    public RT<PageOutput<MaterialTypeAssignVo>> assignPage(@Valid MaterialTypeAssignPageDto dto) {

        MPJLambdaWrapper<MaterialTypeAssign> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper
                .disableSubLogicDel()
                .select(MaterialTypeAssign::getId)
                .selectAs(XjrUser::getName,MaterialTypeAssignVo::getUserName)
                .select(MaterialTypeAssign.class,x -> VoToColumnUtil.fieldsToColumns(MaterialTypeAssignVo.class).contains(x.getProperty()))
                .eq(ObjectUtil.isNotEmpty(dto.getMaterialTypeId()) && dto.getMaterialTypeId() > 0, MaterialTypeAssign::getMaterialTypeId, dto.getMaterialTypeId())
                .leftJoin(MaterialType.class, MaterialType::getId, MaterialTypeAssign::getMaterialTypeId,ext->ext.selectAs(MaterialType::getName, MaterialTypeAssignVo::getMaterialTypeName))
                .innerJoin(XjrUser.class, XjrUser::getId, MaterialTypeAssign::getUserId, ext -> ext.selectAs(XjrUser::getUserName, MaterialTypeAssignVo::getUserName))
                .leftJoin(UserDeptRelation.class, UserDeptRelation::getUserId, MaterialTypeAssign::getUserId)
                .leftJoin(Department.class, Department::getId, UserDeptRelation::getDeptId, ext -> ext.selectAs(Department::getName, MaterialTypeAssignVo::getDeptName))
        ;

        IPage<MaterialTypeAssignVo> page = materialTypeAssignService.selectJoinListPage(ConventPage.getPage(dto),MaterialTypeAssignVo.class, queryWrapper);
        PageOutput<MaterialTypeAssignVo> pageOutput = ConventPage.getPageOutput(page);
        return RT.ok(pageOutput);
    }

    @PostMapping(value = "/assign-add")
    @ApiOperation(value = "材料提交任务类型权限")
    @SaCheckPermission("materialtype:add")
    public RT<Boolean> assignAdd(@Valid @RequestBody AddMaterialTypeAssignDto dto){
        boolean isSuccess = materialTypeAssignService.add(dto);
        return RT.ok(isSuccess);
    }

    @DeleteMapping(value = "/assign-delete")
    @ApiOperation(value = "删除材料提交任务类型")
    @SaCheckPermission("materialtype:delete")
    public RT<Boolean> assignDelete(@Valid @RequestBody List<Long> ids){
        return RT.ok(materialTypeAssignService.delete(ids));
    }

    @PutMapping("/update-enable-mark")
    @ApiOperation(value = "修改启用状态")
    @XjrLog(value = "修改启用状态")
    public R updateEnableMark(@Valid @RequestBody UpdateEnableMarkDto dto) {
        MaterialType materialType = new MaterialType();
        materialType.setId(dto.getId());
        materialType.setEnabledMark(dto.getEnabledMark());
        materialTypeService.updateById(materialType);
        return R.ok(true);
    }
}