import { prisma } from "../constants";
import { CwMemberController } from "../controllers/CwMemberController";
import GenericError from "../Errors/GenericError";

/**
 * CW Members Manager
 *
 * Thin persistence layer wrapping Prisma calls for the CwMember model.
 * Returns CwMemberController instances as domain objects.
 */
export const cwMembers = {
  /**
   * Fetch a single CW member by internal ID, CW member ID, or identifier.
   */
  fetch: async (idOrIdentifier: string): Promise<CwMemberController> => {
    const isNumeric = /^\d+$/.test(idOrIdentifier);

    const record = await prisma.cwMember.findFirst({
      where: isNumeric
        ? { cwMemberId: Number(idOrIdentifier) }
        : {
            OR: [{ id: idOrIdentifier }, { identifier: idOrIdentifier }],
          },
    });

    if (!record) {
      throw new GenericError({
        status: 404,
        name: "CwMemberNotFound",
        message: `CW Member "${idOrIdentifier}" not found`,
      });
    }

    return new CwMemberController(record);
  },

  /**
   * Fetch all CW members with optional filtering.
   */
  fetchAll: async (opts?: {
    includeInactive?: boolean;
  }): Promise<CwMemberController[]> => {
    const where = opts?.includeInactive ? {} : { inactiveFlag: false };

    const records = await prisma.cwMember.findMany({
      where,
      orderBy: { lastName: "asc" },
    });

    return records.map((r) => new CwMemberController(r));
  },

  /**
   * Count CW members.
   */
  count: async (opts?: { includeInactive?: boolean }): Promise<number> => {
    const where = opts?.includeInactive ? {} : { inactiveFlag: false };
    return prisma.cwMember.count({ where });
  },

  /**
   * Update the API key for a CW member.
   */
  updateApiKey: async (
    idOrIdentifier: string,
    apiKey: string | null,
  ): Promise<CwMemberController> => {
    const member = await cwMembers.fetch(idOrIdentifier);

    const updated = await prisma.cwMember.update({
      where: { id: member.id },
      data: { apiKey },
    });

    return new CwMemberController(updated);
  },
};
