/**
 * ملف تعريف أنواع المصادقة (Auth Types)
 * المنصة: backend
 */

// ===== تعريف التعدادات (Enums) =====
export enum UserRole {
  ADMIN = 'ADMIN'
}

// ===== تعريف الأنواع (Interfaces) =====
export interface AuthContext {
  userId: string
  account: string
  email: string
  role: UserRole
}

/**
 * 401 خطأ غير مصرح به (Unauthorized)
 */
export class UnauthorizedError extends Error {
  readonly statusCode = 401
  constructor(message = 'يرجى تسجيل الدخول أولاً') {
    super(message)
    this.name = 'UnauthorizedError'
    Object.setPrototypeOf(this, UnauthorizedError.prototype)
  }
}

/**
 * 403 خطأ الوصول ممنوع (Forbidden)
 */
export class ForbiddenError extends Error {
  readonly statusCode = 403
  constructor(message = 'عذراً، ليس لديك الصلاحيات الكافية لتنفيذ هذا الإجراء') {
    super(message)
    this.name = 'ForbiddenError'
    Object.setPrototypeOf(this, ForbiddenError.prototype)
  }
}

// ===== تواقيع دوال المصادقة =====

/**
 * غلاف يتطلب تسجيل الدخول إجبارياً
 */
export declare function requireAuth(): <TArgs extends any[], TReturn>(
  fn: (...args: TArgs) => Promise<TReturn>
) => (...args: TArgs) => Promise<TReturn>;

/**
 * غلاف يتطلب دوراً وظيفياً محدداً
 * @param roles يدعم قيمة واحدة، مصفوفة، أو نصوص مثل UserRole.ADMIN
 */
export declare function requireRole(
  roles: UserRole | UserRole[] | string | string[]
): <TArgs extends any[], TReturn>(
  fn: (...args: TArgs) => Promise<TReturn>
) => (...args: TArgs) => Promise<TReturn>;

/**
 * الحصول على سياق المصادقة للطلب الحالي
 */
export declare function getAuthContext(): AuthContext

/**
 * الحصول على معرف المستخدم الحالي
 */
export declare function getUserId(): string

/**
 * الحصول على دور المستخدم الحالي
 */
export declare function getRole(): UserRole

/**
 * إصدار رمز JWT (Sign Token)
 * @param userId معرف المستخدم
 * @param role دور المستخدم
 * @param expiresIn مدة الصلاحية، الافتراضي 7 أيام
 */
export declare function signToken(
  userId: string,
  role: string,
  expiresIn?: string
): Promise<string>

/**
 * تشفير كلمة المرور (Hashing)
 * @param password كلمة المرور النصية
 * @returns كلمة المرور مشفرة بخوارزمية SHA256
 */
export declare function hashPassword(password: string): string

/**
 * محاولة الحصول على سياق المصادقة (بدون رمي خطأ)
 * @returns يعيد AuthContext إذا كان مسجلاً، أو null خلاف ذلك
 */
export declare function tryGetAuthContext(): AuthContext | null

/**
 * غلاف الاستجابة القياسي
 * يعالج try-catch تلقائياً
 * 
 * @example
 * // مثال: حذف طلب توصيل (للمسؤول فقط)
 * export const deleteOrder = requireRole(UserRole.ADMIN)(
 *   withResult(async (id: string) => {
 *     await prisma.delivery_order.delete({ where: { id } })
 *   })
 * )
 *
 * @example
 * // مثال: تحديث حالة الطلب مع ربط سجل الحالة
 * // ملاحظة: عند استخدام العلاقات (Relation)، يجب استخدام `connect` بدلاً من المعرف المباشر
 * export const updateOrderStatus = requireAuth()(
 *   withResult(async (input: { orderId: string, status: delivery_order_status }) => {
 *     const userId = getUserId();
 *     const order = await prisma.delivery_order.update({
 *       where: { id: input.orderId },
 *       data: {
 *         status: input.status,
 *         statusHistories: {
 *           create: {
 *             toStatus: input.status,
 *             changedBy: { connect: { id: userId } }
 *           }
 *         }
 *       }
 *     })
 *     return order;
 *   })
 * )
 */
export declare function withResult<TArgs extends any[], TData>(
  fn: (...args: TArgs) => Promise<TData>
): (
  ...args: TArgs
) => Promise<TData>