import { ContactImportJob } from "@prisma/client";
import {
  ContactImportJobsRepository,
  CreateImportJobData,
  IncrementImportJobCountersData,
  UpdateImportJobMappingData,
} from "./contact-import-jobs-repository";

export class InMemoryContactImportJobsRepository implements ContactImportJobsRepository {
  public items: ContactImportJob[] = [];

  async create(data: CreateImportJobData): Promise<ContactImportJob> {
    const job: ContactImportJob = {
      id: `import-job-${this.items.length + 1}`,
      fileName: data.fileName,
      status: "MAPPING",
      columnMapping: null,
      duplicateStrategy: null,
      targetListId: null,
      totalRows: data.totalRows,
      processedRows: 0,
      importedCount: 0,
      updatedCount: 0,
      skippedCount: 0,
      errorCount: 0,
      createdById: data.createdById,
      createdAt: new Date(),
      updatedAt: new Date(),
    };
    this.items.push(job);
    return job;
  }

  async findById(id: string): Promise<ContactImportJob | null> {
    return this.items.find((item) => item.id === id) ?? null;
  }

  async updateMapping(id: string, data: UpdateImportJobMappingData): Promise<ContactImportJob> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index === -1) throw new Error("Import job not found");

    const updated: ContactImportJob = {
      ...this.items[index],
      columnMapping: data.columnMapping as never,
      duplicateStrategy: data.duplicateStrategy,
      targetListId: data.targetListId ?? null,
      status: "PROCESSING",
      updatedAt: new Date(),
    };
    this.items[index] = updated;
    return updated;
  }

  async incrementCounters(id: string, data: IncrementImportJobCountersData): Promise<ContactImportJob> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index === -1) throw new Error("Import job not found");

    const current = this.items[index];
    const updated: ContactImportJob = {
      ...current,
      processedRows: current.processedRows + data.processedRows,
      importedCount: current.importedCount + data.importedCount,
      updatedCount: current.updatedCount + data.updatedCount,
      skippedCount: current.skippedCount + data.skippedCount,
      errorCount: current.errorCount + data.errorCount,
      updatedAt: new Date(),
    };
    this.items[index] = updated;
    return updated;
  }

  async markCompleted(id: string): Promise<ContactImportJob> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index === -1) throw new Error("Import job not found");

    const updated: ContactImportJob = { ...this.items[index], status: "COMPLETED", updatedAt: new Date() };
    this.items[index] = updated;
    return updated;
  }
}
