import { DataAccessError } from "@isa/common/data-access";
import { Receipt, ReceiptItem } from "../../models";
import { ProductCategory } from "../../questions";

/**
 * Enum-like object defining possible reasons for return process creation failures.
 * Used to provide consistent and type-safe error categorization.
 */
export const CreateReturnProcessErrorReason = {
  NO_RETURNABLE_ITEMS: "NO_RETURNABLE_ITEMS",
  MISMATCH_RETURNABLE_ITEMS: "MISMATCH_RETURNABLE_ITEMS",
} as const;

/**
 * Type representing valid reasons for return process creation failures.
 * Derived from CreateReturnProcessErrorReason keys for type safety.
 */
export type CreateReturnProcessErrorReason =
  (typeof CreateReturnProcessErrorReason)[keyof typeof CreateReturnProcessErrorReason];

/**
 * Maps error reasons to their corresponding user-friendly messages.
 * Used to provide consistent error messaging across the application.
 *
 * @example
 * To access a message:
 * ```typescript
 * const message = CreateReturnProcessErrorMessages[CreateReturnProcessErrorReason.NO_RETURNABLE_ITEMS];
 * ```
 */
export const CreateReturnProcessErrorMessages: Record<
  CreateReturnProcessErrorReason,
  string
> = {
  [CreateReturnProcessErrorReason.NO_RETURNABLE_ITEMS]:
    "No returnable items found.",
  [CreateReturnProcessErrorReason.MISMATCH_RETURNABLE_ITEMS]:
    "Mismatch in the number of returnable items.",
};

/**
 * Error thrown when creating a return process fails.
 * Extends DataAccessError with the specific code 'CREATE_RETURN_PROCESS' and includes
 * additional context about the failure through the reason and params properties.
 *
 * The error includes:
 * - An error reason indicating why the process failed (e.g., no returnable items)
 * - Context data including process ID, receipt ID, and involved items
 * - A human-readable message from CreateReturnProcessErrorMessages
 *
 * @see CreateReturnProcessErrorReason for possible error reasons
 * @see CreateReturnProcessErrorMessages for corresponding messages
 *
 * @example
 * ```typescript
 * throw new CreateReturnProcessError(
 *   CreateReturnProcessErrorReason.NO_RETURNABLE_ITEMS,
 *   {
 *     processId: 123,
 *     receipt: { id: 456, printedDate: '2023-10-01' },
 *     items: []
 *   }
 * );
 *
 * // Handling the error
 * try {
 *   // ... create return process
 * } catch (error) {
 *   if (error instanceof CreateReturnProcessError) {
 *     if (error.reason === CreateReturnProcessErrorReason.NO_RETURNABLE_ITEMS) {
 *       // Handle no returnable items case
 *     }
 *   }
 * }
 * ```
 */
export class CreateReturnProcessError extends DataAccessError<"CREATE_RETURN_PROCESS"> {
  constructor(
    public readonly reason: CreateReturnProcessErrorReason,
    public readonly params: {
      processId: number;
      returns: {
        receipt: Receipt;
        items: {
          receiptItem: ReceiptItem;
          quantity: number;
          category: ProductCategory;
        }[];
      }[];
    },
  ) {
    super("CREATE_RETURN_PROCESS", CreateReturnProcessErrorMessages[reason]);
  }
}
