import { Injectable, NotFoundException } from '@nestjs/common';
import { FindOptionsWhere } from 'typeorm';
import { IncidentsRepository } from './incidents.repository';
import {
  Incident,
  IncidentStatus,
  IncidentType,
} from './entities/incident.entity';
import { CreateIncidentDto } from './dto/create-incident.dto';
import { UpdateIncidentDto } from './dto/update-incident.dto';

export interface IncidentFilter {
  vehicleId?: string;
  driverId?: string;
  status?: IncidentStatus;
  type?: IncidentType;
}

export interface DriverIncidentStats {
  total: number;
  byType: Record<string, number>;
  lastIncidentAt: Date | null;
}

@Injectable()
export class IncidentsService {
  constructor(private readonly incidentsRepository: IncidentsRepository) {}

  async create(dto: CreateIncidentDto): Promise<Incident> {
    return this.incidentsRepository.create({
      ...dto,
      occurredAt: new Date(dto.occurredAt),
    });
  }

  async findAll(filter: IncidentFilter = {}): Promise<Incident[]> {
    const where: FindOptionsWhere<Incident> = {};
    if (filter.vehicleId) where.vehicleId = filter.vehicleId;
    if (filter.driverId) where.driverId = filter.driverId;
    if (filter.status) where.status = filter.status;
    if (filter.type) where.type = filter.type;

    return this.incidentsRepository.findAll({
      where,
      order: { occurredAt: 'DESC' },
    });
  }

  async findByDriver(driverId: string): Promise<Incident[]> {
    return this.incidentsRepository.findAll({
      where: { driverId },
      order: { occurredAt: 'DESC' },
    });
  }

  async findById(id: string): Promise<Incident> {
    const incident = await this.incidentsRepository.findById(id);
    if (!incident) {
      throw new NotFoundException(`Incident ${id} not found`);
    }
    return incident;
  }

  async update(id: string, dto: UpdateIncidentDto): Promise<Incident> {
    await this.findById(id);
    const updated = await this.incidentsRepository.update(id, {
      ...dto,
      occurredAt: dto.occurredAt ? new Date(dto.occurredAt) : undefined,
    });
    return updated!;
  }

  async remove(id: string): Promise<void> {
    await this.findById(id);
    await this.incidentsRepository.softDelete(id);
  }

  async statsForDriver(driverId: string): Promise<DriverIncidentStats> {
    const incidents = await this.incidentsRepository.findAll({
      where: { driverId },
      order: { occurredAt: 'DESC' },
    });

    const byType: Record<string, number> = {};
    for (const incident of incidents) {
      byType[incident.type] = (byType[incident.type] || 0) + 1;
    }

    return {
      total: incidents.length,
      byType,
      lastIncidentAt: incidents.length > 0 ? incidents[0].occurredAt : null,
    };
  }
}
