import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BaseRepository } from '@edr/api-common';
import { Vehicle } from './entities/vehicle.entity';

@Injectable()
export class VehiclesRepository extends BaseRepository<Vehicle> {
  constructor(
    @InjectRepository(Vehicle)
    repository: Repository<Vehicle>,
  ) {
    super(repository);
  }

  async findByPlateNumber(plateNumber: string): Promise<Vehicle | null> {
    return this.repository.findOne({ where: { plateNumber } });
  }

  async findVehicleById(id: string): Promise<Vehicle | null> {
    return this.repository.findOne({ where: { id } });
  }

  async findAllWithFilters(query: {
    page?: number;
    pageSize?: number;
    search?: string;
    status?: string;
    sortBy?: string;
    sortOrder?: 'ASC' | 'DESC';
  }) {
    const page = query.page || 1;
    const pageSize = query.pageSize || 10;
    const skip = (page - 1) * pageSize;

    let queryBuilder = this.repository.createQueryBuilder('vehicle');

    if (query.search) {
      queryBuilder = queryBuilder.where(
        '(vehicle.plateNumber ILIKE :search OR vehicle.manufacturer ILIKE :search OR vehicle.model ILIKE :search)',
        { search: `%${query.search}%` },
      );
    }

    if (query.status) {
      queryBuilder = queryBuilder.andWhere('vehicle.status = :status', {
        status: query.status,
      });
    }

    const sortBy = query.sortBy || 'createdAt';
    const sortOrder = query.sortOrder || 'DESC';

    queryBuilder = queryBuilder
      .orderBy(`vehicle.${sortBy}`, sortOrder)
      .skip(skip)
      .take(pageSize);

    const [data, total] = await queryBuilder.getManyAndCount();

    return {
      data,
      total,
      page,
      pageSize,
      totalPages: Math.ceil(total / pageSize),
    };
  }

  async createVehicle(vehicleData: any): Promise<Vehicle> {
    const vehicle = this.repository.create(vehicleData);
    const vehicles = await this.repository.save(vehicle);
    return vehicles?.[0] as Vehicle;
  }

  async updateVehicle(vehicle: Vehicle): Promise<Vehicle> {
    return (await this.repository.save(vehicle)) as Vehicle;
  }
}
