/**
 * TypeORM Organization Repository
 *
 * Implements OrganizationRepository interface using TypeORM
 */

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Organization } from '@domain/entities/organization.entity';
import { OrganizationRepository } from '@domain/ports/out/organization.repository';
import { OrganizationOrmEntity } from '../entities/organization.orm-entity';
import { OrganizationOrmMapper } from '../mappers/organization-orm.mapper';

@Injectable()
export class TypeOrmOrganizationRepository implements OrganizationRepository {
  constructor(
    @InjectRepository(OrganizationOrmEntity)
    private readonly repository: Repository<OrganizationOrmEntity>
  ) {}

  async save(organization: Organization): Promise<Organization> {
    const orm = OrganizationOrmMapper.toOrm(organization);
    const saved = await this.repository.save(orm);
    return OrganizationOrmMapper.toDomain(saved);
  }

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

  async findByName(name: string): Promise<Organization | null> {
    const orm = await this.repository.findOne({ where: { name } });
    return orm ? OrganizationOrmMapper.toDomain(orm) : null;
  }

  async findBySCAC(scac: string): Promise<Organization | null> {
    const orm = await this.repository.findOne({
      where: { scac: scac.toUpperCase() },
    });
    return orm ? OrganizationOrmMapper.toDomain(orm) : null;
  }

  async findAll(): Promise<Organization[]> {
    const orms = await this.repository.find({
      order: { name: 'ASC' },
    });
    return OrganizationOrmMapper.toDomainMany(orms);
  }

  async findAllActive(): Promise<Organization[]> {
    const orms = await this.repository.find({
      where: { isActive: true },
      order: { name: 'ASC' },
    });
    return OrganizationOrmMapper.toDomainMany(orms);
  }

  async findByType(type: string): Promise<Organization[]> {
    const orms = await this.repository.find({
      where: { type },
      order: { name: 'ASC' },
    });
    return OrganizationOrmMapper.toDomainMany(orms);
  }

  async update(organization: Organization): Promise<Organization> {
    const orm = OrganizationOrmMapper.toOrm(organization);
    const updated = await this.repository.save(orm);
    return OrganizationOrmMapper.toDomain(updated);
  }

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

  async count(): Promise<number> {
    return this.repository.count();
  }
}
