package com.kym.service.impl;


import com.github.yulichang.base.MPJBaseServiceImpl;
import com.kym.entity.Cars;
import com.kym.mapper.CarsMapper;
import com.kym.service.CarsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 车辆表 服务实现类
 * </p>
 *
 * @author skyline
 * @since 2023-07-26
 */
@Service
public class CarsServiceImpl extends MPJBaseServiceImpl<CarsMapper, Cars> implements CarsService {

    @Override
    public List<Map<String, Object>> listUserCars(Long userId) {
        return lambdaQuery()
                .eq(Cars::getUserId, userId)
                .and(w -> w.eq(Cars::getIsDelete, false).or().isNull(Cars::getIsDelete))
                .list()
                .stream()
                .map(car -> Map.<String, Object>of(
                        "id", car.getId().toString(),
                        "plateNo", car.getPlateNo(),
                        "isDefault", car.getIsDefault() != null && car.getIsDefault()
                ))
                .toList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveCar(Long userId, String plateNo) {
        var existing = lambdaQuery()
                .eq(Cars::getUserId, userId)
                .eq(Cars::getPlateNo, plateNo)
                .eq(Cars::getIsDelete, false)
                .one();
        if (existing != null) {
            setDefault(userId, existing.getId());
            return false;
        }
        long count = countUserCars(userId);
        var car = new Cars();
        car.setUserId(userId);
        car.setPlateNo(plateNo);
        car.setIsDelete(false);
        car.setIsDefault(count == 0);
        save(car);
        return true;
    }

    private long countUserCars(Long userId) {
        return lambdaQuery()
                .eq(Cars::getUserId, userId)
                .eq(Cars::getIsDelete, false)
                .count();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefault(Long userId, Long carId) {
        lambdaUpdate()
                .eq(Cars::getUserId, userId)
                .set(Cars::getIsDefault, false)
                .update();
        var car = lambdaQuery().eq(Cars::getId, carId).one();
        if (car != null) {
            car.setIsDefault(true);
            updateById(car);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteCar(Long userId, Long carId) {
        var car = lambdaQuery()
                .eq(Cars::getId, carId)
                .eq(Cars::getUserId, userId)
                .one();
        if (car == null) return;
        boolean wasDefault = car.getIsDefault() != null && car.getIsDefault();
        car.setIsDelete(true);
        car.setIsDefault(false);
        updateById(car);
        if (wasDefault) {
            var first = lambdaQuery()
                    .eq(Cars::getUserId, userId)
                    .eq(Cars::getIsDelete, false)
                    .orderByAsc(Cars::getId)
                    .last("limit 1")
                    .one();
            if (first != null) {
                first.setIsDefault(true);
                updateById(first);
            }
        }
    }
}
