import { AppError } from "@/core/errors/app-error";
import { parseCsv } from "../entities/parse-csv";
import { ContactImportJobsRepository } from "../repositories/contact-import-jobs-repository";
import { ContactImportRowsRepository } from "../repositories/contact-import-rows-repository";

const SAMPLE_ROWS_COUNT = 5;
const MAX_IMPORT_ROWS = 50_000;

interface ParseContactImportUseCaseRequest {
  fileName: string;
  csvContent: string;
  createdById: string;
}

interface ParseContactImportUseCaseResponse {
  jobId: string;
  headers: string[];
  sampleRows: Record<string, string>[];
  totalRows: number;
}

export class ParseContactImportUseCase {
  constructor(
    private contactImportJobsRepository: ContactImportJobsRepository,
    private contactImportRowsRepository: ContactImportRowsRepository
  ) {}

  async execute({
    fileName,
    csvContent,
    createdById,
  }: ParseContactImportUseCaseRequest): Promise<ParseContactImportUseCaseResponse> {
    const parsed = parseCsv(csvContent);

    if (parsed.rows.length === 0) {
      throw AppError.badRequest("O arquivo está vazio ou não tem linhas de dados");
    }
    if (parsed.rows.length > MAX_IMPORT_ROWS) {
      throw AppError.badRequest(
        `O arquivo tem ${parsed.rows.length} linhas — o máximo suportado por importação é ${MAX_IMPORT_ROWS}. Divida o arquivo em partes menores.`
      );
    }

    const job = await this.contactImportJobsRepository.create({
      fileName,
      totalRows: parsed.rows.length,
      createdById,
    });

    await this.contactImportRowsRepository.createMany(
      job.id,
      parsed.rows.map((rawData, index) => ({ rowIndex: index, rawData }))
    );

    return {
      jobId: job.id,
      headers: parsed.headers,
      sampleRows: parsed.rows.slice(0, SAMPLE_ROWS_COUNT),
      totalRows: parsed.rows.length,
    };
  }
}
