import { BrowserOAuthClient } from '@atproto/oauth-client-browser'
import type { SessionHooks } from '@atproto/oauth-client-browser'
import { SITE_NAME } from '~/lib/site-config'

// Local dev uses transition:generic because the PDS cannot reach localhost to
// validate a did:web service reference. Production enumerates only the specific
// PDS operations the app needs (aud=* because each user's PDS differs) plus
// wildcard access to the blog API service.
const API_DID = import.meta.env.VITE_API_DID as string
const SCOPE =
  API_DID === 'did:web:localhost'
    ? 'atproto transition:generic'
    : [
        'atproto',
        'repo:site.standard.publication',
        'repo:site.standard.document',
        'repo:site.standard.graph.subscription',
        'repo:pub.lemma.blog.draft?action=create&action=update&action=delete',
        'repo:app.bsky.feed.post?action=create&action=update&action=delete',
        'repo:app.bsky.feed.like',
        'rpc:com.atproto.server.getServiceAuth?aud=*',
        'blob:image/jpeg',
        'blob:image/png',
        'blob:image/gif',
        'blob:image/webp',
      ].join(' ')

export function createOAuthClient(hooks?: SessionHooks): BrowserOAuthClient {
  const { hostname, port, pathname, origin } = window.location
  const isLoopback =
    hostname === 'localhost' ||
    hostname === '127.0.0.1' ||
    hostname === '[::1]'

  if (isLoopback) {
    // Encode the scope into the loopback client_id so the authorization server
    // grants it. The redirect_uri uses 127.0.0.1 because browsers redirect
    // localhost → 127.0.0.1 for loopback URIs.
    const portSuffix = port ? `:${port}` : ''
    const redirectUri = `http://127.0.0.1${portSuffix}${pathname}` as `http://127.0.0.1:${string}`
    const clientId = `http://localhost?scope=${encodeURIComponent(SCOPE)}&redirect_uri=${encodeURIComponent(redirectUri)}`
    return new BrowserOAuthClient({
      handleResolver: 'https://bsky.social',
      clientMetadata: {
        client_id: clientId,
        scope: SCOPE,
        redirect_uris: [redirectUri],
        response_types: ['code'],
        grant_types: ['authorization_code', 'refresh_token'],
        token_endpoint_auth_method: 'none',
        application_type: 'native',
        dpop_bound_access_tokens: true,
      },
      ...hooks,
    })
  }

  return new BrowserOAuthClient({
    handleResolver: 'https://bsky.social',
    clientMetadata: {
      client_id: `${origin}/oauth-client-metadata.json`,
      client_name: SITE_NAME,
      client_uri: origin,
      redirect_uris: [`${origin}/`],
      scope: SCOPE,
      grant_types: ['authorization_code', 'refresh_token'],
      response_types: ['code'],
      token_endpoint_auth_method: 'none',
      application_type: 'web',
      dpop_bound_access_tokens: true,
    },
    ...hooks,
  })
}
