package com.casic.missiles.controller.meter;

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.*;
import com.casic.missiles.dto.flowable.ApprovalDeleteRequest;
import com.casic.missiles.dto.meter.*;
import com.casic.missiles.enums.BusinessExceptionEnum;
import com.casic.missiles.enums.ExportEnum;
import com.casic.missiles.exception.BusinessException;
import com.casic.missiles.model.business.BusinessOutsourcerInfo;
import com.casic.missiles.model.business.BusinessOutsourcerInfoImport;
import com.casic.missiles.model.meter.MeterTraceSupplier;
import com.casic.missiles.model.exception.enums.CoreExceptionEnum;
import com.casic.missiles.model.meter.MeterTraceSupplierImport;
import com.casic.missiles.service.meter.IMeterTraceSupplierService;
import com.casic.missiles.utils.ConvertUtils;
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 org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
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("/meter/supplier")
public class MeterTraceSupplierController extends ExportController {
    @Autowired
    private IMeterTraceSupplierService traceSupplierService;

    @ApiOperation("溯源供方列表（分页）")
    @PostMapping("/listPage")
    @ResponseBody
    public ReturnDTO<PageInfoBT<MeterTraceSupplier>> supplierListPage(@RequestBody @Valid TraceSupplierListRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        Page<MeterTraceSupplier> page = PageFactory.defaultPage();
        return ReturnUtil.success(super.packForBT(traceSupplierService.listPage(page, request)));
    }

    @ApiOperation("溯源供方列表")
    @PostMapping("/list")
    @ResponseBody
    public ReturnDTO<List<MeterTraceSupplier>> supplierList(@RequestBody @Valid TraceSupplierListRequest request, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return ReturnUtil.success(traceSupplierService.list(request));
    }

    @ApiOperation("溯源供方导出")
    @PostMapping("/listExport")
    @ResponseBody
    public void export(@RequestBody @Valid TraceSupplierListRequest request, BindingResult bindingResult) throws IOException {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        List<MeterTraceSupplier> list;
        if (!CollectionUtils.isEmpty(request.getIds())) {
            list = traceSupplierService.listByIds(request.getIds());
        } else {
            list = traceSupplierService.list(request);
        }
        super.exportExcel(MeterTraceSupplier.class, list, ExportEnum.TRACE_SUPPLIER_EXPORT.getSheetName());
    }

    @ApiOperation("溯源供方保存（保存至草稿箱）")
    @PostMapping("/save")
    @ResponseBody
    public ReturnDTO<TraceSupplierSaveResponse> save(@RequestBody @Valid MeterTraceSupplier traceSupplier, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return traceSupplierService.saveTraceSupplier(traceSupplier);
    }

    @ApiOperation("批量导入溯源供方")
    @PostMapping(value = "/import", headers = "content-type=multipart/form-data")
    @ResponseBody
    public ReturnDTO importBatch(@RequestParam MultipartFile[] multipartFile) throws Exception {
        List<MeterTraceSupplierImport> sourceList = new ArrayList();
        for (MultipartFile file : multipartFile) {
            List<MeterTraceSupplierImport> list =  super.importExcel(MeterTraceSupplierImport.class, file, null, null);
            sourceList.addAll(list);
        }
        List<MeterTraceSupplier> targetList = ConvertUtils.sourceToTarget(sourceList, MeterTraceSupplier.class);
        return traceSupplierService.addTraceSupplierList(targetList);
    }

    /**
     * 草稿箱溯源供方编辑
     */
    @ApiOperation("草稿箱溯源供方编辑")
    @PostMapping("/draftUpdate")
    @ResponseBody
    public ReturnDTO draftUpdate(@RequestBody @Valid MeterTraceSupplier traceSupplier, BindingResult bindingResult) {
        Assert.isFalse(Objects.isNull(traceSupplier.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return traceSupplierService.draftUpdate(traceSupplier);
    }

    @ApiOperation("溯源供方提交（未调用过保存接口保存至草稿箱需先调用保存接口，再调用该接口）")
    @PostMapping("/submit")
    @ResponseBody
    public ReturnDTO traceSupplierSubmit(@RequestBody @Valid BaseApprovalSubmitRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return traceSupplierService.submitTraceSupplier(request);
    }

//    @ApiOperation("溯源供方更新（审批通过后还能更新？？暂时保留。。）")
    @PostMapping("/update")
    @ResponseBody
    public ReturnDTO supplierUpdate(@RequestBody @Valid MeterTraceSupplier traceSupplier, BindingResult bindingResult) {
//        Assert.isFalse(Objects.isNull(traceSupplier.getId()), () -> {
//            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
//        });
//        Assert.isFalse(bindingResult.hasErrors(), () -> {
//            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
//        });
//        return traceSupplierService.updateTraceSupplier(traceSupplier);
        return null;
    }

    @ApiOperation("溯源供方删除（草稿删除也调用该接口）")
    @PostMapping("/delete")
    @ResponseBody
    public ReturnDTO supplierDelete(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return traceSupplierService.deleteTraceSupplier(idDTO.getId());
    }

    @ApiOperation("溯源供方批量删除")
    @PostMapping("/batchDelete")
    @ResponseBody
    public ReturnDTO supplierBatchDelete(@RequestBody @Valid IdsDTO idsDTO) {
        Assert.isFalse(CollectionUtils.isEmpty(idsDTO.getIds()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return traceSupplierService.deleteBatchTraceSupplier(idsDTO.getIds());
    }

    @ApiOperation("溯源供方详情")
    @PostMapping("/detail")
    @ResponseBody
    public ReturnDTO<TraceSupplierDetailResponse> supplierDetail(@RequestBody @Valid IdDTO idDTO) {
        Assert.isFalse(Objects.isNull(idDTO.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        return traceSupplierService.traceSupplierDetail(idDTO.getId());
    }

    @ApiOperation("溯源供方审批列表及详情中基础信息（分页），底部的人员信息等可用溯源供方详情接口")
    @PostMapping("/approval/listPage")
    @ResponseBody
    public ReturnDTO<PageInfoBT<TraceSupplierApprovalListResponse>> approvalListPage(@RequestBody @Valid TraceSupplierApprovalListRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        Page<TraceSupplierApprovalListResponse> page = PageFactory.defaultPage();
        List<TraceSupplierApprovalListResponse> responseList = traceSupplierService.approvalListPage(page, request);
        page.setRecords(responseList);
        return ReturnUtil.success(super.packForBT(page));
    }

    /**
     * 删除（发起者或具有删除权限的用户可以删除，已通过/未通过状态不可删除）
     * 前端控制按钮权限
     */
    @ApiOperation("审批操作-删除")
    @PostMapping("/approval/operate/delete")
    @ResponseBody
    public ReturnDTO delete(@RequestBody @Valid ApprovalDeleteRequest request, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return traceSupplierService.approvalDelete(request);
    }

    /**
     * 审批操作-编辑
     *      驳回的流程放置在未通过列表中，实现进行编辑后自动审核通过发起人节点
     */
    @ApiOperation("未通过溯源供方编辑（驳回后的溯源供方重新编辑，仅未通过列表中的编辑按钮可调用）")
    @PostMapping("/failUpdate")
    @ResponseBody
    public ReturnDTO failUpdate(@RequestBody @Valid MeterTraceSupplier traceSupplier, BindingResult bindingResult) {
        Assert.isFalse(Objects.isNull(traceSupplier.getId()), () -> {
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        });
        if (bindingResult.hasErrors()) {
            throw new BusinessException(CoreExceptionEnum.REQUEST_NULL.getCode(), bindingResult.getFieldError().getDefaultMessage());
        }
        return traceSupplierService.failUpdate(traceSupplier);
    }

}
