import { Contact, ContactSource, ContactStatus, MarketingChannel } from "@prisma/client";

export type ContactWithLists = Contact & {
  listMemberships: { list: { id: string; name: string; marketingChannel?: MarketingChannel } }[];
};

export interface ContactListFilters {
  search?: string;
  tag?: string;
  listId?: string;
  status?: ContactStatus;
  openedWithinDays?: number;
  subscribedWithinDays?: number;
}

export type ContactSortBy = "name" | "email" | "createdAt";
export type SortDirection = "asc" | "desc";

export interface FindPaginatedOptions extends ContactListFilters {
  skip: number;
  take: number;
  sortBy?: ContactSortBy;
  sortDir?: SortDirection;
}

export interface CreateContactData {
  email: string;
  name?: string | null;
  lastName?: string | null;
  phone?: string | null;
  bairro?: string | null;
  cidade?: string | null;
  uf?: string | null;
  idioma?: string | null;
  empresa?: string | null;
  cep?: string | null;
  codigoEstabelecimento?: string | null;
  nomeEstabelecimento?: string | null;
  cdate?: string | null;
  tags?: string[];
  source?: ContactSource;
}

export interface UpdateContactData {
  status?: ContactStatus;
  name?: string | null;
  lastName?: string | null;
  phone?: string | null;
  bairro?: string | null;
  cidade?: string | null;
  uf?: string | null;
  idioma?: string | null;
  empresa?: string | null;
  cep?: string | null;
  codigoEstabelecimento?: string | null;
  nomeEstabelecimento?: string | null;
  cdate?: string | null;
  tags?: string[];
}

export interface ContactsRepository {
  findAll(): Promise<Contact[]>;
  findAllWithLists(): Promise<ContactWithLists[]>;
  findById(id: string): Promise<Contact | null>;
  findByIdWithLists(id: string): Promise<ContactWithLists | null>;
  findAllActive(): Promise<Contact[]>;
  findActiveByListId(listId: string): Promise<Contact[]>;
  createMany(emails: string[]): Promise<{ count: number }>;
  findManyByEmails(emails: string[]): Promise<Contact[]>;
  delete(id: string): Promise<void>;
  deleteMany(ids: string[]): Promise<number>;
  deleteContactsByListId(listId: string): Promise<number>;
  updateStatus(id: string, status: ContactStatus): Promise<Contact>;

  findPaginated(options: FindPaginatedOptions): Promise<ContactWithLists[]>;
  countFiltered(filters: ContactListFilters): Promise<number>;
  create(data: CreateContactData): Promise<Contact>;
  update(id: string, data: UpdateContactData): Promise<Contact>;
  addTagsToMany(ids: string[], tags: string[], userId?: string): Promise<void>;
  /** Usado pelo pipeline de importação: cria por e-mail se não existir, ou atualiza os campos informados se já existir. */
  upsertByEmail(data: CreateContactData): Promise<{ contact: Contact; created: boolean }>;
}
