import { Injectable, NotFoundException, Logger } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateVehicleDto, UpdateVehicleDto } from './dto';

@Injectable()
export class VehiclesService {
  private readonly logger = new Logger(VehiclesService.name);

  constructor(private prisma: PrismaService) {}

  async create(createVehicleDto: CreateVehicleDto) {
    this.logger.log(`Creating vehicle: ${createVehicleDto.name}`);

    return this.prisma.vehicle.create({
      data: createVehicleDto,
      include: {
        currentDriver: true,
        events: {
          where: { deletedAt: null },
          include: { driver: true, vehicle: true },
        },
      },
    });
  }

  async findAll() {
    return this.prisma.vehicle.findMany({
      where: { deletedAt: null },
      include: {
        currentDriver: true,
        events: {
          where: { deletedAt: null },
          include: { driver: true, vehicle: true },
          orderBy: { startTime: 'asc' },
        },
      },
      orderBy: { name: 'asc' },
    });
  }

  async findAvailable() {
    return this.prisma.vehicle.findMany({
      where: {
        deletedAt: null,
        status: 'AVAILABLE',
      },
      include: {
        currentDriver: true,
      },
      orderBy: { name: 'asc' },
    });
  }

  async findOne(id: string) {
    const vehicle = await this.prisma.vehicle.findFirst({
      where: { id, deletedAt: null },
      include: {
        currentDriver: true,
        events: {
          where: { deletedAt: null },
          include: { driver: true, vehicle: true },
          orderBy: { startTime: 'asc' },
        },
      },
    });

    if (!vehicle) {
      throw new NotFoundException(`Vehicle with ID ${id} not found`);
    }

    return vehicle;
  }

  async update(id: string, updateVehicleDto: UpdateVehicleDto) {
    const vehicle = await this.findOne(id);

    this.logger.log(`Updating vehicle ${id}: ${vehicle.name}`);

    return this.prisma.vehicle.update({
      where: { id: vehicle.id },
      data: updateVehicleDto,
      include: {
        currentDriver: true,
        events: {
          where: { deletedAt: null },
          include: { driver: true, vehicle: true },
        },
      },
    });
  }

  async remove(id: string, hardDelete = false) {
    const vehicle = await this.findOne(id);

    if (hardDelete) {
      this.logger.log(`Hard deleting vehicle: ${vehicle.name}`);
      return this.prisma.vehicle.delete({
        where: { id: vehicle.id },
      });
    }

    this.logger.log(`Soft deleting vehicle: ${vehicle.name}`);
    return this.prisma.vehicle.update({
      where: { id: vehicle.id },
      data: { deletedAt: new Date() },
    });
  }

  /**
   * Get vehicle utilization statistics
   */
  async getUtilization() {
    const vehicles = await this.findAll();

    const stats = vehicles.map((vehicle) => {
      const upcomingEvents = vehicle.events.filter(
        (event) => new Date(event.startTime) > new Date(),
      );

      return {
        id: vehicle.id,
        name: vehicle.name,
        type: vehicle.type,
        seatCapacity: vehicle.seatCapacity,
        status: vehicle.status,
        upcomingTrips: upcomingEvents.length,
        currentDriver: vehicle.currentDriver?.name,
      };
    });

    return {
      totalVehicles: vehicles.length,
      available: vehicles.filter((v) => v.status === 'AVAILABLE').length,
      inUse: vehicles.filter((v) => v.status === 'IN_USE').length,
      maintenance: vehicles.filter((v) => v.status === 'MAINTENANCE').length,
      reserved: vehicles.filter((v) => v.status === 'RESERVED').length,
      vehicles: stats,
    };
  }
}
