// ── Auth provider contract (base) ──────────────────────────────────────────
//
// The abstract interface every auth provider implements. Concrete providers:
//   - local  → username/password (LocalProvider, unchanged live flow)
//   - google, discord, generic OIDC → OAuth2Provider subclasses
//
// A provider config (a row from auth_providers, or a built-in default) looks like:
//   { id, kind, name, enabled, clientId, clientSecret,
//     authorizeUrl, tokenUrl, userinfoUrl, scopes, priority }
//
// Interface (per the Part 3 spec). OAuth providers implement the SSO-flow methods;
// LocalProvider implements authenticate(). Anything not applicable stays a throw.

class BaseProvider {
  constructor(config = {}) {
    this.config = config
    this.id = config.id || config.kind || 'base'
    this.name = config.name || this.id
    this.kind = config.kind || 'base'
    this.type = this.kind // legacy alias
  }

  isEnabled() {
    return Boolean(this.config.enabled)
  }

  // Direct-credential auth (local providers). Resolve to an internal user or null.
  // eslint-disable-next-line no-unused-vars
  async authenticate(credentials) {
    throw new Error(`authenticate() not implemented for provider '${this.id}'`)
  }

  // Begin an SSO redirect flow: the provider's authorization URL.
  // eslint-disable-next-line no-unused-vars
  getAuthorizationUrl(state, options) {
    throw new Error(`getAuthorizationUrl() not implemented for provider '${this.id}'`)
  }

  // Complete an SSO redirect flow: exchange the callback code for a normalized
  // user profile ({ subject, email, name }).
  // eslint-disable-next-line no-unused-vars
  async handleCallback(params) {
    throw new Error(`handleCallback() not implemented for provider '${this.id}'`)
  }

  // Fetch the raw external profile using an access token.
  // eslint-disable-next-line no-unused-vars
  async getUserProfile(accessToken) {
    throw new Error(`getUserProfile() not implemented for provider '${this.id}'`)
  }

  // Normalize a raw external profile to { subject, email, name }.
  // eslint-disable-next-line no-unused-vars
  mapUser(profile) {
    throw new Error(`mapUser() not implemented for provider '${this.id}'`)
  }

  // Link an external identity to an internal user (shared by OAuth2Provider).
  // eslint-disable-next-line no-unused-vars
  async linkAccount(user, profile) {
    throw new Error(`linkAccount() not implemented for provider '${this.id}'`)
  }
}

module.exports = BaseProvider
