/**
 * Per-page moderator access (Nash, 2026-09-23).
 *
 * "Any of the moderator pages is not available by default to anyone. The
 * main admin can invite a specific user with his email to a specific page,
 * and he has access to that page. He cannot invite anyone else, only the
 * admin can… Maybe I want a guy from marketing to deal with the leads, one
 * with the pilot cars, one with the brokers. Two guys on the AI feedback.
 * And I can do it from the page itself — add a moderator, put the email,
 * send the invite, it gives him access."
 *
 * A SURFACE is one moderator page plus the API routes behind it. Access is
 * granted per surface, per person, by the platform admin only. Pure rules;
 * the I/O is in src/lib/data/moderator-access.ts.
 */

export type SurfaceKey =
  | 'moderation'
  | 'email_templates'
  | 'email_health'
  | 'broker_leads'
  | 'carrier_leads'
  | 'pilot_invitations'
  | 'company_review'
  | 'intake_security'
  | 'operations'
  | 'users'
  | 'purchases'

export interface Surface {
  key: SurfaceKey
  label: string
  /** What a moderator on this page can do — shown in the invitation and on the access card. */
  description: string
  path: string
  /** API route prefixes this surface covers. */
  apiPrefixes: string[]
  /**
   * Never delegated. User management hands out roles and passwords, so
   * granting it would be granting the platform itself.
   */
  adminOnly?: boolean
}

export const SURFACES: Surface[] = [
  { key: 'moderation', label: 'Moderator Dashboard', description: 'Support tickets, developer issues, AI feedback and moderation settings.', path: '/admin/moderation', apiPrefixes: ['/api/admin/moderation'] },
  { key: 'broker_leads', label: 'Freight Broker Leads', description: 'Freight broker leads, segments, invitation campaigns and their analytics.', path: '/admin/broker-leads', apiPrefixes: ['/api/admin/broker-leads'] },
  { key: 'carrier_leads', label: 'Carrier Leads', description: 'Dispatchers and drivers without a carrier yet: leads, segments, invitation campaigns and their analytics.', path: '/admin/carrier-leads', apiPrefixes: ['/api/admin/carrier-leads'] },
  { key: 'pilot_invitations', label: 'Pilot Invitation Manager', description: 'Pilot car leads, invitations, campaigns and the pilot network.', path: '/admin/pilot-invitations', apiPrefixes: ['/api/admin/pilot-invitations'] },
  { key: 'email_templates', label: 'Email Templates', description: 'Wording, subjects, versions and activation of every platform email.', path: '/admin/email-templates', apiPrefixes: ['/api/admin/email-templates'] },
  { key: 'email_health', label: 'Email Health', description: 'Delivery, bounces, complaints and suppression across both sending streams.', path: '/admin/email-health', apiPrefixes: [] },
  { key: 'company_review', label: 'Company Review', description: 'Company verification requests and manual review.', path: '/admin/company-review', apiPrefixes: ['/api/admin/company-review'] },
  { key: 'intake_security', label: 'Intake Security', description: 'Public intake protection, blocked senders and submission review.', path: '/admin/intake-security', apiPrefixes: ['/api/admin/intake-security'] },
  { key: 'operations', label: 'Operations Log', description: 'Recent activity and outcomes across trips, permits, email, access, intake and integrations.', path: '/admin/operations', apiPrefixes: [], adminOnly: true },
  { key: 'users', label: 'Users', description: 'Accounts, roles, password resets and multi-factor authentication.', path: '/admin/users', apiPrefixes: ['/api/admin/users'], adminOnly: true },
  { key: 'purchases', label: 'Purchases', description: 'Route purchases, Synchron payment references, fulfillment and reconciliation.', path: '/admin/purchases', apiPrefixes: ['/api/admin/purchases'], adminOnly: true },
]

export const SURFACE_KEYS = SURFACES.map((s) => s.key)

export function surfaceByKey(key: string | null | undefined): Surface | null {
  return SURFACES.find((s) => s.key === key) ?? null
}

/** Surfaces the admin may hand out. `users` is deliberately not one of them. */
export function delegatableSurfaces(): Surface[] {
  return SURFACES.filter((s) => !s.adminOnly)
}

export function isDelegatable(key: string): boolean {
  return delegatableSurfaces().some((s) => s.key === key)
}

export interface AccessUser {
  role: string
  /** Surface keys granted to this person and not revoked. */
  surfaces?: readonly string[] | null
}

/** The platform admin sees everything; anyone else needs a grant for that exact surface. */
export function canAccessSurface(user: AccessUser | null | undefined, key: SurfaceKey | string): boolean {
  if (!user) return false
  if (user.role === 'admin') return true
  const surface = surfaceByKey(key)
  if (!surface || surface.adminOnly) return false
  return (user.surfaces ?? []).includes(key)
}

/** Every surface this person may open, in menu order. */
export function surfacesFor(user: AccessUser | null | undefined): Surface[] {
  if (!user) return []
  return SURFACES.filter((s) => canAccessSurface(user, s.key))
}

/** True when the person can open at least one moderator page — drives the menu section. */
export function hasAnySurface(user: AccessUser | null | undefined): boolean {
  return surfacesFor(user).length > 0
}

/** Only the platform admin grants or revokes access. A moderator can never invite anyone. */
export function canManageAccess(user: AccessUser | null | undefined): boolean {
  return user?.role === 'admin'
}

/** Which surface an API path belongs to, for the route guard and the audit trail. */
export function surfaceForPath(path: string): Surface | null {
  return SURFACES.find((s) => s.apiPrefixes.some((p) => path === p || path.startsWith(`${p}/`))) ?? null
}

export type GrantState = 'invited' | 'active' | 'revoked'

export function grantState(g: { accepted_at?: string | null; revoked_at?: string | null }): GrantState {
  if (g.revoked_at) return 'revoked'
  return g.accepted_at ? 'active' : 'invited'
}

export const GRANT_STATE_LABELS: Record<GrantState, string> = {
  invited: 'Invited — has not signed in yet',
  active: 'Active',
  revoked: 'Revoked',
}

/** An email is required and must not be a demo or placeholder address. */
export function validateModeratorEmail(raw: string): { ok: true; email: string } | { ok: false; error: string } {
  const email = raw.trim().toLowerCase()
  if (!/^[^@\s]+@[^@\s]+\.[a-z]{2,}$/i.test(email)) return { ok: false, error: 'Enter a valid email address.' }
  if (/@(users\.local|[a-z0-9.-]+\.(test|example|invalid))$/i.test(email)) return { ok: false, error: 'Enter a real email address the person can receive mail at.' }
  return { ok: true, email }
}
