import type { MedicineProductsRepository } from './medicine-products.repository.js';
import type { MedicinesRepository } from '../medicines/medicines.repository.js';
import type { CreateMedicineProductInput, UpdateMedicineProductInput } from '@meshitrack/shared';
import { NotFoundError } from '../../common/errors.js';

interface Deps {
  medicineProductsRepository: MedicineProductsRepository;
  medicinesRepository: MedicinesRepository;
}

export class MedicineProductsService {
  private readonly medicineProductsRepository: MedicineProductsRepository;
  private readonly medicinesRepository: MedicinesRepository;

  public constructor({ medicineProductsRepository, medicinesRepository }: Deps) {
    this.medicineProductsRepository = medicineProductsRepository;
    this.medicinesRepository = medicinesRepository;
  }

  public async listByMedicine(
    householdId: string,
    medicineId: string,
    query: { cursor?: string; limit: number },
  ) {
    return this.medicineProductsRepository.findByMedicine(householdId, medicineId, query);
  }

  public async getById(id: string, householdId: string) {
    const product = await this.medicineProductsRepository.findById(id, householdId);
    if (!product) {
      throw new NotFoundError('Medicine product not found');
    }
    return product;
  }

  public async create(
    data: CreateMedicineProductInput,
    householdId: string,
    medicineId: string,
    createdBy: string,
  ) {
    const medicine = await this.medicinesRepository.findById(medicineId, householdId);
    if (!medicine) {
      throw new NotFoundError('Medicine not found');
    }

    return this.medicineProductsRepository.create(
      data,
      householdId,
      medicineId,
      medicine.name,
      createdBy,
    );
  }

  public async update(id: string, householdId: string, data: UpdateMedicineProductInput) {
    await this.getById(id, householdId);
    const updated = await this.medicineProductsRepository.update(id, householdId, data);
    if (!updated) throw new NotFoundError('Medicine product not found');
    return updated;
  }

  public async delete(id: string, householdId: string) {
    await this.getById(id, householdId);
    const deleted = await this.medicineProductsRepository.softDelete(id, householdId);
    if (!deleted) throw new NotFoundError('Medicine product not found');
    return deleted;
  }
}
