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

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

  async findByLicenseNumber(licenseNumber: string): Promise<Driver | null> {
    return this.repository.findOne({ where: { licenseNumber } });
  }

  async findByEmail(email: string): Promise<Driver | null> {
    return this.repository.findOne({ where: { email } });
  }

  async findByPhoneNumber(phoneNumber: string): Promise<Driver | null> {
    return this.repository.findOne({ where: { phoneNumber } });
  }

  async findDriverById(id: string): Promise<Driver | 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('driver');

    if (query.search) {
      queryBuilder = queryBuilder.where(
        '(driver.firstName ILIKE :search OR driver.lastName ILIKE :search OR driver.email ILIKE :search OR driver.phoneNumber ILIKE :search OR driver.licenseNumber ILIKE :search)',
        { search: `%${query.search}%` },
      );
    }

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

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

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

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

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

  async createDriver(driverData: any): Promise<Driver> {
    const driver = this.repository.create(driverData);
    const result = await this.repository.save(driver);
    return result?.[0] as Driver;
  }

  async updateDriver(driver: Driver): Promise<Driver> {
    const result = await this.repository.save(driver);
    return result as Driver;
  }
}
