/**
 * Fleet Service
 * Mecánicas Diesel - ERP Suite
 *
 * Business logic for fleet management.
 */

import { Repository, DataSource } from 'typeorm';
import { Fleet } from '../entities/fleet.entity';
import { Vehicle, VehicleStatus } from '../entities/vehicle.entity';

// DTOs
export interface CreateFleetDto {
  name: string;
  code?: string;
  contactName?: string;
  contactPhone?: string;
  contactEmail?: string;
  discountLaborPct?: number;
  discountPartsPct?: number;
  creditDays?: number;
  creditLimit?: number;
  notes?: string;
}

export interface UpdateFleetDto {
  name?: string;
  code?: string;
  contactName?: string;
  contactPhone?: string;
  contactEmail?: string;
  discountLaborPct?: number;
  discountPartsPct?: number;
  creditDays?: number;
  creditLimit?: number;
  notes?: string;
  isActive?: boolean;
}

export class FleetService {
  private fleetRepository: Repository<Fleet>;
  private vehicleRepository: Repository<Vehicle>;

  constructor(dataSource: DataSource) {
    this.fleetRepository = dataSource.getRepository(Fleet);
    this.vehicleRepository = dataSource.getRepository(Vehicle);
  }

  /**
   * Create a new fleet
   */
  async create(tenantId: string, dto: CreateFleetDto): Promise<Fleet> {
    const fleet = this.fleetRepository.create({
      tenantId,
      name: dto.name,
      code: dto.code,
      contactName: dto.contactName,
      contactPhone: dto.contactPhone,
      contactEmail: dto.contactEmail,
      discountLaborPct: dto.discountLaborPct || 0,
      discountPartsPct: dto.discountPartsPct || 0,
      creditDays: dto.creditDays || 0,
      creditLimit: dto.creditLimit || 0,
      notes: dto.notes,
      isActive: true,
      vehicleCount: 0,
    });

    return this.fleetRepository.save(fleet);
  }

  /**
   * Find fleet by ID
   */
  async findById(tenantId: string, id: string): Promise<Fleet | null> {
    return this.fleetRepository.findOne({
      where: { id, tenantId },
    });
  }

  /**
   * List fleets
   */
  async findAll(
    tenantId: string,
    pagination = { page: 1, limit: 20 }
  ) {
    const queryBuilder = this.fleetRepository.createQueryBuilder('fleet')
      .where('fleet.tenant_id = :tenantId', { tenantId });

    const skip = (pagination.page - 1) * pagination.limit;

    const [data, total] = await queryBuilder
      .orderBy('fleet.name', 'ASC')
      .skip(skip)
      .take(pagination.limit)
      .getManyAndCount();

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

  /**
   * Update fleet
   */
  async update(tenantId: string, id: string, dto: UpdateFleetDto): Promise<Fleet | null> {
    const fleet = await this.findById(tenantId, id);
    if (!fleet) return null;

    Object.assign(fleet, dto);
    return this.fleetRepository.save(fleet);
  }

  /**
   * Deactivate fleet
   */
  async deactivate(tenantId: string, id: string): Promise<boolean> {
    const fleet = await this.findById(tenantId, id);
    if (!fleet) return false;

    fleet.isActive = false;
    await this.fleetRepository.save(fleet);
    return true;
  }

  /**
   * Get fleet with vehicle count
   */
  async getFleetWithStats(tenantId: string, id: string): Promise<{
    fleet: Fleet;
    vehicleCount: number;
    activeVehicles: number;
  } | null> {
    const fleet = await this.findById(tenantId, id);
    if (!fleet) return null;

    const [vehicleCount, activeVehicles] = await Promise.all([
      this.vehicleRepository.count({ where: { tenantId, fleetId: id } }),
      this.vehicleRepository.count({ where: { tenantId, fleetId: id, status: VehicleStatus.ACTIVE } }),
    ]);

    return {
      fleet,
      vehicleCount,
      activeVehicles,
    };
  }

  /**
   * Get active fleets
   */
  async findActive(tenantId: string): Promise<Fleet[]> {
    return this.fleetRepository.find({
      where: { tenantId, isActive: true },
      order: { name: 'ASC' },
    });
  }

  /**
   * Add vehicle to fleet
   */
  async addVehicle(tenantId: string, fleetId: string, vehicleId: string): Promise<boolean> {
    const fleet = await this.findById(tenantId, fleetId);
    if (!fleet) return false;

    const vehicle = await this.vehicleRepository.findOne({
      where: { id: vehicleId, tenantId },
    });
    if (!vehicle) return false;

    vehicle.fleetId = fleetId;
    await this.vehicleRepository.save(vehicle);

    // Update vehicle count
    fleet.vehicleCount = await this.vehicleRepository.count({ where: { tenantId, fleetId } });
    await this.fleetRepository.save(fleet);

    return true;
  }

  /**
   * Remove vehicle from fleet
   */
  async removeVehicle(tenantId: string, fleetId: string, vehicleId: string): Promise<boolean> {
    const vehicle = await this.vehicleRepository.findOne({
      where: { id: vehicleId, tenantId, fleetId },
    });
    if (!vehicle) return false;

    const fleet = await this.findById(tenantId, fleetId);
    if (!fleet) return false;

    vehicle.fleetId = undefined;
    await this.vehicleRepository.save(vehicle);

    // Update vehicle count
    fleet.vehicleCount = await this.vehicleRepository.count({ where: { tenantId, fleetId } });
    await this.fleetRepository.save(fleet);

    return true;
  }
}
