import { betterAuth } from 'better-auth'
import { admin, organization } from 'better-auth/plugins'
import { actor, fabric } from '@pikku/better-auth'
import { pikkuBetterAuth } from '#pikku/pikku-types.gen.js'

export const auth = pikkuBetterAuth(async ({ kysely, secrets, variables }) => {
  const BETTER_AUTH_SECRET = await secrets.getSecret('BETTER_AUTH_SECRET')
  // Genuinely optional: unset simply disables /api/auth/sign-in/actor (scenarios
  // off for this deployment) — the actor plugin refuses all sign-ins without it.
  const SCENARIO_ACTOR_SECRET = await secrets
    .getSecret('SCENARIO_ACTOR_SECRET')
    .catch(() => undefined)
  // Fabric operator admin: the RSA public key the control plane's token is
  // verified against. The Fabric deployer pushes FABRIC_AUTH_PUBLIC_KEY onto
  // every stage; locally it's simply absent, which disables /sign-in/fabric.
  const FABRIC_AUTH_PUBLIC_KEY = await variables.get('FABRIC_AUTH_PUBLIC_KEY')

  return betterAuth({
    secret: BETTER_AUTH_SECRET,
    database: { db: kysely as any, type: 'sqlite' },
    emailAndPassword: { enabled: true },
    session: { cookieCache: { enabled: true } },
    advanced: { database: { generateId: 'uuid' } },
    // organization(): org/team scoping with invitations (db/sqlite/0003).
    // admin(): list/setRole/ban/impersonate users (db/sqlite/0006-admin.sql).
    // actor(): synthetic scenario users (db/sqlite/0005-user-actor.sql).
    // fabric(): Fabric console operator sign-in (db/sqlite/0007-fabric.sql).
    plugins: [
      organization(),
      actor({ secret: SCENARIO_ACTOR_SECRET }),
      // New users must get a role the user.role CHECK
      // ('managing_director','shareholder','angel') accepts. The admin plugin
      // otherwise defaults them to 'user', which the CHECK rejects → every
      // sign-up fails with SQLITE_CONSTRAINT_CHECK. A self-signup user creates
      // a company as its managing director (create-company.function.ts), so
      // that's the right default.
      admin({ defaultRole: 'managing_director' }),
      fabric({ publicKey: FABRIC_AUTH_PUBLIC_KEY }),
    ],
    user: {
      additionalFields: {
        displayName: {
          type: 'string',
          required: false,
          defaultValue: '',
          input: true,
        },
      },
    },
  })
})
