import { betterAuth } from 'better-auth';
import { bearer } from 'better-auth/plugins/bearer';
import { Pool } from 'pg';
import { Kysely, PostgresDialect } from 'kysely';
import type { FastifyBaseLogger } from 'fastify';

export interface BetterAuthConfig {
  databaseUrl: string;
  pool?: Pool;
  secret: string;
  baseUrl: string;
  trustedOrigins: string[];
  logger: FastifyBaseLogger;
}

/**
 * Create Better Auth instance with PostgreSQL adapter and passkey support
 */
export async function createBetterAuth(config: BetterAuthConfig) {
  try {
    config.logger.debug({
      databaseUrl: config.databaseUrl.replace(/:[^:@]+@/, ':***@'),
      baseUrl: config.baseUrl,
    }, 'Creating Better Auth instance');

    // Use existing pool if provided, otherwise create new one
    const pool = config.pool || new Pool({
      connectionString: config.databaseUrl,
    });

    config.logger.debug('PostgreSQL pool created');

    // Test database connection first
    try {
      config.logger.debug('Testing database connection...');
      const testClient = await pool.connect();
      await testClient.query('SELECT 1');
      testClient.release();
      config.logger.debug('Database connection test successful');
    } catch (dbError: any) {
      config.logger.error({
        error: dbError,
        message: dbError.message,
        stack: dbError.stack,
      }, 'Database connection test failed');
      throw new Error(`Database connection failed: ${dbError.message}`);
    }

    // Create Kysely instance for Better Auth
    config.logger.debug('Creating Kysely database instance...');
    const db = new Kysely({
      dialect: new PostgresDialect({ pool }),
    });
    config.logger.debug('Kysely instance created');

    // Better Auth v1.5.3 postgres configuration
    const auth = betterAuth({
      database: {
        db,
        type: 'postgres',
      },

      // Secret for JWT signing
      secret: config.secret,

      // Base URL for callbacks and redirects
      baseURL: config.baseUrl,

      // Trusted origins for CORS
      trustedOrigins: config.trustedOrigins,

      // Email/password authentication
      emailAndPassword: {
        enabled: true,
        requireEmailVerification: false, // Set to true in production
        sendResetPassword: async ({ user, url }) => {
          // TODO: Implement email sending
          config.logger.info({ userId: user.id, resetUrl: url }, 'Password reset requested');
        },
      },

      // Session configuration
      session: {
        expiresIn: 60 * 60 * 24 * 7, // 7 days
        updateAge: 60 * 60 * 24, // Update session every 24 hours
        cookieCache: {
          enabled: true,
          maxAge: 5 * 60, // 5 minutes
        },
      },

      // Plugins
      plugins: [
        bearer(), // Enable Bearer token authentication for API/WebSocket
      ],

    });

    config.logger.debug('Better Auth instance created');
    return auth;
  } catch (error: any) {
    config.logger.error({
      error,
      message: error.message,
      stack: error.stack,
      cause: error.cause,
    }, 'Error creating Better Auth instance');
    throw error;
  }
}

export type BetterAuthInstance = Awaited<ReturnType<typeof createBetterAuth>>;
