import { ROLE_SCOPES } from '@/shared/constants/roles';

/**
 * Per-tenant content helpers (FRAME / quizzes / documents). Each tenant level
 * (org / school / campus / class) owns its own dedicated content — not an
 * aggregate of children. Pure functions of the authenticated user, kept in
 * `shared/` so both the data layer (`db/api/*`) and the business layer
 * (`services/*`) can use them without crossing the layer boundary.
 */

export type TenantLevel = 'organization' | 'school' | 'campus' | 'class';

/** The minimal shape these helpers read off the authenticated user. */
export interface TenantUser {
  organizations?: { id: string | null } | null;
  organizationId?: string | null;
  schoolId?: string | null;
  campusId?: string | null;
  classId?: string | null;
  app_role?: { globalAccess?: boolean | null; scope?: string | null } | null;
  activeScope?: {
    level: 'organization' | 'school' | 'campus' | 'class';
    organizationId: string | null;
    schoolId: string | null;
    campusId: string | null;
    classId: string | null;
  } | null;
}

export interface ActiveTenant {
  organizationId: string | null;
  level: TenantLevel;
  schoolId: string | null;
  campusId: string | null;
  classId: string | null;
}

function orgId(user?: TenantUser): string | null {
  return user?.organizations?.id || user?.organizationId || null;
}

function leaf(user: TenantUser | undefined, key: 'schoolId' | 'campusId' | 'classId'): string | null {
  return user?.[key] || null;
}

/** The current user's own tenant (their scope level + matching leaf id). */
export function getOwnTenant(user?: TenantUser): ActiveTenant {
  // Drill-down override: act as the drilled tenant. A class owns no content, so
  // a class-level drill resolves to its campus for content purposes.
  const a = user?.activeScope;
  if (a) {
    if (a.level === 'school') {
      return { organizationId: a.organizationId, level: 'school', schoolId: a.schoolId, campusId: null, classId: null };
    }
    if (a.level === 'campus' || a.level === 'class') {
      return { organizationId: a.organizationId, level: 'campus', schoolId: null, campusId: a.campusId, classId: null };
    }
    return { organizationId: a.organizationId, level: 'organization', schoolId: null, campusId: null, classId: null };
  }

  const organizationId = orgId(user);
  const isGlobal = user?.app_role?.globalAccess === true;
  const scope = user?.app_role?.scope;

  if (!isGlobal && scope === ROLE_SCOPES.SCHOOL) {
    return { organizationId, level: 'school', schoolId: leaf(user, 'schoolId'), campusId: null, classId: null };
  }
  // A class owns no content of its own (only roster + attendance), so class-
  // scoped roles (teacher/support_staff) read campus-level content.
  if (!isGlobal && (scope === ROLE_SCOPES.CAMPUS || scope === ROLE_SCOPES.CLASS)) {
    return { organizationId, level: 'campus', schoolId: null, campusId: leaf(user, 'campusId'), classId: null };
  }
  return { organizationId, level: 'organization', schoolId: null, campusId: null, classId: null };
}

/**
 * Exact-match where for per-tenant content: rows whose owning tenant is exactly
 * this level (the leaf id matches and more-specific levels are null).
 */
export function tenantExactWhere(tenant: ActiveTenant): {
  organizationId?: string;
  schoolId?: string | null;
  campusId?: string | null;
  classId?: string | null;
} {
  const base = tenant.organizationId
    ? { organizationId: tenant.organizationId }
    : {};
  switch (tenant.level) {
    case 'class':
      return { ...base, classId: tenant.classId };
    case 'campus':
      return { ...base, campusId: tenant.campusId, classId: null };
    case 'school':
      return { ...base, schoolId: tenant.schoolId, campusId: null, classId: null };
    case 'organization':
    default:
      return { ...base, schoolId: null, campusId: null, classId: null };
  }
}

/** The owning-tenant ids to stamp on a per-tenant content row at create time. */
export function tenantStamp(tenant: ActiveTenant): {
  organizationId: string | null;
  schoolId: string | null;
  campusId: string | null;
  classId: string | null;
} {
  return {
    organizationId: tenant.organizationId,
    schoolId: tenant.level === 'school' ? tenant.schoolId : null,
    campusId: tenant.level === 'campus' ? tenant.campusId : null,
    classId: tenant.level === 'class' ? tenant.classId : null,
  };
}
