import { Request, Response } from 'express';

type GenerateStaticParams = () => Array<Record<string, string>> | Promise<Array<Record<string, string>>>;
interface ServerContext {
    req: Request;
    res: Response;
    params: Record<string, string>;
    pathname: string;
    locals: Record<string, any>;
}
interface WssActions {
    /**
     * Emit to current socket only (reply)
     */
    reply(event: string, payload?: any): void;
    /**
     * Emit an event to all clients in the namespace
     */
    emit: (event: string, ...args: any[]) => void;
    /**
     * Emit to everyone except current socket
     */
    broadcast(event: string, payload?: any, opts?: {
        excludeSelf?: boolean;
    }): void;
    /**
     * Join a room
     */
    join(room: string): Promise<void>;
    /**
     * Leave a room
     */
    leave(room: string): Promise<void>;
    /**
     * Emit to a specific room
     */
    toRoom(room: string): {
        emit(event: string, payload?: any): void;
    };
    /**
     * Emit to a specific user (by userId)
     * Uses presence mapping to find user's sockets
     */
    toUser(userId: string): {
        emit(event: string, payload?: any): void;
    };
    /**
     * Emit error event (reserved event: __loly:error)
     */
    error(code: string, message: string, details?: any): void;
    /**
     * Emit an event to a specific socket by Socket.IO socket ID
     * @deprecated Use toUser() for user targeting
     */
    emitTo?: (socketId: string, event: string, ...args: any[]) => void;
    /**
     * Emit an event to a specific client by custom clientId
     * @deprecated Use toUser() for user targeting
     */
    emitToClient?: (clientId: string, event: string, ...args: any[]) => void;
}
/**
 * Route middleware function type.
 * Middlewares run before getServerSideProps and can modify ctx.locals, set headers, redirect, etc.
 *
 * @param ctx - Server context with optional theme
 * @param next - Function to call the next middleware in the chain (must be awaited if used)
 * @returns Promise<void> | void
 *
 * @example
 * // Simple middleware that adds data to ctx.locals
 * export const beforeServerData: RouteMiddleware[] = [
 *   async (ctx, next) => {
 *     ctx.locals.user = await getUser(ctx.req);
 *     await next();
 *   }
 * ];
 *
 * @example
 * // Middleware that redirects
 * export const beforeServerData: RouteMiddleware[] = [
 *   async (ctx, next) => {
 *     if (!ctx.locals.user) {
 *       ctx.res.redirect('/login');
 *       return; // Don't call next() if redirecting
 *     }
 *     await next();
 *   }
 * ];
 */
type RouteMiddleware = (ctx: ServerContext & {
    theme?: string;
}, next: () => Promise<void>) => Promise<void> | void;
/**
 * Result returned by a server loader (getServerSideProps).
 * @template TProps - Type of props that will be passed to the component (defaults to Record<string, any>)
 */
interface LoaderResult<TProps extends Record<string, any> = Record<string, any>> {
    pathname?: string;
    props?: TProps;
    redirect?: {
        destination: string;
        permanent?: boolean;
    };
    notFound?: boolean;
    metadata?: PageMetadata | null;
    className?: string;
    theme?: string;
}
/**
 * Server loader function type (getServerSideProps).
 * This function is exported from server.hook.ts files.
 *
 * @template TProps - Type of props that will be returned (defaults to Record<string, any>)
 *
 * @example
 * // Typed loader
 * export const getServerSideProps: ServerLoader<{ user: User; posts: Post[] }> = async (ctx) => ({
 *   props: { user: await getUser(), posts: await getPosts() }
 * });
 *
 * @example
 * // Untyped loader (backward compatible)
 * export const getServerSideProps: ServerLoader = async (ctx) => ({
 *   props: { any: 'data' }
 * });
 */
type ServerLoader<TProps extends Record<string, any> = Record<string, any>> = (ctx: ServerContext) => Promise<LoaderResult<TProps>>;
/**
 * Comprehensive page metadata for SEO and social sharing.
 * Supports standard HTML meta tags, Open Graph, Twitter Cards, and more.
 */
interface PageMetadata {
    /** Page title (sets <title> tag) */
    title?: string;
    /** Page description (sets <meta name="description">) */
    description?: string;
    /** Language code (sets <html lang="...">) */
    lang?: string;
    /** Canonical URL (sets <link rel="canonical">) */
    canonical?: string;
    /** Robots directive (sets <meta name="robots">) */
    robots?: string;
    /** Theme color (sets <meta name="theme-color">) */
    themeColor?: string;
    /** Viewport configuration (sets <meta name="viewport">) */
    viewport?: string;
    /** Open Graph metadata for social sharing */
    openGraph?: {
        title?: string;
        description?: string;
        type?: string;
        url?: string;
        image?: string | {
            url: string;
            width?: number;
            height?: number;
            alt?: string;
        };
        siteName?: string;
        locale?: string;
    };
    /** Twitter Card metadata */
    twitter?: {
        card?: "summary" | "summary_large_image" | "app" | "player";
        title?: string;
        description?: string;
        image?: string;
        imageAlt?: string;
        site?: string;
        creator?: string;
    };
    /** Additional custom meta tags */
    metaTags?: {
        name?: string;
        property?: string;
        httpEquiv?: string;
        content: string;
    }[];
    /** Additional link tags (e.g., preconnect, dns-prefetch) */
    links?: {
        rel: string;
        href: string;
        as?: string;
        crossorigin?: string;
        type?: string;
    }[];
}
type MetadataLoader = (ctx: ServerContext) => PageMetadata | Promise<PageMetadata>;
interface ApiContext {
    req: Request;
    res: Response;
    Response: (body?: any, status?: number) => Response<any, Record<string, any>>;
    NotFound: (body?: any) => Response<any, Record<string, any>>;
    params: Record<string, string>;
    pathname: string;
    locals: Record<string, any>;
}
/**
 * API middleware function type.
 * Middlewares run before the API handler and can modify ctx.locals, set headers, etc.
 *
 * @param ctx - API context
 * @param next - Function to call the next middleware in the chain (must be awaited if used)
 * @returns Promise<void> | void
 *
 * @example
 * // Authentication middleware
 * export const middlewares: ApiMiddleware[] = [
 *   async (ctx, next) => {
 *     const token = ctx.req.headers.authorization;
 *     if (!token) {
 *       return ctx.Response({ error: 'Unauthorized' }, 401);
 *     }
 *     ctx.locals.user = await verifyToken(token);
 *     await next();
 *   }
 * ];
 */
type ApiMiddleware = (ctx: ApiContext, next: () => Promise<void>) => void | Promise<void>;

export type { ApiMiddleware as A, GenerateStaticParams as G, LoaderResult as L, MetadataLoader as M, PageMetadata as P, RouteMiddleware as R, ServerContext as S, WssActions as W, ApiContext as a, ServerLoader as b };
