package com.tykj.dev.device.apply.controller;

import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.allot.service.AllotBillService;
import com.tykj.dev.device.allot.subject.domin.AllotBill;
import com.tykj.dev.device.apply.service.DeviceApplyBillService;
import com.tykj.dev.device.apply.subject.domin.DeviceApplyBill;
import com.tykj.dev.device.apply.subject.vo.ApplyDetailVo;
import com.tykj.dev.device.apply.subject.vo.DeviceApplyAllotSaveVo;
import com.tykj.dev.device.apply.subject.vo.DeviceApplyConfirmVo;
import com.tykj.dev.device.apply.subject.vo.DeviceApplySaveVo;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.service.DeviceLogService;
import com.tykj.dev.device.library.subject.Dto.DeviceLogDto;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.library.subject.vo.DeviceLibrarySelectVo;
import com.tykj.dev.device.library.subject.vo.FileVo;
import com.tykj.dev.device.packing.service.PackingLibraryService;
import com.tykj.dev.device.packing.subject.domin.PackingLibrary;
import com.tykj.dev.device.task.repository.TaskDao;
import com.tykj.dev.device.task.service.TaskLogService;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.task.subject.bto.TaskLogBto;
import com.tykj.dev.device.task.subject.common.BusinessEnum;
import com.tykj.dev.device.task.subject.common.StatusEnum;
import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.task.subject.vo.TaskLogUserVo;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.ResultUtil;
import com.tykj.dev.misc.utils.StringSplitUtil;
import com.tykj.dev.socket.MyWebSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@RestController
@Api(tags = "装备申请模块",description = "申请模块")
@AutoDocument
@RequestMapping("/apply")
public class DeviceApplyController {

    @Autowired
    private DeviceApplyBillService deviceApplyBillService;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    private TaskService taskService;

    @Autowired
    private DeviceLogService deviceLogService;

    @Autowired
    private UserPublicService userPublicService;

    @Autowired
    private AllotBillService allotBillService;

    @Autowired
    private TaskLogService taskLogService;

    @Autowired
    private PackingLibraryService packingLibraryService;

    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Autowired
    private TaskDao taskDao;

    @Autowired
    private MyWebSocket myWebSocket;

    @ApiOperation(value = "发起装备申请", notes = "可以通过这个接口发起装备申请")
    @PostMapping("/addDeviceApplyBill")
    public ResponseEntity addDeviceApplyBill(@RequestBody DeviceApplySaveVo deviceApplySaveVo) {
        //添加申请单
        DeviceApplyBill deviceApplyBillEntity = deviceApplyBillService.addEntity(deviceApplySaveVo.toDo());
        Integer userId = userUtils.getCurrentUserId();
        //发起任务
        TaskBto taskBto;
        //指定批复人
        if (deviceApplySaveVo.getReplyUseraId() != null) {
            List<Integer> userIds = new ArrayList<>();
            userIds.add(userId);
            userIds.add(deviceApplySaveVo.getReplyUseraId());
            taskBto = new TaskBto(StatusEnum.DEVICE_APPLY_CONFIRM.id, "申请业务", null, ".", deviceApplyBillEntity.getId(), 9, userPublicService.findUnitIdByName(deviceApplySaveVo.getReplyUnit()), 1, null, userIds);
        }
        //不指定批复人
        else{
            List<Integer> userIds = new ArrayList<>();
            userIds.add(userId);
            userIds.add(0);
            taskBto = new TaskBto(StatusEnum.DEVICE_APPLY_CONFIRM.id, "申请业务", null, ".", deviceApplyBillEntity.getId(), 9, userPublicService.findUnitIdByName(deviceApplySaveVo.getReplyUnit()), 1, null, userIds);
        }
        Task saveEntity = taskService.start(taskBto);
        //添加业务日志
        TaskLogBto taskLogBto = new TaskLogBto(saveEntity.getId(),"发起装备申请",null);
        taskLogService.addLog(taskLogBto);
        myWebSocket.sendMessage1();
        return ResponseEntity.ok(deviceApplyBillEntity);
    }

    @ApiOperation(value = "装备申请批复", notes = "可以通过这个接口批复")
    @PostMapping("/replay")
    public ResponseEntity addDeviceApplyBillReplay(@RequestBody DeviceApplyConfirmVo deviceApplyConfirmVo) {
        TaskBto taskBto = taskService.get(deviceApplyConfirmVo.getTaskId());
        Integer userId = userUtils.getCurrentUserId();
        DeviceApplyBill applyBillEntity = deviceApplyBillService.getOne(taskBto.getBillId());
        //如果修改了批复文号
        if (deviceApplyConfirmVo.getReplyNumber() != null) {
            applyBillEntity.setReplayNumber(deviceApplyConfirmVo.getReplyNumber());
        }
        //批复驳回
        if (deviceApplyConfirmVo.getStatus() == 1) {
            applyBillEntity.setApplyStatus(1);
            taskService.update(taskService.moveToArchive(taskBto));
            deviceApplyBillService.update(applyBillEntity);
            TaskLogBto taskLogBto = new TaskLogBto(taskBto.getId(),"装备申请批复驳回",null);
            taskLogService.addLog(taskLogBto);
            myWebSocket.sendMessage1();
            return ResponseEntity.ok(taskBto);
        }
        //批复成功
        if (deviceApplyConfirmVo.getStatus()==0){
            applyBillEntity.setApplyStatus(2);
            taskService.update(taskService.moveToEnd(taskBto));
            TaskLogBto taskLogBto = new TaskLogBto(taskBto.getId(),"装备申请批复通过",null);
            taskLogService.addLog(taskLogBto);
            //添加空的配发账单
            AllotBill allotBill = allotBillService.addEntity(new AllotBill());
            //生成配发子任务
            List<Integer> userIds = new ArrayList<>();
            userIds.add(userId);
            TaskBto taskBto1 = new TaskBto(StatusEnum.WAIT_ALLOT.id, "配发业务", taskBto.getId(), "."+taskBto.getId()+".", allotBill.getId(), 3, userUtils.getCurrentUnitId(), 0, null, userIds);
            Task task = taskService.start(taskBto1);
            deviceApplyBillService.update(applyBillEntity);
            myWebSocket.sendMessage1();
            return ResponseEntity.ok(task.parse2Bto());
        }
        else {
            throw new ApiException(ResultUtil.failed("status只能为0或1"));
        }
    }

    @ApiOperation(value = "装备申请后发起配发", notes = "可以通过这个接口装备申请后发起配发")
    @PostMapping("/allot")
    public ResponseEntity allot(@RequestBody DeviceApplyAllotSaveVo deviceApplyAllotSaveVo) {
        //获取配发的业务
        TaskBto taskBto = taskService.get(deviceApplyAllotSaveVo.getTaskId());
        //获取申请的业务
        TaskBto applyTask = taskService.get(taskBto.getParentTaskId());
        Integer userId = userUtils.getCurrentUserId();
        //获取申请账单
        DeviceApplyBill deviceApplyBillEntity = deviceApplyBillService.getOne(applyTask.getBillId());
        //添加配发单
        AllotBill allotBillEntity = allotBillService.getOne(taskBto.getBillId());
        BeanUtils.copyProperties(deviceApplyAllotSaveVo, allotBillEntity);
        allotBillEntity.setTitle("申请后配发");
        allotBillEntity.setSendUseraId(userId);
        allotBillEntity.setReceiveUseraId(applyTask.getCreateUserId());
        allotBillEntity.setApplyNumber(deviceApplyBillEntity.getApplyNumber());
        allotBillEntity.setReplayNumber(deviceApplyBillEntity.getReplayNumber());
        allotBillEntity.setSendUnit(deviceApplyBillEntity.getReplyUnit());
        allotBillEntity.setReceiveUnit(deviceApplyBillEntity.getApplyUnit());
        allotBillEntity.setSendTime(new Date());
        allotBillEntity.setAllotType(2);
        allotBillEntity.setAllotStatus(0);
        allotBillService.update(allotBillEntity);
        //配发业务移动到下一阶段
        taskService.update(taskService.moveToNext(taskBto,deviceApplyAllotSaveVo.getSendUserbId()));
        //添加业务日志
        List<FileVo> fileVoList = new ArrayList<>();
        fileVoList.add(new FileVo("出库确认单",allotBillEntity.getFileName(),allotBillEntity.getFileUrl()));
        TaskLogBto taskLogBto = new TaskLogBto(taskBto.getId(),"对" + allotBillEntity.getReceiveUnit() + "发起配发",fileVoList);
        taskLogService.addLog(taskLogBto);
        //添加装备日志
        List<Integer> integerList = StringSplitUtil.split(allotBillEntity.getAllotCheckDetail());
        if (integerList.size()>0) {
            for (Integer id : integerList) {
                if (id > 0) {
                    DeviceLogDto deviceLogDto = new DeviceLogDto(id,"对" + allotBillEntity.getReceiveUnit() + "发起配发",fileVoList);
                    deviceLogService.addLog(deviceLogDto);
                }
            }
        }
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("发起配发成功");
    }

    @ApiOperation(value = "查询申请任务详情", notes = "可以通过这个接口查询申请任务详情")
    @GetMapping(value = "/detail/{billId}")
    public ResponseEntity selectDetail(@PathVariable("billId") int billId) {
        ApplyDetailVo applyDetailVo = new ApplyDetailVo();
        //获取业务
        TaskBto taskBto = taskService.get(billId, BusinessEnum.APPLY.id);
        //获取账单
        DeviceApplyBill deviceApplyBillEntity = deviceApplyBillService.getOne(billId);
        if (deviceApplyBillEntity.getApplyUseraId() != null) {
            deviceApplyBillEntity.setApplyUser(userPublicService.getOne(deviceApplyBillEntity.getApplyUseraId()).getName());
        }
        applyDetailVo.setDeviceApplyBill(deviceApplyBillEntity);
        //获取申请的列装Id和数量
        List<Integer> idList = StringSplitUtil.userIdSplit(deviceApplyBillEntity.getApplyDetail());
        List<Integer> packingIdList = new ArrayList<>();
        List<Integer> numList = new ArrayList<>();
        List<PackingLibrary> packingLibraryEntityList = new ArrayList<>();
        if (idList.size()>0){
            //奇数存列装id，偶数存数量
            for (int i=1;i<=idList.size();i++) {
                if (i%2==1){
                    packingIdList.add(idList.get(i-1));
                }
                else {
                    numList.add(idList.get(i-1));
                }
            }
        }
        if (packingIdList.size()==numList.size()){
            //set申请数量
            for (int i=0;i<packingIdList.size();i++) {
                PackingLibrary p = packingLibraryService.getOne(packingIdList.get(i));
                p.setApplyNum(numList.get(i));
                packingLibraryEntityList.add(p);
            }
        }
        applyDetailVo.setPackingLibraries(packingLibraryEntityList);
        //获取可配发装备,按列装Id筛选,列装Id排序
        applyDetailVo.setDeviceLibraries(deviceLibraryService.getAllotList(new DeviceLibrarySelectVo()).stream()
                .filter(deviceLibraryEntity -> packingIdList.contains(deviceLibraryEntity.getPackingId()))
                .sorted(Comparator.comparing(DeviceLibrary::getPackingId))
                .collect(Collectors.toList()));
        //添加业务日志
        List<TaskLogUserVo> applyLogUserVos = taskLogService.getByTaskId(taskBto.getId());
        //查询子任务
        List<Task> sonTasks = taskDao.findAllByParentTaskId(taskBto.getId());
        //添加子任务日志
        if (sonTasks.size()>0) {
            sonTasks.forEach(task -> applyLogUserVos.addAll(taskLogService.getByTaskId(task.getId())));
        }
        //按日志时间排序
        List<TaskLogUserVo> allLogUserVos = applyLogUserVos.stream()
                .sorted(Comparator.comparing(TaskLogUserVo::getCreateTime))
                .collect(Collectors.toList());
        applyDetailVo.setTaskLogUserVos(allLogUserVos);
        return ResponseEntity.ok(applyDetailVo);
    }
}
