/**
 * InMemory implementation of ISponsorshipPricingRepository
 */

import type { ISponsorshipPricingRepository } from '@core/racing/domain/repositories/ISponsorshipPricingRepository';
import { SponsorshipPricing } from '@core/racing/domain/value-objects/SponsorshipPricing';
import type { SponsorableEntityType } from '@core/racing/domain/entities/SponsorshipRequest';
import type { Logger } from '@core/shared/application';

export class InMemorySponsorshipPricingRepository implements ISponsorshipPricingRepository {
  private pricings: Map<string, { entityType: SponsorableEntityType; entityId: string; pricing: SponsorshipPricing }> = new Map();
  private readonly logger: Logger;

  constructor(logger: Logger) {
    this.logger = logger;
    this.logger.info('InMemorySponsorshipPricingRepository initialized.');
  }

  private makeKey(entityType: SponsorableEntityType, entityId: string): string {
    return `${entityType}:${entityId}`;
  }

  async findByEntity(entityType: SponsorableEntityType, entityId: string): Promise<SponsorshipPricing | null> {
    this.logger.debug(`Finding sponsorship pricing for entity: ${entityType}, ${entityId}`);
    try {
      const key = this.makeKey(entityType, entityId);
      const entry = this.pricings.get(key);
      const pricing = entry?.pricing ?? null;
      if (pricing) {
        this.logger.info(`Found sponsorship pricing for entity: ${entityType}, ${entityId}.`);
      } else {
        this.logger.warn(`Sponsorship pricing for entity ${entityType}, ${entityId} not found.`);
      }
      return pricing;
    } catch (error) {
      this.logger.error(`Error finding sponsorship pricing for entity ${entityType}, ${entityId}:`, error instanceof Error ? error : new Error(String(error)));
      throw error;
    }
  }

  async save(entityType: SponsorableEntityType, entityId: string, pricing: SponsorshipPricing): Promise<void> {
    this.logger.debug(`Saving sponsorship pricing for entity: ${entityType}, ${entityId}`);
    try {
      const key = this.makeKey(entityType, entityId);
      if (this.pricings.has(key)) {
        this.logger.info(`Updating existing sponsorship pricing for entity: ${entityType}, ${entityId}.`);
      } else {
        this.logger.info(`Creating new sponsorship pricing for entity: ${entityType}, ${entityId}.`);
      }
      this.pricings.set(key, { entityType, entityId, pricing });
      this.logger.info(`Sponsorship pricing saved for entity: ${entityType}, ${entityId}.`);
    } catch (error) {
      this.logger.error(`Error saving sponsorship pricing for entity ${entityType}, ${entityId}:`, error instanceof Error ? error : new Error(String(error)));
      throw error;
    }
  }

  async delete(entityType: SponsorableEntityType, entityId: string): Promise<void> {
    this.logger.debug(`Deleting sponsorship pricing for entity: ${entityType}, ${entityId}`);
    try {
      const key = this.makeKey(entityType, entityId);
      if (this.pricings.delete(key)) {
        this.logger.info(`Sponsorship pricing deleted for entity: ${entityType}, ${entityId}.`);
      } else {
        this.logger.warn(`Sponsorship pricing for entity ${entityType}, ${entityId} not found for deletion.`);
      }
    } catch (error) {
      this.logger.error(`Error deleting sponsorship pricing for entity ${entityType}, ${entityId}:`, error instanceof Error ? error : new Error(String(error)));
      throw error;
    }
  }

  async exists(entityType: SponsorableEntityType, entityId: string): Promise<boolean> {
    this.logger.debug(`Checking existence of sponsorship pricing for entity: ${entityType}, ${entityId}`);
    try {
      const key = this.makeKey(entityType, entityId);
      const exists = this.pricings.has(key);
      this.logger.debug(`Sponsorship pricing for entity ${entityType}, ${entityId} exists: ${exists}.`);
      return exists;
    } catch (error) {
      this.logger.error(`Error checking existence of sponsorship pricing for entity ${entityType}, ${entityId}:`, error instanceof Error ? error : new Error(String(error)));
      throw error;
    }
  }

  async findAcceptingApplications(entityType: SponsorableEntityType): Promise<Array<{
    entityId: string;
    pricing: SponsorshipPricing;
  }>> {
    this.logger.debug(`Finding entities accepting applications for type: ${entityType}`);
    try {
      const accepting = Array.from(this.pricings.values())
        .filter(entry => entry.entityType === entityType && entry.pricing.acceptingApplications)
        .map(entry => ({ entityId: entry.entityId, pricing: entry.pricing }));
      this.logger.info(`Found ${accepting.length} entities accepting applications for type: ${entityType}.`);
      return accepting;
    } catch (error) {
      this.logger.error(`Error finding accepting applications for entity type ${entityType}:`, error instanceof Error ? error : new Error(String(error)));
      throw error;
    }
  }
}