/**
 * TypeORM Subscription Repository
 *
 * Implements SubscriptionRepository interface using TypeORM
 */

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Subscription } from '@domain/entities/subscription.entity';
import { SubscriptionRepository } from '@domain/ports/out/subscription.repository';
import { SubscriptionOrmEntity } from '../entities/subscription.orm-entity';
import { SubscriptionOrmMapper } from '../mappers/subscription-orm.mapper';

@Injectable()
export class TypeOrmSubscriptionRepository implements SubscriptionRepository {
  constructor(
    @InjectRepository(SubscriptionOrmEntity)
    private readonly repository: Repository<SubscriptionOrmEntity>
  ) {}

  async save(subscription: Subscription): Promise<Subscription> {
    const orm = SubscriptionOrmMapper.toOrm(subscription);
    const saved = await this.repository.save(orm);
    return SubscriptionOrmMapper.toDomain(saved);
  }

  async findById(id: string): Promise<Subscription | null> {
    const orm = await this.repository.findOne({ where: { id } });
    return orm ? SubscriptionOrmMapper.toDomain(orm) : null;
  }

  async findByOrganizationId(organizationId: string): Promise<Subscription | null> {
    const orm = await this.repository.findOne({ where: { organizationId } });
    return orm ? SubscriptionOrmMapper.toDomain(orm) : null;
  }

  async findByStripeSubscriptionId(stripeSubscriptionId: string): Promise<Subscription | null> {
    const orm = await this.repository.findOne({ where: { stripeSubscriptionId } });
    return orm ? SubscriptionOrmMapper.toDomain(orm) : null;
  }

  async findByStripeCustomerId(stripeCustomerId: string): Promise<Subscription | null> {
    const orm = await this.repository.findOne({ where: { stripeCustomerId } });
    return orm ? SubscriptionOrmMapper.toDomain(orm) : null;
  }

  async findAll(): Promise<Subscription[]> {
    const orms = await this.repository.find({
      order: { createdAt: 'DESC' },
    });
    return SubscriptionOrmMapper.toDomainMany(orms);
  }

  async delete(id: string): Promise<void> {
    await this.repository.delete({ id });
  }
}
