import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { admin } from 'better-auth/plugins';
import { genericOAuth, type GenericOAuthConfig } from 'better-auth/plugins/generic-oauth';
import type { Db } from '@mosaicstack/db';
import { buildGenericOidcProviderConfigs } from './sso.js';

export interface AuthConfig {
  db: Db;
  baseURL?: string;
  secret?: string;
}

export function buildOAuthProviders(): GenericOAuthConfig[] {
  return buildGenericOidcProviderConfigs() as GenericOAuthConfig[];
}

export function createAuth(config: AuthConfig) {
  const { db, baseURL, secret } = config;
  const oidcConfigs = buildOAuthProviders();
  const plugins =
    oidcConfigs.length > 0
      ? [
          genericOAuth({
            config: oidcConfigs,
          }),
        ]
      : undefined;

  const corsOrigin = process.env['GATEWAY_CORS_ORIGIN'] ?? 'http://localhost:3000';
  const trustedOrigins = corsOrigin.split(',').map((o) => o.trim());

  return betterAuth({
    database: drizzleAdapter(db, {
      provider: 'pg',
      usePlural: true,
    }),
    baseURL: baseURL ?? process.env['BETTER_AUTH_URL'] ?? 'http://localhost:14242',
    secret: secret ?? process.env['BETTER_AUTH_SECRET'],
    basePath: '/api/auth',
    trustedOrigins,
    emailAndPassword: {
      enabled: true,
    },
    user: {
      additionalFields: {
        role: {
          type: 'string',
          required: false,
          defaultValue: 'member',
          input: false,
        },
      },
    },
    session: {
      expiresIn: 60 * 60 * 24 * 7, // 7 days
      updateAge: 60 * 60 * 24, // refresh daily
    },
    plugins: [...(plugins ?? []), admin({ defaultRole: 'member', adminRoles: ['admin'] })],
  });
}

export type Auth = ReturnType<typeof createAuth>;
