import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { BaseRepository } from '@edr/api-common';
import { IsNull, Repository } from 'typeorm';
import { MaintenanceInterval } from './entities/maintenance-interval.entity';
import { MaintenanceType } from './entities/maintenance-schedule.entity';

@Injectable()
export class MaintenanceIntervalRepository extends BaseRepository<MaintenanceInterval> {
  constructor(
    @InjectRepository(MaintenanceInterval)
    private readonly intervalRepository: Repository<MaintenanceInterval>,
  ) {
    super(intervalRepository);
  }

  /**
   * Resolve the interval for a completed service. Prefers the exact
   * (type, serviceItem) match; a completion without an item falls back to the
   * type's item-less interval only, so "oil" completions never consume the
   * "tires" interval.
   */
  async getByVehicleAndType(
    vehicleId: string,
    maintenanceType: MaintenanceType,
    serviceItem?: string | null,
  ): Promise<MaintenanceInterval | null> {
    return this.intervalRepository.findOne({
      where: {
        vehicleId,
        maintenanceType,
        isActive: true,
        serviceItem: serviceItem?.trim() ? serviceItem.trim() : IsNull(),
      },
    });
  }

  async getActiveIntervals(vehicleId: string): Promise<MaintenanceInterval[]> {
    return this.intervalRepository.find({
      where: { vehicleId, isActive: true },
      order: { maintenanceType: 'ASC', serviceItem: 'ASC' },
    });
  }

  async upsertInterval(
    vehicleId: string,
    maintenanceType: MaintenanceType,
    serviceItem?: string | null,
    intervalKm?: number | null,
    intervalDays?: number | null,
    description?: string | null,
  ): Promise<MaintenanceInterval> {
    const item = serviceItem?.trim() || null;
    const existing = await this.getByVehicleAndType(vehicleId, maintenanceType, item);

    if (existing) {
      await this.intervalRepository.update(existing.id, {
        intervalKm: intervalKm ?? existing.intervalKm,
        intervalDays: intervalDays ?? existing.intervalDays,
        description: description ?? existing.description,
      });
      const updated = await this.intervalRepository.findOneBy({ id: existing.id });
      return updated!;
    }

    return this.intervalRepository.save(
      this.intervalRepository.create({
        vehicleId,
        maintenanceType,
        serviceItem: item,
        intervalKm,
        intervalDays,
        description,
        isActive: true,
      }),
    );
  }

  /** Soft-disable: history keeps pointing at it, auto-scheduling stops. */
  async deactivate(id: string): Promise<void> {
    await this.intervalRepository.update(id, { isActive: false });
  }
}
