package com.casic.missiles.controller.system;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.casic.missiles.core.base.controller.ExportController;
import com.casic.missiles.core.page.PageFactory;
import com.casic.missiles.core.page.PageInfoBT;
import com.casic.missiles.dto.IdDTO;
import com.casic.missiles.dto.IdsDTO;
import com.casic.missiles.dto.ReturnDTO;
import com.casic.missiles.dto.ReturnUtil;
import com.casic.missiles.dto.system.*;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.enums.ExportEnum;
import com.casic.missiles.enums.PrefixCodeEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.model.exception.enums.CoreExceptionEnum;
import com.casic.missiles.model.system.SystemNotice;
import com.casic.missiles.model.system.SystemSign;
import com.casic.missiles.model.system.SystemTemplate;
import com.casic.missiles.service.system.ISystemNoticeService;
import com.casic.missiles.service.system.ISystemSignService;
import com.casic.missiles.service.system.ISystemTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description: 系统管理-常用工具、通知公告
 * @Author: wangpeng
 * @Date: 2022/11/21 20:31
 */
@Api(tags = "系统管理接口")
@Controller
@RequestMapping("/system")
public class SystemController extends ExportController {
    @Autowired
    private ISystemSignService signService;
    @Autowired
    private ISystemNoticeService noticeService;
    @Autowired
    private ISystemTemplateService templateService;

    @ApiOperation("签名/签章列表（分页）")
    @PostMapping("/sign/listPage")
    @ResponseBody
    public ReturnDTO<PageInfoBT<SystemSign>> signListPage(@RequestBody @Valid SignListRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        Page<SystemSign> page = PageFactory.defaultPage();
        return ReturnUtil.success(super.packForBT(signService.listPage(page, request)));
    }

    @ApiOperation("签名/签章详情")
    @PostMapping("/sign/detail")
    @ResponseBody
    public ReturnDTO<SignDetailResponse> signDetail(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return signService.signDetail(idDTO.getId());
    }

    @ApiOperation("签名/签章列表")
    @PostMapping("/sign/list")
    @ResponseBody
    public ReturnDTO<List<SystemSign>> signList(@RequestBody @Valid SignListRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return ReturnUtil.success(signService.list(request));
    }

    @ApiOperation("签名/签章导出")
    @PostMapping("/sign/listExport")
    @ResponseBody
    public void export(@RequestBody @Valid SignListRequest request, BindingResult bindingResult) throws IOException {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        List<SystemSign> list;
        if (!CollectionUtils.isEmpty(request.getIds())) {
            list = signService.listByIds(request.getIds());
        } else {
            list = signService.list(request);
        }
        super.exportExcel(SystemSign.class, list, ExportEnum.SIGN_EXPORT.getSheetName());
    }

    @ApiOperation("签名/签章新建")
    @PostMapping("/sign/add")
    @ResponseBody
    public ReturnDTO signAdd(@RequestBody @Valid SignAddRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return signService.addSign(request);
    }

    @ApiOperation("签名/签章更新")
    @PostMapping("/sign/update")
    @ResponseBody
    public ReturnDTO signUpdate(@RequestBody @Valid SystemSign systemSign, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return signService.updateSign(systemSign);
    }

    @ApiOperation("签名/签章删除")
    @PostMapping("/sign/delete")
    @ResponseBody
    public ReturnDTO signDelete(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return signService.deleteSign(idDTO.getId());
    }

    @ApiOperation("签名/签章批量删除")
    @PostMapping("/sign/batchDelete")
    @ResponseBody
    public ReturnDTO signBatchDelete(@RequestBody @Valid IdsDTO idsDTO) {
        Assert.isFalse(CollectionUtils.isEmpty(idsDTO.getIds()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return signService.deleteBatchSign(idsDTO.getIds());
    }

    @ApiOperation("获取本人可使用签名/签章")
    @GetMapping("/sign/usable")
    @ResponseBody
    public ReturnDTO<List<SystemSign>> signUsable() {
        return ReturnUtil.success(signService.usableSign());
    }

    @ApiOperation("原始记录模板/证书报告模板列表（分页）")
    @PostMapping("/template/listPage")
    @ResponseBody
    public ReturnDTO<PageInfoBT<SystemTemplate>> templateListPage(@RequestBody @Valid TemplateListRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        Page<SystemTemplate> page = PageFactory.defaultPage();
        return ReturnUtil.success(super.packForBT(templateService.listPage(page, request)));
    }

    @ApiOperation("原始记录模板/证书报告模板详情")
    @PostMapping("/template/detail")
    @ResponseBody
    public ReturnDTO<TemplateDetailResponse> templateDetail(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return templateService.templateDetail(idDTO.getId());
    }

    @ApiOperation("原始记录模板/证书报告模板列表")
    @PostMapping("/template/list")
    @ResponseBody
    public ReturnDTO<List<SystemTemplate>> templateList(@RequestBody @Valid TemplateListRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return ReturnUtil.success(templateService.list(request));
    }

    @ApiOperation("原始记录模板/证书报告模板导出")
    @PostMapping("/template/listExport")
    @ResponseBody
    public void export(@RequestBody @Valid TemplateListRequest request, BindingResult bindingResult) throws IOException {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        List<SystemTemplate> list;
        if (!CollectionUtils.isEmpty(request.getIds())) {
            list = templateService.listByIds(request.getIds());
        } else {
            list = templateService.list(request);
        }
        super.exportExcel(SystemTemplate.class, list, ExportEnum.TEMPLATE_EXPORT.getSheetName());
    }

    @ApiOperation("原始记录模板/证书报告模板新建")
    @PostMapping("/template/add")
    @ResponseBody
    public ReturnDTO templateAdd(@RequestBody @Valid TemplateAddRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return templateService.addTemplate(request);
    }

    @ApiOperation("原始记录模板/证书报告模板更新")
    @PostMapping("/template/update")
    @ResponseBody
    public ReturnDTO templateUpdate(@RequestBody @Valid SystemTemplate systemTemplate, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return templateService.updateTemplate(systemTemplate);
    }

    @ApiOperation("原始记录模板/证书报告模板删除")
    @PostMapping("/template/delete")
    @ResponseBody
    public ReturnDTO templateDelete(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return templateService.deleteTemplate(idDTO.getId());
    }

    @ApiOperation("原始记录模板/证书报告模板批量删除")
    @PostMapping("/template/batchDelete")
    @ResponseBody
    public ReturnDTO templateBatchDelete(@RequestBody @Valid IdsDTO idsDTO) {
        Assert.isFalse(CollectionUtils.isEmpty(idsDTO.getIds()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return templateService.deleteBatchTemplate(idsDTO.getIds());
    }

    @ApiOperation("通知公告列表/详情")
    @PostMapping("/notice/listPage")
    @ResponseBody
    public ReturnDTO<PageInfoBT<SystemNotice>> noticeListPage(@RequestBody NoticeListRequest request) {
        Page<SystemNotice> page = PageFactory.defaultPage();
        return ReturnUtil.success(super.packForBT(noticeService.listPage(page, request)));
    }

    @ApiOperation("通知公告新建")
    @PostMapping("/notice/add")
    @ResponseBody
    public ReturnDTO noticeAdd(@RequestBody @Valid NoticeAddRequest noticeAddRequest, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return noticeService.addNotice(noticeAddRequest);
    }

    @ApiOperation("通知公告更新")
    @PostMapping("/notice/update")
    @ResponseBody
    public ReturnDTO noticeUpdate(@RequestBody @Valid SystemNotice systemNotice, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return noticeService.updateNotice(systemNotice);
    }

    @ApiOperation("通知公告删除")
    @PostMapping("/notice/delete")
    @ResponseBody
    public ReturnDTO noticeDelete(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return noticeService.deleteNotice(idDTO.getId());
    }

    @ApiOperation("通知公告标记已读")
    @PostMapping("/notice/read")
    @ResponseBody
    public ReturnDTO noticeRead(@RequestBody @Valid NoticeReadRequest noticeReadRequest, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return noticeService.noticeRead(noticeReadRequest);
    }

    @ApiOperation("获取业务编号前缀列表")
    @PostMapping("/prefixcode/list")
    @ResponseBody
    public Object getPreFixCodeList() throws Exception{
        Class  fixCodeEnumClass = PrefixCodeEnum.class;
        Field[] fixCodeEnumFileds = fixCodeEnumClass.getDeclaredFields();
        List<String> fixCodeList=new ArrayList<>();
        for(Field field: fixCodeEnumFileds){
            fixCodeList.add( field.get(PrefixCodeEnum.class).toString());
        }
        return ReturnUtil.success(fixCodeList);
    }
}
