// packages/functions/src/firebase/crud/delete.ts

/**
 * @fileoverview Generic function to delete an entity.
 * @description Provides a reusable implementation for deleting documents in Firestore with reference checking.
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

import { getFirebaseAdminFirestore } from '@donotdev/firebase/server';
import * as v from 'valibot';

import {
  assertAdmin,
  DoNotDevError,
  findReferences,
} from '../../shared/utils.js';
import { createBaseFunction } from '../baseFunction.js';
import { CRUD_CONFIG } from '../config/constants.js';

import type { CallableRequest } from 'firebase-functions/v2/https';

/**
 * Generic business logic for deleting entities
 * Base function handles: validation, auth, rate limiting, monitoring
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
function deleteEntityLogicFactory(collection: string) {
  return async function deleteEntityLogic(
    data: { id: string },
    context: { uid: string; request: CallableRequest<any> }
  ) {
    const { id } = data;

    // Ensure the user is an admin
    await assertAdmin(context.uid);

    // Check for references to this document
    const references = await findReferences(collection, id);

    // Prevent deletion if references exist
    if (references.length > 0) {
      throw new DoNotDevError(
        'Cannot delete: item is referenced by other entities',
        'permission-denied',
        { details: { references } }
      );
    }

    // Delete the document
    const db = getFirebaseAdminFirestore();
    await db.collection(collection).doc(id).delete();

    return { success: true };
  };
}

/**
 * Generic function to delete entities from any Firestore collection
 * @param collection - The Firestore collection name
 * @param customSchema - Optional custom request schema
 * @returns Firebase callable function
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export const deleteEntity = (
  collection: string,
  customSchema?: v.BaseSchema<unknown, any, v.BaseIssue<unknown>>
) => {
  const requestSchema =
    customSchema ||
    v.object({
      id: v.pipe(v.string(), v.minLength(1)),
    });

  return createBaseFunction(
    CRUD_CONFIG,
    requestSchema,
    'delete_entity',
    deleteEntityLogicFactory(collection)
  );
};
