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

export class PrismaDomainsRepository implements DomainsRepository {
  async findById(id: string): Promise<Domain | null> {
    return prisma.domain.findUnique({
      where: { id },
    });
  }

  async findByUserId(userId: string): Promise<Domain[]> {
    return prisma.domain.findMany({
      where: { userId },
      orderBy: { createdAt: "desc" },
    });
  }

  async searchByUserId(userId: string, query: string, limit: number): Promise<Domain[]> {
    return prisma.domain.findMany({
      where: { userId, domain: { contains: query, mode: "insensitive" } },
      orderBy: { createdAt: "desc" },
      take: limit,
    });
  }

  async findByDomainName(domainName: string): Promise<Domain | null> {
    return prisma.domain.findUnique({
      where: { domain: domainName },
    });
  }

  async findAllPending(): Promise<Domain[]> {
    return prisma.domain.findMany({
      where: { verificationStatus: DomainVerificationStatus.PENDING },
    });
  }

  async create(domain: string, userId: string): Promise<Domain> {
    return prisma.domain.create({
      data: {
        domain,
        userId,
      },
    });
  }

  async updateSesIdentity(id: string, data: UpdateSesIdentityInput): Promise<Domain> {
    return prisma.domain.update({
      where: { id },
      data: {
        dkimRecords: data.dkimRecords as unknown as Prisma.InputJsonValue,
        mailFromDomain: data.mailFromDomain,
        mailFromMxRecord: data.mailFromMxRecord,
        sesIdentityArn: data.sesIdentityArn,
        lastCheckedAt: new Date(),
      },
    });
  }

  async updateVerificationStatus(
    id: string,
    status: DomainVerificationStatus
  ): Promise<Domain> {
    return prisma.domain.update({
      where: { id },
      data: {
        verificationStatus: status,
        lastCheckedAt: new Date(),
        ...(status === DomainVerificationStatus.VERIFIED && { verifiedAt: new Date() }),
      },
    });
  }

  async delete(id: string): Promise<void> {
    await prisma.domain.delete({
      where: { id },
    });
  }
}
