package com.qmth.sop.server.api;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.sop.business.bean.params.DeviceDeliveryParam;
import com.qmth.sop.business.bean.params.DeviceInOutForm;
import com.qmth.sop.business.bean.result.ProjectExchangeResult;
import com.qmth.sop.business.entity.SysUser;
import com.qmth.sop.business.entity.TBDeviceDelivery;
import com.qmth.sop.business.service.TBDeviceDeliveryService;
import com.qmth.sop.common.annotation.OperationLog;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.Result;
import com.qmth.sop.common.util.ResultUtil;
import com.qmth.sop.common.util.ServletUtil;
import io.swagger.annotations.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备发货表 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2023-11-28
 */
@Api(tags = "设备发货表Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_DEVICE_DELIVERY)
public class TBDeviceDeliveryController {

    @Resource
    TBDeviceDeliveryService tbDeviceDeliveryService;

    @ApiOperation(value = "设备发货列表分页查询")
    @RequestMapping(value = "/page", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = ProjectExchangeResult.class) })
    public Result list(@ApiParam(value = "服务单元id") @RequestParam(required = false) String serviceId, @ApiParam(value = "用途类型") @RequestParam(required = false) DeviceUsageTypeEnum usageType,
            @ApiParam(value = "项目单号") @RequestParam(required = false) String crmNo, @ApiParam(value = "发货状态") @RequestParam(required = false) DeviceDeliveryStatusEnum status,
            @ApiParam(value = "发货人id") @RequestParam(required = false) String deliverUserId, @ApiParam(value = "发货开始时间") @RequestParam(required = false) Long deliverStartTime,
            @ApiParam(value = "发货结束时间") @RequestParam(required = false) Long deliverEndTime, @ApiParam(value = "设备序列号") @RequestParam(required = false) String serialNo,
            @ApiParam(value = "设备编号") @RequestParam(required = false) String deviceNo, @ApiParam(value = "供应商id") @RequestParam(required = false) String supplierId,
            @ApiParam(value = "签收开始时间") @RequestParam(required = false) Long receiveStartTime, @ApiParam(value = "签收结束时间") @RequestParam(required = false) Long receiveEndTime,
            @ApiParam(value = "收件人") @RequestParam(required = false) String consignee,
            @ApiParam(value = "邮寄地址") @RequestParam(required = false) String mailingAddress,
            @ApiParam(value = "出入库状态") @RequestParam(required = false) InOutTypeEnum deliveryType,
            @ApiParam(value = "品牌") @RequestParam(required = false) String brand,
            @ApiParam(value = "型号") @RequestParam(required = false) String model,
            @ApiParam(value = "快递单号") @RequestParam(required = false) String expressNo,
            @ApiParam(value = "页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
            @ApiParam(value = "页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize)
            throws Exception {
        return ResultUtil.ok(tbDeviceDeliveryService.page(new Page<>(pageNumber, pageSize), SystemConstant.convertIdToLong(serviceId),
                usageType, crmNo, status, SystemConstant.convertIdToLong(deliverUserId), deliverStartTime, deliverEndTime,
                serialNo, deviceNo, SystemConstant.convertIdToLong(supplierId), receiveStartTime, receiveEndTime,
                consignee, mailingAddress, deliveryType, brand, model, expressNo));
    }

    @ApiOperation(value = "设备发货保存接口")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Object.class) })
    @OperationLog(logType = LogTypeEnum.UPDATE)
    @Transactional
    public Result save(@Valid @ApiParam(value = "设备发货修改信息", required = true) @RequestBody DeviceDeliveryParam deviceDeliveryParam,
            BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        tbDeviceDeliveryService.editDeviceDelivery(deviceDeliveryParam);
        return ResultUtil.ok();
    }

    @ApiOperation(value = "设备发货查询单个记录接口")
    @RequestMapping(value = "/find/by/id", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = TBDeviceDelivery.class) })
    public Result edit(@ApiParam(value = "设备发货id", required = true) @RequestParam String id) throws Exception {
        TBDeviceDelivery tbDeviceDelivery = tbDeviceDeliveryService.getById(SystemConstant.convertIdToLong(id));
        Optional.ofNullable(tbDeviceDelivery).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未找到设备发货信息"));
        return ResultUtil.ok(tbDeviceDelivery);
    }

    @ApiOperation(value = "设备发货状态修改接口")
    @RequestMapping(value = "/status/update", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Object.class) })
    @OperationLog(logType = LogTypeEnum.UPDATE)
    @Transactional
    public Result statusUpdate(@ApiParam(value = "设备发货id", required = true) @RequestParam List<String> idList, @ApiParam(value = "设备发货状态", required = true) @RequestParam DeviceDeliveryStatusEnum status) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        if (CollectionUtils.isNotEmpty(idList)) {
            tbDeviceDeliveryService.updateStatus(
                    idList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList()), status,
                    requestUser.getId());
        }
        return ResultUtil.ok();
    }

    @ApiOperation(value = "设备发货导入")
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Object.class) })
    @OperationLog(logType = LogTypeEnum.IMPORT)
    public Result importDeviceDelivery(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file)
            throws Exception {
        tbDeviceDeliveryService.deviceDeliveryImport(file);
        return ResultUtil.ok();
    }

    @ApiOperation(value = "设备发货导出")
    @RequestMapping(value = "/export", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = ProjectExchangeResult.class) })
    @OperationLog(logType = LogTypeEnum.EXPORT)
    public void export(@ApiParam(value = "服务单元id") @RequestParam(required = false) Long serviceId, @ApiParam(value = "用途类型") @RequestParam(required = false) DeviceUsageTypeEnum usageType,
            @ApiParam(value = "项目单号") @RequestParam(required = false) String crmNo, @ApiParam(value = "发货状态") @RequestParam(required = false) DeviceDeliveryStatusEnum status,
            @ApiParam(value = "发货人id") @RequestParam(required = false) Long deliverUserId, @ApiParam(value = "发货开始时间") @RequestParam(required = false) Long deliverStartTime,
            @ApiParam(value = "发货结束时间") @RequestParam(required = false) Long deliverEndTime, @ApiParam(value = "设备序列号") @RequestParam(required = false) String serialNo,
            @ApiParam(value = "设备编号") @RequestParam(required = false) String deviceNo, @ApiParam(value = "供应商id") @RequestParam(required = false) Long supplierId,
            @ApiParam(value = "签收开始时间") @RequestParam(required = false) Long receiveStartTime, @ApiParam(value = "签收结束时间") @RequestParam(required = false) Long receiveEndTime,
            @ApiParam(value = "收件人") @RequestParam(required = false) String consignee,
            @ApiParam(value = "邮寄地址") @RequestParam(required = false) String mailingAddress, @ApiParam(value = "出入库状态") @RequestParam(required = false) InOutTypeEnum deliveryType,
            @ApiParam(value = "品牌") @RequestParam(required = false) String brand,
            @ApiParam(value = "型号") @RequestParam(required = false) String model,
            @ApiParam(value = "快递单号") @RequestParam(required = false) String expressNo) throws Exception {
        tbDeviceDeliveryService.dataExport(serviceId, usageType, crmNo, status, deliverUserId, deliverStartTime,
                deliverEndTime, serialNo, deviceNo, supplierId, receiveStartTime, receiveEndTime, consignee,
                mailingAddress, deliveryType, brand, model, expressNo);
    }

    @ApiOperation(value = "设备发货人列表查询")
    @RequestMapping(value = "/delivery_user_list", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = SysUser.class) })
    public Result findDeliveryUserList() {
        return ResultUtil.ok(tbDeviceDeliveryService.findDeliveryUserList());
    }

    @ApiOperation(value = "设备发货可返还设备列表查询")
    @RequestMapping(value = "/can_return_info", method = RequestMethod.POST)
    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = SysUser.class) })
    public Result findDeviceReturnList(@ApiParam(value = "设备发货id集合") @RequestParam(required = false) List<String> idList) {
        List<Long> deviceDeliveryIdList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(idList)) {
            deviceDeliveryIdList = idList.stream().map(SystemConstant::convertIdToLong).distinct().collect(Collectors.toList());

        }
        List<DeviceInOutForm> deviceInOutFormList = tbDeviceDeliveryService.findDeviceReturnList(deviceDeliveryIdList);
        if (CollectionUtils.isEmpty(deviceInOutFormList)) {
            throw ExceptionResultEnum.ERROR.exception("缺少可返还的设备发货记录");
        }
        return ResultUtil.ok(deviceInOutFormList);
    }
}
