/**
 * Carrier Activity Repository
 *
 * Repository for carrier activity logging and querying
 */

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

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

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

  async create(data: {
    carrierId: string;
    bookingId?: string | null;
    activityType: CarrierActivityType;
    description?: string | null;
    metadata?: Record<string, any> | null;
    ipAddress?: string | null;
    userAgent?: string | null;
  }): Promise<CarrierActivityOrmEntity> {
    this.logger.log(
      `Creating carrier activity: ${data.activityType} for carrier ${data.carrierId}`
    );

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

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

  async findByCarrierId(
    carrierId: string,
    limit: number = 10
  ): Promise<CarrierActivityOrmEntity[]> {
    this.logger.log(`Finding activities for carrier: ${carrierId} (limit: ${limit})`);

    const activities = await this.repository.find({
      where: { carrierId },
      order: { createdAt: 'DESC' },
      take: limit,
    });

    this.logger.log(`Found ${activities.length} activities for carrier: ${carrierId}`);
    return activities;
  }

  async findByBookingId(bookingId: string): Promise<CarrierActivityOrmEntity[]> {
    this.logger.log(`Finding activities for booking: ${bookingId}`);

    const activities = await this.repository.find({
      where: { bookingId },
      order: { createdAt: 'DESC' },
    });

    this.logger.log(`Found ${activities.length} activities for booking: ${bookingId}`);
    return activities;
  }

  async findByActivityType(
    carrierId: string,
    activityType: CarrierActivityType,
    limit: number = 10
  ): Promise<CarrierActivityOrmEntity[]> {
    this.logger.log(`Finding ${activityType} activities for carrier: ${carrierId}`);

    const activities = await this.repository.find({
      where: { carrierId, activityType },
      order: { createdAt: 'DESC' },
      take: limit,
    });

    this.logger.log(
      `Found ${activities.length} ${activityType} activities for carrier: ${carrierId}`
    );
    return activities;
  }

  async findRecent(limit: number = 50): Promise<CarrierActivityOrmEntity[]> {
    this.logger.log(`Finding ${limit} most recent carrier activities`);

    const activities = await this.repository.find({
      order: { createdAt: 'DESC' },
      take: limit,
      relations: ['carrierProfile'],
    });

    this.logger.log(`Found ${activities.length} recent activities`);
    return activities;
  }

  async countByCarrier(carrierId: string): Promise<number> {
    this.logger.log(`Counting activities for carrier: ${carrierId}`);

    const count = await this.repository.count({
      where: { carrierId },
    });

    this.logger.log(`Found ${count} activities for carrier: ${carrierId}`);
    return count;
  }

  async countByType(carrierId: string, activityType: CarrierActivityType): Promise<number> {
    this.logger.log(`Counting ${activityType} activities for carrier: ${carrierId}`);

    const count = await this.repository.count({
      where: { carrierId, activityType },
    });

    this.logger.log(`Found ${count} ${activityType} activities for carrier: ${carrierId}`);
    return count;
  }

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

    const activity = await this.repository.findOne({
      where: { id },
      relations: ['carrierProfile', 'booking'],
    });

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

    return activity;
  }

  async deleteOlderThan(days: number): Promise<number> {
    this.logger.log(`Deleting carrier activities older than ${days} days`);

    const date = new Date();
    date.setDate(date.getDate() - days);

    const result = await this.repository
      .createQueryBuilder()
      .delete()
      .where('created_at < :date', { date })
      .execute();

    this.logger.log(`Deleted ${result.affected} carrier activities older than ${days} days`);
    return result.affected || 0;
  }
}
