// index.d.ts

// Make Next.js types optional to avoid dependency issues
declare module 'next/server' {
  export interface NextRequest {
    url: string;
    nextUrl: { pathname: string };
    cookies: {
      get(name: string): { value: string } | undefined;
    };
    headers: {
      get(name: string): string | null;
    };
    user?: any;
    role?: string;
    subrole?: string;
    app?: any;
    statusAccess?: boolean;
  }
  
  export class NextResponse {
    static next(): NextResponse;
    static redirect(url: URL | string): NextResponse;
    cookies: {
      set(name: string, value: string, options?: any): void;
    };
    headers: {
      set(name: string, value: string): void;
    };
  }
}

export interface SSOPayload {
    exp?: number;
    user?: {
        id: string;
        phone: string;
        email: string;
        type: string;
        identity: string;
        status: string;
        lastLogin: string;
        createdAt: string;
        updatedAt: string;
        profile?: {
            id: string;
            userId: string;
            name: string;
            [key: string]: any;
        };
        applications?: {
            id: string;
            applicationKey: string;
            role: string;
            subrole: string;
            [key: string]: any;
        }[];
        application?: {
            id: string;
            applicationKey: string;
            role: string;
            subrole: string;
            [key: string]: any;
        };
    };
    [key: string]: any;
}

export interface LocalStorageUtils {
    setTokens(params: { accessToken: string; refreshToken: string }): boolean;
    getAccessToken(): string | null;
    getRefreshToken(): string | null;
    clearTokens(): void;
    addTokensToHeaders(headers?: Record<string, string>): Record<string, string>;
}

export interface CookieOptions {
    httpOnly: boolean;
    secure: boolean;
    sameSite: string;
    path: string;
    domain?: string;
    maxAge: number;
}

import { NextRequest, NextResponse } from 'next/server';

// Base configuration class
export declare class SSOConfig {
    constructor(options?: any);
    SSO_LOGIN_URL: string;
    APP_KEY: string;
    JWT_SECRET: Uint8Array;
    JWT_REFRESH_SECRET: Uint8Array;
    COOKIE_ACCESS_TOKEN_NAME: string;
    COOKIE_REFRESH_TOKEN_NAME: string;
    SSO_API_URL: string;
    COOKIE_DOMAIN: string;
    NEXT_REDIRECT_URL: string;
    NEXT_PUBLIC_COOKIE_ACCESS_TOKEN_NAME: string;
    NEXT_PUBLIC_COOKIE_REFRESH_TOKEN_NAME: string;
    NEXT_PUBLIC_COOKIE_DOMAIN: string;
    NEXT_PUBLIC_REDIRECT_URL: string;
    LOCAL_STORAGE_ACCESS_TOKEN_KEY: string;
    LOCAL_STORAGE_REFRESH_TOKEN_KEY: string;
}

// Server-side SSO class
export declare class SSOServerSide extends SSOConfig {
    constructor(options?: any);
    
    // Token management methods
    getTokensFromRequest(req: NextRequest): { accessToken: string | null; refreshToken: string | null };
    getTokenFromRequest(req: NextRequest): string | null;
    getRefreshTokenFromRequest(req: NextRequest): string | null;
    setTokensInResponse(params: { response: NextResponse; accessToken: string; refreshToken: string }): void;
    
    // Main middleware method
    withSSOValidation(handler: (req: NextRequest) => Promise<Response | NextResponse> | Response | NextResponse): (req: NextRequest) => Promise<Response | NextResponse>;
    
    // Payload extraction methods
    getPayload(req: NextRequest): Promise<SSOPayload | null>;
    getPayloadFromHeaders(headers: Headers | Record<string, string | string[] | undefined>): Promise<SSOPayload | null>;
    
    // Utility methods
    getCookieOptions(): CookieOptions;
    redirectToSSO(currentUrl?: URL, payload?: any): Promise<NextResponse>;
    
    // User and role methods
    findUserApplication(user: any): { app: any; statusAccess: boolean };
    hasRole(req: NextRequest, requiredRole: string): boolean;
    hasSubrole(req: NextRequest, requiredSubrole: string): boolean;
    requireRole(allowedRoles: string | string[]): (handler: (req: NextRequest) => Promise<Response | NextResponse> | Response | NextResponse) => (req: NextRequest) => Promise<Response | NextResponse>;
}

// Client-side SSO class
export declare class SSOClientSide extends SSOConfig {
    constructor(options?: any);
    
    // Client-side utilities
    getLocalStorageUtils(): LocalStorageUtils;
    getCookieUtils(): any;
    
    // Static methods
    static getLocalStorageUtils(): LocalStorageUtils;
    static getCookieOptions(): CookieOptions;
}

// Token utilities class
export declare class TokenUtils {
    constructor(config: SSOConfig);
    
    getTokensFromRequest(req: NextRequest): { accessToken: string | null; refreshToken: string | null };
    getTokenFromRequest(req: NextRequest): string | null;
    getRefreshTokenFromRequest(req: NextRequest): string | null;
    setTokensInResponse(params: { response: NextResponse; accessToken: string; refreshToken: string }): void;
    getPayload(req: NextRequest): Promise<SSOPayload | null>;
    getPayloadFromHeaders(headers: Headers | Record<string, string | string[] | undefined>): Promise<SSOPayload | null>;
}

// Logger interface
export interface Logger {
    debug(...args: any[]): void;
    info(...args: any[]): void;
    warn(...args: any[]): void;
    error(...args: any[]): void;
    log(level: string, ...args: any[]): void;
}

export declare const logger: Logger;

// Export default instance (SSOServerSide)
declare const ssoMiddleware: SSOServerSide;
export default ssoMiddleware;

// Backward compatibility alias
export declare class SSOMiddleware extends SSOServerSide {}