/**
 * Shared shapes of the auth layer (docs/backend-plan.md §3.4). Two sides meet through them:
 *  - the BUNDLE side (`auth` global, ./global.ts) — what `*.server.ts` code calls;
 *  - the HOST side (./host.ts) — sessions, email codes and OAuth binding, run by the runner with the
 *    project's db handle and the platform's secrets. Installed on `globalThis.__lecodesAuth`.
 */

import type { RequestContext } from "../context"
import type { AuthProvider } from "./models"

/** The built-in user row — what `auth.user` is typed with (custom fields exist at runtime; select them via `db.user`). */
export type AuthUser = {
  id: number
  email: string | null
  name: string | null
  avatar: string | null
  role: string
  createdAt: number
}

/** Per-request auth state, resolved by the host before the endpoint runs (`RequestContext.auth`). */
export type AuthState = {
  sessionId: number
  userId: number | null
  user: AuthUser | null
  /** A token to hand back to the client in this response (a new guest session, or a rotation). */
  issuedToken?: string
}

/** What an OAuth provider hands the runner after a successful web sign-in. */
export type OAuthProfile = { sub: string, email?: string | null, emailVerified?: boolean, name?: string | null, avatar?: string | null }
/** A credential a NATIVE provider SDK produced in the app (client plugin `OAuth.signIn`): an access token
 *  (Yandex, VK ID) or an OpenID identity token (Google, Apple). Verified server-side, never trusted as-is. */
export type OAuthCredential = { accessToken?: string, idToken?: string, name?: string | null, email?: string | null }

/** Host operations the bundle's `auth` global forwards to (all request-scoped through `ctx`). */
export type AuthOps = {
  email: {
    sendCode(ctx: RequestContext, email: string): Promise<void>
    verify(ctx: RequestContext, email: string, code: string): Promise<AuthUser>
  }
  oauth: {
    url(ctx: RequestContext, provider: Exclude<AuthProvider, "email">): Promise<string>
    signIn(ctx: RequestContext, provider: Exclude<AuthProvider, "email">, credential: OAuthCredential): Promise<AuthUser>
  }
  signIn(ctx: RequestContext, userId: number): Promise<AuthUser>
  signOut(ctx: RequestContext): Promise<void>
  /** `db.session` filtered to the current user's sessions (or just this device's, when signed out). */
  sessions(ctx: RequestContext): any
}
