import { Domain, DomainVerificationStatus, Prisma } from "@prisma/client";
import { DomainsRepository, UpdateSesIdentityInput } from "./domains-repository";

export class InMemoryDomainsRepository implements DomainsRepository {
  public items: Domain[] = [];

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

  async findByUserId(userId: string): Promise<Domain[]> {
    return this.items
      .filter((item) => item.userId === userId)
      .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
  }

  async searchByUserId(userId: string, query: string, limit: number): Promise<Domain[]> {
    const normalized = query.toLowerCase();

    return this.items
      .filter((item) => item.userId === userId && item.domain.toLowerCase().includes(normalized))
      .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
      .slice(0, limit);
  }

  async findByDomainName(domainName: string): Promise<Domain | null> {
    const domain = this.items.find((item) => item.domain === domainName);
    return domain ?? null;
  }

  async findAllPending(): Promise<Domain[]> {
    return this.items.filter((item) => item.verificationStatus === DomainVerificationStatus.PENDING);
  }

  async create(domainName: string, userId: string): Promise<Domain> {
    const domainItem: Domain = {
      id: `cdomain${this.items.length + 1}`,
      domain: domainName,
      verificationStatus: DomainVerificationStatus.PENDING,
      dkimRecords: null,
      mailFromDomain: null,
      mailFromMxRecord: null,
      sesIdentityArn: null,
      verifiedAt: null,
      lastCheckedAt: null,
      userId,
      createdAt: new Date(),
      updatedAt: new Date(),
    };

    this.items.push(domainItem);
    return domainItem;
  }

  async updateSesIdentity(id: string, data: UpdateSesIdentityInput): Promise<Domain> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index === -1) {
      throw new Error("Domain not found");
    }

    const updated: Domain = {
      ...this.items[index],
      dkimRecords: data.dkimRecords as unknown as Prisma.JsonValue,
      mailFromDomain: data.mailFromDomain,
      mailFromMxRecord: data.mailFromMxRecord,
      sesIdentityArn: data.sesIdentityArn ?? null,
      lastCheckedAt: new Date(),
      updatedAt: new Date(),
    };

    this.items[index] = updated;
    return updated;
  }

  async updateVerificationStatus(
    id: string,
    status: DomainVerificationStatus
  ): Promise<Domain> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index === -1) {
      throw new Error("Domain not found");
    }

    const updated: Domain = {
      ...this.items[index],
      verificationStatus: status,
      lastCheckedAt: new Date(),
      verifiedAt: status === DomainVerificationStatus.VERIFIED ? new Date() : this.items[index].verifiedAt,
      updatedAt: new Date(),
    };

    this.items[index] = updated;
    return updated;
  }

  async delete(id: string): Promise<void> {
    const index = this.items.findIndex((item) => item.id === id);
    if (index !== -1) {
      this.items.splice(index, 1);
    }
  }
}
