package com.dji.sample.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dji.sample.manage.dao.IFleetMapper;
import com.dji.sample.manage.dao.IUserMapper;
import com.dji.sample.manage.model.dto.FleetDTO;
import com.dji.sample.manage.model.dto.FleetDeviceDTO;
import com.dji.sample.manage.model.dto.FleetUserDTO;
import com.dji.sample.manage.model.entity.FleetDeviceEntity;
import com.dji.sample.manage.model.entity.FleetEntity;
import com.dji.sample.manage.model.entity.FleetUserEntity;
import com.dji.sample.manage.model.entity.UserEntity;
import com.dji.sample.manage.model.param.FleetSearchParam;
import com.dji.sample.manage.service.IFleetDeviceService;
import com.dji.sample.manage.service.IFleetService;
import com.dji.sample.manage.service.IFleetUserService;
import com.dji.sample.manage.service.IWorkspaceService;
import com.dji.sdk.common.Pagination;
import com.dji.sdk.common.PaginationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.dji.sample.common.util.SecurityUtils.aboveSysAdminRole;
import static com.dji.sample.common.util.SecurityUtils.getOrgId;

/**
 * @author guan
 */
@Service
@Transactional
public class FleetServiceImpl extends ServiceImpl<IFleetMapper, FleetEntity> implements IFleetService {

    @Autowired
    private IFleetMapper mapper;

    @Autowired
    private IWorkspaceService workspaceService;

    @Autowired
    private IFleetUserService fleetUserService;

    @Autowired
    private IFleetDeviceService fleetDeviceService;

    @Override
    public List<FleetDTO> getFleets(String workspaceId) {
        LambdaQueryWrapper<FleetEntity> fleetQueryWrapper = new LambdaQueryWrapper<>();
        fleetQueryWrapper.eq(FleetEntity::getWorkspaceId, workspaceId);

        List<FleetEntity> fleetEntities = mapper.selectList(fleetQueryWrapper);
        List<FleetDTO> fleetList = fleetEntities.stream()
                .map(this::fleetEntityToDTO)
//                .peek(fleet -> {
//                })
                .collect(Collectors.toList());
        return fleetList;
    }

    @Override
    public PaginationData<FleetDTO> getFleetPage(FleetSearchParam param, String workspaceId, Long page, Long pageSize) {

        LambdaQueryWrapper<FleetEntity> fleetQueryWrapper = new LambdaQueryWrapper<>();
        fleetQueryWrapper.eq(FleetEntity::getWorkspaceId, workspaceId);
        if (StringUtils.hasText(param.getFleetName())) {
            fleetQueryWrapper.like(FleetEntity::getFleetName, param.getFleetName());
        }

        // 限制 团队
        if (aboveSysAdminRole()) {

        } else {
            fleetQueryWrapper.eq(FleetEntity::getOrgId, getOrgId());
        }

        Page<FleetEntity> pagination = mapper.selectPage(new Page<>(page, pageSize), fleetQueryWrapper);

        List<FleetDTO> fleetList = pagination.getRecords().stream()
                .map(this::fleetEntityToDTO)
//                .peek(fleet -> {
//                })
                .collect(Collectors.toList());

        // 查询全部userList 和 deviceList
        List<Integer> fleetIdList = fleetList.stream().map(FleetDTO::getId).filter(x -> !ObjectUtils.isEmpty(x)).collect(Collectors.toList());
        // 查询用户
        List<FleetUserDTO> fleetUserDTOList = fleetUserService.searchUserDTOListByFleetIds(fleetIdList);
        Map<String, List<FleetUserDTO>> fleetUserDTOMap = fleetUserDTOList.stream().collect(Collectors.groupingBy(FleetUserDTO::getFleetId));
        // 查询设备
        List<FleetDeviceDTO> fleetDeviceDTOList = fleetDeviceService.searchDeviceDTOListByFleetIds(fleetIdList);
        Map<String, List<FleetDeviceDTO>> fleetDeviceDTOMap = fleetDeviceDTOList.stream().collect(Collectors.groupingBy(FleetDeviceDTO::getFleetId));

        for (FleetDTO fleetDTO : fleetList) {
            fleetDTO.setUserList(fleetUserDTOMap.getOrDefault(fleetDTO.getId().toString(), new ArrayList<>()));
            fleetDTO.setDeviceList(fleetDeviceDTOMap.getOrDefault(fleetDTO.getId().toString(), new ArrayList<>()));

        }

        return new PaginationData<>(fleetList, new Pagination(pagination.getCurrent(), pagination.getSize(), pagination.getTotal()));

    }

    @Override
    public FleetDTO getFleetBySn(String workspaceId, String fleetSn) {

        LambdaQueryWrapper<FleetEntity> fleetEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        fleetEntityLambdaQueryWrapper.eq(FleetEntity::getFleetSn, fleetSn);
        fleetEntityLambdaQueryWrapper.eq(FleetEntity::getWorkspaceId, workspaceId);

        FleetEntity fleetEntity = this.mapper.selectOne(fleetEntityLambdaQueryWrapper);
        FleetDTO fleetDTO = fleetEntityToDTO(fleetEntity);
        // 查询 用户
        fleetDTO.setUserList(fleetUserService.searchUserDTOListByFleetId(fleetDTO.getId().toString()));
        // 查询设备
        fleetDTO.setDeviceList(fleetDeviceService.searchDeviceDTOListByFleetId(fleetDTO.getId().toString()));

        return fleetDTO;
    }

    @Override
    public boolean addFleet(FleetDTO fleetDTO) {

        FleetEntity addFleet = new FleetEntity();
        if (StringUtils.hasText(fleetDTO.getFleetSn())) {
            addFleet.setFleetSn(fleetDTO.getFleetSn()); 
        } else {
            addFleet.setFleetSn(UUID.randomUUID().toString());
        }

        addFleet.setOrgId(StringUtils.hasText(fleetDTO.getOrgId()) ? fleetDTO.getOrgId() : getOrgId());
        addFleet.setFleetName(fleetDTO.getFleetName());
        addFleet.setNickname(fleetDTO.getNickname());
        addFleet.setFleetDesc(fleetDTO.getFleetDesc());
        addFleet.setWorkspaceId(fleetDTO.getWorkspaceId());
        addFleet.setCreateTime(System.currentTimeMillis());
        addFleet.setUpdateTime(System.currentTimeMillis());
        addFleet.setUserId(fleetDTO.getUserId());

        int insert = mapper.insert(addFleet);

        List<FleetUserDTO> userList = fleetDTO.getUserList();
        List<FleetDeviceDTO> deviceList = fleetDTO.getDeviceList();
        // 新增 userList
        List<FleetUserEntity> addUserList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userList)) {
            for (FleetUserDTO fleetUserDTO : userList) {
                if (StringUtils.hasText(fleetUserDTO.getUserId())) {
                    FleetUserEntity newUser = new FleetUserEntity();
                    newUser.setUserId(fleetUserDTO.getUserId());
                    newUser.setFleetId(addFleet.getId().toString());
                    addUserList.add(newUser);
                }
            }
        }
        fleetUserService.addFleetUser(addUserList);

        // 新增 deviceList
        List<FleetDeviceEntity> addDeviceList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(deviceList)) {
            for (FleetDeviceDTO fleetDeviceDTO : deviceList) {
                if (StringUtils.hasText(fleetDeviceDTO.getDeviceId())) {
                    FleetDeviceEntity newDevice = new FleetDeviceEntity();
                    newDevice.setDeviceId(fleetDeviceDTO.getDeviceId());
                    newDevice.setFleetId(addFleet.getId().toString());
                    addDeviceList.add(newDevice);
                }
            }
        }
        fleetDeviceService.addFleetDevice(addDeviceList);

        return insert > 0;
    }

    @Override
    public boolean editFleet(FleetDTO fleetDTO) {


        FleetEntity editFleet = new FleetEntity();
        editFleet.setId(fleetDTO.getId());
        editFleet.setFleetSn(fleetDTO.getFleetSn());
        editFleet.setFleetName(fleetDTO.getFleetName());
        editFleet.setNickname(fleetDTO.getNickname());
        editFleet.setFleetDesc(fleetDTO.getFleetDesc());
        editFleet.setWorkspaceId(fleetDTO.getWorkspaceId());

        // editFleet.setCreateTime(System.currentTimeMillis());
        editFleet.setUpdateTime(System.currentTimeMillis());
        editFleet.setUserId(fleetDTO.getUserId());

        int update = mapper.updateById(editFleet);

        // todo 机场用户 和 机场设备
        List<FleetDeviceDTO> deviceList = fleetDTO.getDeviceList();
        List<FleetUserDTO> userList = fleetDTO.getUserList();

        // 直接删除旧的 然后增加新的
        // 删除 userList
        LambdaQueryWrapper<FleetUserEntity> delUserWrapper = new LambdaQueryWrapper<>();
        delUserWrapper.eq(FleetUserEntity::getFleetId, editFleet.getId().toString());
        fleetUserService.remove(delUserWrapper);
        // 新增 userList
        List<FleetUserEntity> addUserList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userList)) {
            for (FleetUserDTO fleetUserDTO : userList) {
                if (StringUtils.hasText(fleetUserDTO.getUserId())) {
                    FleetUserEntity newUser = new FleetUserEntity();
                    newUser.setUserId(fleetUserDTO.getUserId());
                    newUser.setFleetId(editFleet.getId().toString());
                    addUserList.add(newUser);
                }
            }
        }
        fleetUserService.addFleetUser(addUserList);

        // 删除 deviceList
        LambdaQueryWrapper<FleetDeviceEntity> delDeviceWrapper = new LambdaQueryWrapper<>();
        delDeviceWrapper.eq(FleetDeviceEntity::getFleetId, editFleet.getId().toString());
        fleetDeviceService.remove(delDeviceWrapper);
        // 新增 deviceList
        List<FleetDeviceEntity> addDeviceList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(deviceList)) {
            for (FleetDeviceDTO fleetDeviceDTO : deviceList) {
                if (StringUtils.hasText(fleetDeviceDTO.getDeviceId())) {
                    FleetDeviceEntity newDevice = new FleetDeviceEntity();
                    newDevice.setDeviceId(fleetDeviceDTO.getDeviceId());
                    newDevice.setFleetId(editFleet.getId().toString());
                    addDeviceList.add(newDevice);
                }
            }
        }
        fleetDeviceService.addFleetDevice(addDeviceList);

        return update > 0;
    }

    @Override
    public boolean deleteFleet(String fleetSn) {

        // 查询id

        LambdaQueryWrapper<FleetEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FleetEntity::getFleetSn, fleetSn);

        FleetEntity fleetEntity = this.getOne(queryWrapper);
        int delete = this.mapper.delete(queryWrapper);

        // 删除 机场用户 和 机场设备
        LambdaQueryWrapper<FleetUserEntity> fleetUserQueryWrapper = new LambdaQueryWrapper<>();
        fleetUserQueryWrapper.eq(FleetUserEntity::getFleetId, fleetEntity.getId());
        fleetUserService.remove(fleetUserQueryWrapper);

        LambdaQueryWrapper<FleetDeviceEntity> fleetDeviceQueryWrapper = new LambdaQueryWrapper<>();
        fleetDeviceQueryWrapper.eq(FleetDeviceEntity::getFleetId, fleetEntity.getId());
        fleetDeviceService.remove(fleetDeviceQueryWrapper);

        return delete > 0;
    }

    @Override
    public boolean deleteFleetById(String workspaceId, Integer id) {

        LambdaQueryWrapper<FleetEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FleetEntity::getWorkspaceId, workspaceId);
        queryWrapper.eq(FleetEntity::getId, id);

        int delete = mapper.delete(queryWrapper);

        return delete > 0;
    }

    public FleetDTO fleetEntityToDTO(FleetEntity fleetEntity) {
        FleetDTO fleetDTO = new FleetDTO();
        fleetDTO.setId(fleetEntity.getId());
        fleetDTO.setFleetSn(fleetEntity.getFleetSn());
        fleetDTO.setFleetName(fleetEntity.getFleetName());
        fleetDTO.setWorkspaceId(fleetEntity.getWorkspaceId());
        fleetDTO.setCreateTime(fleetEntity.getCreateTime());
        fleetDTO.setUpdateTime(fleetEntity.getUpdateTime());
        fleetDTO.setFleetDesc(fleetEntity.getFleetDesc());
        fleetDTO.setUserId(fleetEntity.getUserId());
        fleetDTO.setNickname(fleetEntity.getNickname());
        fleetDTO.setOrgId(fleetEntity.getOrgId());
        return fleetDTO;
    }

    public FleetEntity fleetDTOToEntity(FleetDTO fleetDTO) {
        FleetEntity fleetEntity = new FleetEntity();
        fleetEntity.setId(fleetDTO.getId());
        fleetEntity.setFleetSn(fleetDTO.getFleetSn());
        fleetEntity.setFleetName(fleetDTO.getFleetName());
        fleetEntity.setWorkspaceId(fleetDTO.getWorkspaceId());
        fleetEntity.setCreateTime(fleetDTO.getCreateTime());
        fleetEntity.setUpdateTime(fleetDTO.getUpdateTime());
        fleetEntity.setFleetDesc(fleetDTO.getFleetDesc());
        fleetEntity.setUserId(fleetDTO.getUserId());
        fleetEntity.setNickname(fleetDTO.getNickname());
        fleetEntity.setOrgId(fleetDTO.getOrgId());
        return fleetEntity;
    }

}
