package cn.lihongjie.coal.deviceWorkOrder.service;

import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.common.ArchiveUtils;
import cn.lihongjie.coal.deviceWorkOrder.dto.CreateDeviceWorkOrderDto;
import cn.lihongjie.coal.deviceWorkOrder.dto.DeviceWorkOrderDto;
import cn.lihongjie.coal.deviceWorkOrder.dto.UpdateDeviceWorkOrderDto;
import cn.lihongjie.coal.deviceWorkOrder.entity.DeviceWorkOrderEntity;
import cn.lihongjie.coal.deviceWorkOrder.mapper.DeviceWorkOrderMapper;
import cn.lihongjie.coal.deviceWorkOrder.repository.DeviceWorkOrderRepository;
import cn.lihongjie.coal.exception.BizException;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@Transactional
public class DeviceWorkOrderService
        extends BaseService<DeviceWorkOrderEntity, DeviceWorkOrderRepository> {
    @Autowired private DeviceWorkOrderRepository repository;

    @Autowired private DeviceWorkOrderMapper mapper;

    @Autowired private ConversionService conversionService;

    public DeviceWorkOrderDto create(CreateDeviceWorkOrderDto request) {
        DeviceWorkOrderEntity entity = mapper.toEntity(request);
        if (CollectionUtils.isNotEmpty(entity.getDetails())) {

            entity.getDetails().forEach(x -> x.setWorkOrder(entity));
        }

        this.repository.save(entity);

        return getById(entity.getId());
    }

    public DeviceWorkOrderDto update(UpdateDeviceWorkOrderDto request) {
        DeviceWorkOrderEntity entity = this.repository.get(request.getId());
        ArchiveUtils.checkArchiveStatus(
                entity,
                DeviceWorkOrderEntity::getArchiveStatus,
                x -> "0",
                (e, actual, expected) -> {
                    throw new BizException("数据 " + "已归档，无法编辑");
                });
        this.mapper.updateEntity(entity, request);



        if (CollectionUtils.isNotEmpty(entity.getDetails())) {

            entity.getDetails().forEach(x -> x.setWorkOrder(entity));
        }

        this.repository.save(entity);

        return getById(entity.getId());
    }

    public void delete(IdRequest request) {
        ArchiveUtils.checkArchiveStatus(
                this.repository::findAllById,
                request.getIds(),
                DeviceWorkOrderEntity::getArchiveStatus,
                x -> "0",
                (e, actual, expected) -> {
                    throw new BizException("数据 " + "已归档，无法删除");
                });
        this.repository.deleteAllById(request.getIds());
    }

    public DeviceWorkOrderDto getById(String id) {
        DeviceWorkOrderEntity entity = repository.get(id);

        return mapper.toDto(entity);
    }

    public Page<DeviceWorkOrderDto> list(CommonQuery query) {
        Page<DeviceWorkOrderEntity> page =
                repository.findAll(
                        query.specification(conversionService),
                        PageRequest.of(
                                query.getPageNo(),
                                query.getPageSize(),
                                Sort.by(query.getOrders())));

        return page.map(this.mapper::toDto);
    }

    public void archive(IdRequest dto) {
        this.repository.findAllById(dto.getIds()).stream()
                .peek(
                        x ->
                                ArchiveUtils.checkArchiveStatus(
                                        x,
                                        DeviceWorkOrderEntity::getArchiveStatus,
                                        y -> "0",
                                        (e, actual, expected) -> {
                                            throw new BizException("数据 " + "已归档，无法再次归档");
                                        }))
                .peek(x -> x.setArchiveStatus("1"))
                .forEach(this.repository::save);
    }

    public void unarchive(IdRequest dto) {
        this.repository.findAllById(dto.getIds()).stream()
                .peek(
                        x ->
                                ArchiveUtils.checkArchiveStatus(
                                        x,
                                        DeviceWorkOrderEntity::getArchiveStatus,
                                        y -> "1",
                                        (e, actual, expected) -> {
                                            throw new BizException("数据" + "未归档，无法取消归档");
                                        }))
                .peek(x -> x.setArchiveStatus("0"))
                .forEach(this.repository::save);
    }
}
