/**
 * 鉴权类型定义文件
 * 平台: app
 */

import { delivery_order_status } from "../prisma-generated/client"

// ===== 枚举定义 =====
export enum UserRole {
  ADMIN = 'ADMIN'
}

// ===== 类型定义 =====
export interface AuthContext {
  userId: string
  username: 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 أو String
 */
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

/**
 * 获取当前登录用户 ID
 */
export declare function getUserId(): string

/**
 * 获取当前登录用户角色
 */
export declare function getRole(): UserRole

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

/**
 * 密码哈希
 * @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 updateOrderStatus = requireRole(UserRole.ADMIN)(
 *   withResult(async (orderId: string, newStatus: delivery_order_status) => {
 *     const auth = getAuthContext();
 *     return await prisma.delivery_order.update({
 *       where: { id: orderId },
 *       data: { 
 *         status: newStatus,
 *         statusHistories: {
 *           create: {
 *             toStatus: newStatus,
 *             changedBy: { connect: { id: auth.userId } }
 *           }
 *         }
 *       }
 *     })
 *   })
 * )
 *
 * @example
 * // مثال: إنشاء طلب توصيل جديد
 * export const createDeliveryOrder = requireAuth()(
 *   withResult(async (data: { orderNo: string, customerName: string, customerPhone: string }) => {
 *     return await prisma.delivery_order.create({
 *       data: {
 *         orderNo: data.orderNo,
 *         customerName: data.customerName,
 *         customerPhone: data.customerPhone,
 *         governorateName: "بغداد", // مثال افتراضي
 *         areaName: "الكرادة",
 *         nearestLandmark: "ساحة كهرمانة",
 *         driverName: "قيد التعيين",
 *         orderType: "Standard"
 *       }
 *     })
 *   })
 * )
 */
export declare function withResult<TArgs extends any[], TData>(
  fn: (...args: TArgs) => Promise<TData>
): (
  ...args: TArgs
) => Promise<TData>