package org.dromara.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.domain.proprietorCar.ProprietorCar;
import org.dromara.domain.proprietorCar.bo.ProprietorCarBo;
import org.dromara.domain.proprietorCar.vo.ProprietorCarVo;
import org.dromara.mapper.ProprietorCarMapper;
import org.dromara.service.IProprietorCarService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 业主车辆管理Service业务层处理
 *
 * @author boman
 * @date 2025-04-11
 */
@RequiredArgsConstructor
@Service
public class ProprietorCarServiceImpl implements IProprietorCarService {

    private final ProprietorCarMapper baseMapper;

    /**
     * 查询业主车辆管理
     *
     * @param carId 主键
     * @return 业主车辆管理
     */
    @Override
    public ProprietorCarVo queryById(Long carId){
        return baseMapper.selectVoById(carId);
    }

    /**
     * 分页查询业主车辆管理列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 业主车辆管理分页列表
     */
    @Override
    public TableDataInfo<ProprietorCarVo> queryPageList(ProprietorCarBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ProprietorCar> lqw = buildQueryWrapper(bo);
        Page<ProprietorCarVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的业主车辆管理列表
     *
     * @param bo 查询条件
     * @return 业主车辆管理列表
     */
    @Override
    public List<ProprietorCarVo> queryList(ProprietorCarBo bo) {
        LambdaQueryWrapper<ProprietorCar> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ProprietorCar> buildQueryWrapper(ProprietorCarBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ProprietorCar> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(ProprietorCar::getCarId);
        lqw.eq(bo.getHouseId() != null, ProprietorCar::getHouseId, bo.getHouseId());
        lqw.eq(StringUtils.isNotBlank(bo.getDetailedAddress()), ProprietorCar::getDetailedAddress, bo.getDetailedAddress());
        lqw.eq(bo.getResidentId() != null, ProprietorCar::getResidentId, bo.getResidentId());
        lqw.eq(bo.getUserId() != null, ProprietorCar::getUserId, bo.getUserId());
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), ProprietorCar::getUserName, bo.getUserName());
        lqw.eq(StringUtils.isNotBlank(bo.getResidentPhone()), ProprietorCar::getResidentPhone, bo.getResidentPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getPlateNumber()), ProprietorCar::getPlateNumber, bo.getPlateNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getVehicleBrand()), ProprietorCar::getVehicleBrand, bo.getVehicleBrand());
        lqw.eq(StringUtils.isNotBlank(bo.getVehicleType()), ProprietorCar::getVehicleType, bo.getVehicleType());
        lqw.eq(StringUtils.isNotBlank(bo.getVehicleEnergy()), ProprietorCar::getVehicleEnergy, bo.getVehicleEnergy());
        lqw.eq(StringUtils.isNotBlank(bo.getVehicleColour()), ProprietorCar::getVehicleColour, bo.getVehicleColour());
        lqw.eq(StringUtils.isNotBlank(bo.getEngineNumber()), ProprietorCar::getEngineNumber, bo.getEngineNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getIdentificationNumber()), ProprietorCar::getIdentificationNumber, bo.getIdentificationNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getRegistrationDate()), ProprietorCar::getRegistrationDate, bo.getRegistrationDate());
        lqw.eq(StringUtils.isNotBlank(bo.getIssueDate()), ProprietorCar::getIssueDate, bo.getIssueDate());
        return lqw;
    }

    /**
     * 新增业主车辆管理
     *
     * @param bo 业主车辆管理
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ProprietorCarBo bo) {
        ProprietorCar add = MapstructUtils.convert(bo, ProprietorCar.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setCarId(add.getCarId());
        }
        return flag;
    }

    /**
     * 判断车牌号是否合规
     *
     * @param plateNumber
     * @return
     */
    public static boolean checkPlateNumber(String plateNumber) {
        String regEx = "^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$";
        // 编译正则表达式
        //Pattern pattern = Pattern.compile(regEx);
        // 忽略大小写的写法
        Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);

        Matcher matcher = pat.matcher(plateNumber);
        // 字符串是否与正则表达式相匹配
        return matcher.matches();
    }

    /**
     * 修改业主车辆管理
     *
     * @param bo 业主车辆管理
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ProprietorCarBo bo) {
        ProprietorCar update = MapstructUtils.convert(bo, ProprietorCar.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ProprietorCar entity){
        //TODO 做一些数据校验,如唯一约束
        String plateNumber = entity.getPlateNumber();
        if (!checkPlateNumber(plateNumber)){
           throw new UserException("plate.number.error",plateNumber);
        }
    }

    /**
     * 校验并批量删除业主车辆管理信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
