/**
 * TypeORM Carrier Repository
 *
 * Implements CarrierRepository interface using TypeORM
 */

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Carrier } from '@domain/entities/carrier.entity';
import { CarrierRepository } from '@domain/ports/out/carrier.repository';
import { CarrierOrmEntity } from '../entities/carrier.orm-entity';
import { CarrierOrmMapper } from '../mappers/carrier-orm.mapper';

@Injectable()
export class TypeOrmCarrierRepository implements CarrierRepository {
  constructor(
    @InjectRepository(CarrierOrmEntity)
    private readonly repository: Repository<CarrierOrmEntity>
  ) {}

  async save(carrier: Carrier): Promise<Carrier> {
    const orm = CarrierOrmMapper.toOrm(carrier);
    const saved = await this.repository.save(orm);
    return CarrierOrmMapper.toDomain(saved);
  }

  async saveMany(carriers: Carrier[]): Promise<Carrier[]> {
    const orms = carriers.map(carrier => CarrierOrmMapper.toOrm(carrier));
    const saved = await this.repository.save(orms);
    return CarrierOrmMapper.toDomainMany(saved);
  }

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

  async findByCode(code: string): Promise<Carrier | null> {
    const orm = await this.repository.findOne({
      where: { code: code.toUpperCase() },
    });
    return orm ? CarrierOrmMapper.toDomain(orm) : null;
  }

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

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

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

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

  async update(carrier: Carrier): Promise<Carrier> {
    const orm = CarrierOrmMapper.toOrm(carrier);
    const updated = await this.repository.save(orm);
    return CarrierOrmMapper.toDomain(updated);
  }

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