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

import com.tykj.dev.config.cache.ConfigCache;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.library.repository.DeviceLogDao;
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.domin.DeviceLog;
import com.tykj.dev.device.library.subject.vo.DeviceLogUserVo;
import com.tykj.dev.device.library.subject.vo.FileVo;
import com.tykj.dev.device.matching.repository.MatchingRepairBillDao;
import com.tykj.dev.device.matching.service.MatchingDeviceBillService;
import com.tykj.dev.device.matching.service.MatchingDeviceLibraryService;
import com.tykj.dev.device.matching.subject.domin.MatchingDeviceBill;
import com.tykj.dev.device.matching.subject.domin.MatchingDeviceLibrary;
import com.tykj.dev.device.matching.subject.domin.MatchingRepairBill;
import com.tykj.dev.device.matching.subject.vo.*;
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.user.read.service.MessageService;
import com.tykj.dev.device.user.read.subject.bto.MessageBto;
import com.tykj.dev.device.user.subject.service.UserPublicService;
import com.tykj.dev.device.user.util.UserUtils;
import com.tykj.dev.misc.base.BusinessEnum;
import com.tykj.dev.misc.base.StatusEnum;
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.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dengdiyi
 */
@RestController
@RequestMapping(value = "/matchingDevice")
@AutoDocument
@Api(tags = "配套设备模块", description = "配套设备模块")
@Validated
public class MatchingDeviceController {

    @Autowired
    private MatchingDeviceLibraryService matchingDeviceLibraryService;

    @Autowired
    private MatchingDeviceBillService matchingDeviceBillService;

    @Autowired
    private UserUtils userUtils;

    @Autowired
    private TaskService taskService;

    @Autowired
    private TaskLogService taskLogService;

    @Autowired
    private DeviceLogService deviceLogService;

    @Autowired
    private DeviceLibraryService deviceLibraryService;

    @Autowired
    private DeviceLogDao deviceLogDao;

    @Autowired
    private MyWebSocket myWebSocket;

    @Autowired
    private MatchingRepairBillDao matchingRepairBillDao;

    @Autowired
    private ConfigCache configCache;

    @Autowired
    private UserPublicService userPublicService;

    @Autowired
    private MessageService messageService;

    @ApiOperation(value = "添加配套设备", notes = "可以通过这个接口添加配套设备")
    @PostMapping(value = "/add")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity addStorageBill(@RequestBody @Validated MatchingDeviceBillSaveVo matchingDeviceBillSaveVo) {
        //添加账单
        MatchingDeviceBill matchingDeviceBillEntity = matchingDeviceBillSaveVo.toDo();
        MatchingDeviceBill m = matchingDeviceBillService.addEntity(matchingDeviceBillEntity);
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("x");
        Integer userId = userUtils.getCurrentUserId();
        //发起任务
        List<Integer> userIds = new ArrayList<>();
        userIds.add(userId);
//        userIds.add(matchingDeviceBillSaveVo.getUserbId());
        TaskBto taskBto = new TaskBto(StatusEnum.END.id, "新增配套", null, ".", m.getId(), 19, userUtils.getCurrentUnitId(), 0, null, userIds);
        TaskBto taskBto1 = taskService.start(taskBto);
        //日志文件
        List<FileVo> fileVoList = new ArrayList<>();
        fileVoList.add(new FileVo("新增确认单", matchingDeviceBillEntity.getFileName(), matchingDeviceBillEntity.getFileUrl()));
        //添加业务日志
//        TaskLogBto taskLogBto2 = new TaskLogBto(taskBto1.getId(), "发起新增配套", fileVoList);
//        taskLogService.addLog(taskLogBto2);
        for (MatchingDeviceSaveVo matchingDeviceSaveVo : matchingDeviceBillSaveVo.getMatchingDeviceSaveVoList()) {
            MatchingDeviceLibrary matchingDeviceLibraryEntity = matchingDeviceSaveVo.toDo();
            MatchingDeviceLibrary saveEntity = matchingDeviceLibraryService.addEntity(matchingDeviceLibraryEntity);
            stringBuffer.append(saveEntity.getId());
            stringBuffer.append("x");
            //存装备日志
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, saveEntity.getId(), "发起新增配套", fileVoList);
            deviceLogService.addLog(deviceLogDto);
        }
        //set账单新增设备详情
        m.setDeviceDetail(stringBuffer.toString());
        matchingDeviceBillService.update(m);
        //发送阅知信息
        List<Integer> ids = userPublicService.findOtherUser(userId);
        MessageBto messageBto = new MessageBto(taskBto1.getId(),taskBto1.getBusinessType(),"业务办结",ids,1);
        messageService.add(messageBto);
        myWebSocket.sendMessage1();
        return ResponseEntity.ok("添加成功");
    }

    @ApiOperation(value = "添加配套设备审核", notes = "可以通过这个接口添加配套设备审核")
    @PostMapping(value = "/confirm")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity confirm(@RequestBody @Validated MatchingDeviceBillConfirmVo matchingDeviceBillConfirmVo) {
        TaskBto taskBto = taskService.get(matchingDeviceBillConfirmVo.getTaskId());
        //1.审核成功,入库任务结束,改变装备状态
        if (matchingDeviceBillConfirmVo.getStatus() == 0) {
            taskService.update(taskService.moveToEnd(taskBto));
            //更新账单状态
            MatchingDeviceBill matchingDeviceBillEntity = matchingDeviceBillService.getOne(taskBto.getBillId());
            matchingDeviceBillEntity.setBillStatus(2);
            matchingDeviceBillService.update(matchingDeviceBillEntity);
            //改变设备状态，增加日志
            List<Integer> list = StringSplitUtil.userIdSplit(matchingDeviceBillEntity.getDeviceDetail());
            if (!list.isEmpty()) {
                for (Integer d : list) {
                    MatchingDeviceLibrary deviceLibraryEntity = matchingDeviceLibraryService.getOne(d);
                    deviceLibraryEntity.setLifeStatus(2);
                    DeviceLogDto deviceLogDto = new DeviceLogDto(1, deviceLibraryEntity.getId(), "添加配套设备审核成功", null);
                    deviceLogService.addLog(deviceLogDto);
                    matchingDeviceLibraryService.update(deviceLibraryEntity);
                }
            }
            myWebSocket.sendMessage1();
            return ResponseEntity.ok("审核通过新增成功");
        }
        //2.审核失败
        if (matchingDeviceBillConfirmVo.getStatus() == 1) {
            taskService.update(taskService.moveToArchive(taskBto));
            //更新账单状态
            MatchingDeviceBill matchingDeviceBillEntity = matchingDeviceBillService.getOne(taskBto.getBillId());
            matchingDeviceBillEntity.setBillStatus(1);
            matchingDeviceBillService.update(matchingDeviceBillEntity);
            //改变设备状态，增加日志
            List<Integer> list = StringSplitUtil.userIdSplit(matchingDeviceBillEntity.getDeviceDetail());
            if (!list.isEmpty()) {
                for (Integer d : list) {
                    MatchingDeviceLibrary deviceLibraryEntity = matchingDeviceLibraryService.getOne(d);
                    deviceLibraryEntity.setLifeStatus(1);
                    DeviceLogDto deviceLogDto = new DeviceLogDto(1, deviceLibraryEntity.getId(), "添加配套设备审核失败", null);
                    deviceLogService.addLog(deviceLogDto);
                    matchingDeviceLibraryService.update(deviceLibraryEntity);
                }
            }
            myWebSocket.sendMessage1();
            return ResponseEntity.ok("入库审核失败");
        } else {
            return ResponseEntity.ok("status只能为0或1");
        }
    }

    @ApiOperation(value = "模糊查询配套装备分页", notes = "可以通过这个接口查询装备列表")
    @PostMapping("/feature/summary")
    public ResponseEntity getAll(@RequestBody MatchingDeviceSelectVo matchingDeviceSelectVo) {
        Page<MatchingDeviceLibrary> page = matchingDeviceLibraryService.getPage(matchingDeviceSelectVo, matchingDeviceSelectVo.getPageable());
        //set关联装备的表面号
        for (MatchingDeviceLibrary m : page.getContent()) {
            if (m.getDeviceId() > 0) {
                m.setRelateDevice(deviceLibraryService.getOne(m.getDeviceId()).getRfidSurfaceId());
            }
            m.setConfigName();
        }
        return ResponseEntity.ok(page);
    }

    @ApiOperation(value = "查询配套装备详情", notes = "可以通过这个接口查询配套装备详情")
    @GetMapping("/feature/detail/{id}")
    public ResponseEntity getDetail(@PathVariable("id") @Min(value = 1,message = "id不能小于1") int id) {
        List<Object> list = new ArrayList<>();
        //添加配套设备详情
        MatchingDeviceLibrary m = matchingDeviceLibraryService.getOne(id);
        list.add(m);
        //添加关联装备详情
        if (m.getDeviceId() != 0) {
            list.add(deviceLibraryService.getOne(m.getDeviceId()));
        } else {
            list.add(new DeviceLibrary());
        }
        //添加设备履历日志
        List<DeviceLogUserVo> deviceLogs = deviceLogDao.getAllByDeviceIdAndType(id, 1).stream()
                .map(DeviceLog::parse2Dto)
                .map(DeviceLogDto::toVo)
                .sorted(Comparator.comparing(DeviceLogUserVo::getCreateTime,Comparator.nullsLast(Date::compareTo)))
                .collect(Collectors.toList());
        list.add(deviceLogs);
        return ResponseEntity.ok(list);
    }

    @ApiOperation(value = "更新配套设备", notes = "可以通过这个接口更新配套设备")
    @PostMapping("/update")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity update(@RequestBody @Validated MatchingDeviceEditVo matchingDeviceEditVo) {
        MatchingDeviceLibrary m = matchingDeviceLibraryService.getOne(matchingDeviceEditVo.getMatchingDeviceId());
        if (matchingDeviceEditVo.getCreateUnit() != null && !m.getCreateUnit().equals(matchingDeviceEditVo.getCreateUnit())) {
            //添加设备日志
            String remark = "将设备的创建单位由" + m.getCreateUnit() + "改为" + matchingDeviceEditVo.getCreateUnit();
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setCreateUnit(matchingDeviceEditVo.getCreateUnit());
        }
        if (matchingDeviceEditVo.getLifeStatus() != null && !m.getLifeStatus().equals(matchingDeviceEditVo.getLifeStatus())) {
            //添加设备日志
            String remark = "将设备的生命状态由" + configCache.getLifeStatusMap().get(m.getLifeStatus()) + "改为" + configCache.getLifeStatusMap().get(matchingDeviceEditVo.getLifeStatus());
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setLifeStatus(matchingDeviceEditVo.getLifeStatus());
        }
        if (matchingDeviceEditVo.getDeviceId() != null && m.getDeviceId() == 0) {
            //添加设备日志
            DeviceLibrary deviceLibrary = deviceLibraryService.getOne(matchingDeviceEditVo.getDeviceId());
            String remark = "将该设备与表面号为" + deviceLibrary.getRfidSurfaceId() + "的装备绑定";
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setDeviceId(matchingDeviceEditVo.getDeviceId());
        }
        if (matchingDeviceEditVo.getModel() != null && !m.getModel().equals(matchingDeviceEditVo.getModel())) {
            //添加设备日志
            String remark = "将设备的型号由" + m.getModel() + "改为" + matchingDeviceEditVo.getModel();
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setModel(matchingDeviceEditVo.getModel());
        }
        if (matchingDeviceEditVo.getName() != null && !m.getName().equals(matchingDeviceEditVo.getName())) {
            //添加设备日志
            String remark = "将设备的名称由" + m.getName() + "改为" + matchingDeviceEditVo.getName();
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setName(matchingDeviceEditVo.getName());
        }
        if (matchingDeviceEditVo.getSeqNumber() != null && !m.getSeqNumber().equals(matchingDeviceEditVo.getSeqNumber())) {
            //添加设备日志
            String remark = "将设备的序列号由" + m.getSeqNumber() + "改为" + matchingDeviceEditVo.getSeqNumber();
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setSeqNumber(matchingDeviceEditVo.getSeqNumber());
        }
        if (matchingDeviceEditVo.getType() != null && !m.getType().equals(matchingDeviceEditVo.getType())) {
            //添加设备日志
            String remark = "将设备类型由" + m.getType() + "改为" + matchingDeviceEditVo.getType();
            DeviceLogDto deviceLogDto = new DeviceLogDto(1, matchingDeviceEditVo.getMatchingDeviceId(), remark, null);
            deviceLogService.addLog(deviceLogDto);
            m.setType(matchingDeviceEditVo.getType());
        }
        matchingDeviceLibraryService.update(m);
        return ResponseEntity.ok("修改成功");
    }

    @ApiOperation(value = "查询新增配套任务详情", notes = "可以通过这个接口查询新增配套任务详情")
    @GetMapping(value = "/detail/{billId}")
    public ResponseEntity selectDetail(@PathVariable("billId") int billId) {
        MacthingDetailVo macthingDetailVo = new MacthingDetailVo();
        //获取业务
        TaskBto taskBto = taskService.get(billId, BusinessEnum.ADD_MATCHING_DEVICE.id);
        //获取账单
        MatchingDeviceBill matchingDeviceBillEntity = matchingDeviceBillService.getOne(billId);
        macthingDetailVo.setMatchingDeviceBill(matchingDeviceBillEntity);
        //获取设备
        List<Integer> integerList = StringSplitUtil.userIdSplit(matchingDeviceBillEntity.getDeviceDetail());
        List<MatchingDeviceLibrary> matchingDeviceLibraryEntities = new ArrayList<>();
        if (integerList.size() > 0) {
            for (Integer id : integerList) {
                if (id > 0) {
                    matchingDeviceLibraryEntities.add(matchingDeviceLibraryService.getOne(id));
                }
            }
        }
        macthingDetailVo.setMatchingDeviceLibraries(matchingDeviceLibraryEntities);
        //获取业务日志
        macthingDetailVo.setTaskLogUserVos(taskLogService.getByTaskId(taskBto.getId()));
        return ResponseEntity.ok(macthingDetailVo);
    }

    @ApiOperation(value = "查询所有配套设备型号", notes = "查询所有配套设备型号")
    @GetMapping(value = "/selectAllModel")
    public ResponseEntity selectAllModel() {
        return ResponseEntity.ok(matchingDeviceLibraryService.getAllModel());
    }

    @ApiOperation(value = "查询所有配套设备名称", notes = "查询所有配套设备名称")
    @GetMapping(value = "/selectAllName")
    public ResponseEntity selectAllName() {
        return ResponseEntity.ok(matchingDeviceLibraryService.getAllName());
    }

    @ApiOperation(value = "上传维修单", notes = "上传维修单")
    @PostMapping(value = "/repair")
    public ResponseEntity uploadRepairBill(@RequestBody @Validated MatchingRepairVo matchingRepairVo){
        MatchingRepairBill matchingRepairBill = new MatchingRepairBill();
        BeanUtils.copyProperties(matchingRepairVo,matchingRepairBill);
        return ResponseEntity.ok(matchingRepairBillDao.save(matchingRepairBill));
    }
}
