/**
 * Get organization member for authenticated user from Better Auth
 */

import { components } from '../../../_generated/api';
import type { QueryCtx, MutationCtx } from '../../../_generated/server';
import { requireAuthenticatedUser } from '../auth/require_authenticated_user';
import { UnauthorizedError } from '../errors';
import type { AuthenticatedUser, OrganizationMember } from '../types';

/**
 * Get organization member for authenticated user from Better Auth's member table
 */
export async function getOrganizationMember(
  ctx: QueryCtx | MutationCtx,
  organizationId: string,
  user?: AuthenticatedUser,
): Promise<OrganizationMember> {
  const authUser = user || (await requireAuthenticatedUser(ctx));

  // Query Better Auth's member table by userId
  let result = await ctx.runQuery(components.betterAuth.adapter.findMany, {
    model: 'member',
    paginationOpts: {
      cursor: null,
      numItems: 1,
    },
    where: [
      {
        field: 'organizationId',
        value: organizationId,
        operator: 'eq',
      },
      {
        field: 'userId',
        value: authUser.userId,
        operator: 'eq',
      },
    ],
  });

  let member = result?.page?.[0];

  // Fallback to email lookup if no direct match.
  // This handles cases where the JWT userId doesn't match the stored userId, which can occur during:
  // - Account migrations (e.g., user data moved between auth providers)
  // - Account linking (e.g., social login linked to existing email account)
  // - Session/JWT created before user record was updated in Better Auth
  // NOTE: This fallback adds 2 sequential queries when triggered. Monitor frequency in production.
  if (!member && authUser.email) {
    console.warn('[RLS] Falling back to email lookup for organization member', {
      organizationId,
      userId: authUser.userId,
      email: authUser.email,
    });
    const userRes = await ctx.runQuery(components.betterAuth.adapter.findMany, {
      model: 'user',
      paginationOpts: { cursor: null, numItems: 1 },
      where: [{ field: 'email', value: authUser.email, operator: 'eq' }],
    });
    const userByEmail = userRes?.page?.[0];
    if (userByEmail?._id) {
      result = await ctx.runQuery(components.betterAuth.adapter.findMany, {
        model: 'member',
        paginationOpts: { cursor: null, numItems: 1 },
        where: [
          {
            field: 'organizationId',
            value: organizationId,
            operator: 'eq',
          },
          { field: 'userId', value: userByEmail._id, operator: 'eq' },
        ],
      });
      member = result?.page?.[0];
    }
  }

  if (!member) {
    throw new UnauthorizedError(
      `Not a member of organization ${organizationId}`,
    );
  }

  if (member.role === 'disabled') {
    throw new UnauthorizedError(
      `Member account is disabled in organization ${organizationId}`,
    );
  }

  return member;
}
