import type { MiddlewareHandler } from 'hono'
import { createEntitlements, type EntitlementDatabase } from '@platform-modules/entitlements'

import { getDb, type DbEnv } from '../db.js'
import { fail } from '../http.js'
import type { PressZoneSchema } from '../schema.js'

export interface AccessVariables {
  account: string
  capabilities: string[]
}

type AccessEnv = {
  Bindings: DbEnv
  Variables: AccessVariables
}

/**
 * Composes the two independent access axes from spec §5: account
 * entitlement (`entitlementKey`, e.g. `plugin:translate`) and member/API-key
 * action capability (`permission`, e.g. `translate.write`). These MUST stay
 * distinct — collapsing them to one string means the capability check
 * silently tests for the entitlement string, which real `resolveCapabilities`
 * output (role/permission tokens) never contains.
 */
export function requirePluginAccess(
  entitlementKey: string,
  permission: string,
): MiddlewareHandler<AccessEnv> {
  return async (context, next) => {
    const account = context.get('account')
    const entitlements = createEntitlements({
      db: getDb(context.env) as EntitlementDatabase<PressZoneSchema>,
    })

    if (!(await entitlements.can(account, entitlementKey))) {
      return fail('PLUGIN_NOT_ENTITLED', 'Plugin is not entitled', 402)
    }

    const capabilities = context.get('capabilities')

    if (!capabilities.includes(permission)) {
      return fail('FORBIDDEN', 'Forbidden', 403)
    }

    await next()
  }
}
