/**
 * Carrier Profile Repository
 *
 * Repository for carrier profile CRUD operations
 */

import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CarrierProfileOrmEntity } from '../entities/carrier-profile.orm-entity';

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

  constructor(
    @InjectRepository(CarrierProfileOrmEntity)
    private readonly repository: Repository<CarrierProfileOrmEntity>
  ) {}

  async findById(id: string): Promise<CarrierProfileOrmEntity | null> {
    this.logger.log(`Finding carrier profile by ID: ${id}`);

    const profile = await this.repository.findOne({
      where: { id },
      relations: ['user', 'organization'],
    });

    if (!profile) {
      this.logger.log(`Carrier profile not found: ${id}`);
      return null;
    }

    return profile;
  }

  async findByUserId(userId: string): Promise<CarrierProfileOrmEntity | null> {
    this.logger.log(`Finding carrier profile by user ID: ${userId}`);

    const profile = await this.repository.findOne({
      where: { userId },
      relations: ['user', 'organization'],
    });

    if (!profile) {
      this.logger.log(`Carrier profile not found for user: ${userId}`);
      return null;
    }

    return profile;
  }

  async findByEmail(email: string): Promise<CarrierProfileOrmEntity | null> {
    this.logger.log(`Finding carrier profile by email: ${email}`);

    const profile = await this.repository.findOne({
      where: { user: { email: email.toLowerCase() } },
      relations: ['user', 'organization'],
    });

    if (!profile) {
      this.logger.log(`Carrier profile not found for email: ${email}`);
      return null;
    }

    return profile;
  }

  async create(data: Partial<CarrierProfileOrmEntity>): Promise<CarrierProfileOrmEntity> {
    this.logger.log(`Creating carrier profile for user: ${data.userId}`);

    const profile = this.repository.create(data);
    const saved = await this.repository.save(profile);

    this.logger.log(`Carrier profile created successfully: ${saved.id}`);
    return saved;
  }

  async update(
    id: string,
    data: Partial<CarrierProfileOrmEntity>
  ): Promise<CarrierProfileOrmEntity> {
    this.logger.log(`Updating carrier profile: ${id}`);

    await this.repository.update(id, data);
    const updated = await this.findById(id);

    if (!updated) {
      throw new Error(`Carrier profile not found after update: ${id}`);
    }

    this.logger.log(`Carrier profile updated successfully: ${id}`);
    return updated;
  }

  async updateStatistics(
    id: string,
    stats: {
      totalBookingsAccepted?: number;
      totalBookingsRejected?: number;
      acceptanceRate?: number;
      totalRevenueUsd?: number;
      totalRevenueEur?: number;
    }
  ): Promise<void> {
    this.logger.log(`Updating carrier statistics: ${id}`);
    await this.repository.update(id, stats);
    this.logger.log(`Carrier statistics updated successfully: ${id}`);
  }

  async updateLastLogin(id: string): Promise<void> {
    this.logger.log(`Updating last login for carrier: ${id}`);
    await this.repository.update(id, { lastLoginAt: new Date() });
    this.logger.log(`Last login updated successfully: ${id}`);
  }

  async findAll(): Promise<CarrierProfileOrmEntity[]> {
    this.logger.log('Finding all carrier profiles');

    const profiles = await this.repository.find({
      relations: ['user', 'organization'],
      order: { companyName: 'ASC' },
    });

    this.logger.log(`Found ${profiles.length} carrier profiles`);
    return profiles;
  }

  async findByOrganizationId(organizationId: string): Promise<CarrierProfileOrmEntity[]> {
    this.logger.log(`Finding carrier profiles for organization: ${organizationId}`);

    const profiles = await this.repository.find({
      where: { organizationId },
      relations: ['user', 'organization'],
    });

    this.logger.log(
      `Found ${profiles.length} carrier profiles for organization: ${organizationId}`
    );
    return profiles;
  }

  async delete(id: string): Promise<void> {
    this.logger.log(`Deleting carrier profile: ${id}`);

    const result = await this.repository.delete({ id });

    if (result.affected === 0) {
      throw new Error(`Carrier profile not found: ${id}`);
    }

    this.logger.log(`Carrier profile deleted successfully: ${id}`);
  }
}
