import React, { createContext, useContext, useMemo, type ReactNode } from 'react';

import { canCreateManagedTelegramBot, canManageSuperagent } from './agentPermissions';
import { tierAllowsBestSuperagentModels } from '../features/settings/modelOptions';
import type { SuperagentAgent, SuperagentUser } from '../types';

/**
 * Holds the signed-in platform user (the `/me` payload) injected by the host via
 * the `user` prop on `SuperagentHomeScreen`, and derives feature-flag and
 * capability reads off it.
 *
 * The package never fetches the user — auth is a shell concern (see CLAUDE.md).
 * It only consumes what the host provides. The hooks mirror the web builder's
 * `useFeatureFlags` / `useCapability`, minus the web-only PostHog exposure
 * tracking (also a shell concern). The native package can't import from
 * `apps/builder`, so the `Capability` enum and role check are mirrored here.
 */

/**
 * Capability keys matching the backend Capability enum (the keys returned in the
 * `/me` `allowed_capabilities`). Mirror of the web builder's `Capability` enum.
 */
export enum Capability {
  // Development features
  BACKEND_FUNCTIONS = 'backend_functions',
  CONNECTORS = 'connectors',
  INTEGRATIONS = 'integrations',
  CUSTOM_INTEGRATIONS = 'custom_integrations',
  MCP_CONNECTIONS = 'mcp_connections',
  WORKSPACE_SKILLS = 'workspace_skills',
  CUSTOM_DOMAINS = 'custom_domains',
  CODE_EDITING = 'code_editing',
  STATIC_CODE_ANALYSIS = 'static_code_analysis',
  GITHUB_INTEGRATION = 'github_integration',
  DEV_STAGING = 'dev_staging',
  MANUAL_MODEL_SELECTION = 'manual_model_selection',
  CUSTOM_GOOGLE_OAUTH = 'custom_google_oauth',
  MOBILE_BUILDS = 'mobile_builds',
  CODE_EXPORT = 'code_export',
  SCREEN_RECORDINGS = 'screen_recordings',

  // Apps
  PRIVATE_APPS = 'private_apps',
  INTERNAL_VISIBILITY = 'internal_visibility',
  UNLIMITED_APPS = 'unlimited_apps',

  // Branding
  REMOVE_BADGE = 'remove_badge',

  // Security
  SSO = 'sso',
  ENFORCE_WORKSPACE_SSO = 'enforce_workspace_sso',
  SCIM = 'scim',
  APP_SSO = 'app_sso',
  IP_WHITELISTING = 'ip_whitelisting',
  OPT_OUT_DATA_TRAINING = 'opt_out_data_training',
  AUDIT_LOGS = 'audit_logs',
  WORKSPACE_API_KEYS = 'workspace_api_keys',

  // Team
  ADVANCED_ROLE_PERMISSIONS = 'advanced_role_permissions',
  RESTRICT_MEMBER_APP_VISIBILITY = 'restrict_member_app_visibility',
  PUBLISH_GOVERNANCE = 'publish_governance',
  MEMBER_CREDIT_LIMITS = 'member_credit_limits',

  // Support
  WORKSPACE_MONITORING = 'workspace_monitoring',
  PREMIUM_SUPPORT = 'premium_support',
  PRIVATE_TEMPLATES = 'private_templates',

  // AI Agents
  AGENT_WEBHOOKS = 'agent_webhooks',

  // Marketplace
  PAID_LISTINGS = 'paid_listings',

  // Data Residency
  DATA_RESIDENCY = 'data_residency',

  // Connector Governance
  CONNECTOR_GOVERNANCE = 'connector_governance',

  // Enterprise operational controls & defaults
  SUPERAGENT_CONTROLS = 'superagent_controls',
  APP_TRANSFER_GOVERNANCE = 'app_transfer_governance',
  RATE_LIMIT_MULTIPLIER = 'rate_limit_multiplier',
  EXCLUDE_COST_SAVING_MODELS = 'exclude_cost_saving_models',
  DEDICATED_EMAIL_IP_POOL = 'dedicated_email_ip_pool',
  ADVANCED_SECURITY_POSTURE = 'advanced_security_posture',
  SECURE_WORKSPACE_DEFAULTS = 'secure_workspace_defaults',

  // CRM Metadata
  HUBSPOT_ID = 'hubspot_id',
}

// Mirror of the builder's `isPlatformAdminOrSupportPersonnel`: platform admins,
// owners, and support personnel bypass capability gates so they can investigate
// customer apps without being blocked by upgrade overlays.
const isPlatformAdminOrSupportPersonnel = (platformRole?: string | null): boolean =>
  platformRole === 'platform_admin' ||
  platformRole === 'platform_owner' ||
  platformRole === 'support_personnel';

const UserContext = createContext<SuperagentUser | null>(null);

export function UserProvider({
  user,
  children,
}: {
  user?: SuperagentUser | null;
  children: ReactNode;
}) {
  // Memoize on the user reference so consumers only re-render when the host swaps
  // the user object (e.g. after a /me refresh), not on every parent render.
  const value = useMemo(() => user ?? null, [user]);
  return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}

/**
 * Feature-flag reads off the injected user. `hasFlag(name)` returns whether a
 * flag is enabled; `getFlagVariant(name)` returns the active variant key (or null).
 */
export function useFeatureFlags(): {
  hasFlag: (flagName: string) => boolean;
  getFlagVariant: (flagName: string) => string | null;
} {
  const user = useContext(UserContext);
  const flags = user?.feature_flags;
  const variants = user?.feature_flag_variants;
  return useMemo(
    () => ({
      hasFlag: (flagName: string) => flags?.includes(flagName) ?? false,
      getFlagVariant: (flagName: string) => variants?.[flagName] ?? null,
    }),
    [flags, variants],
  );
}

/**
 * Check if the user has a specific capability. Reads from `allowed_capabilities`
 * (the single source of truth from `/me`); platform admins and support personnel
 * bypass the gate. Same logic as the web builder's `useCapability`, with the user
 * sourced from the injected context instead of an auth hook.
 */
export function useCapability(capability: Capability): boolean {
  const user = useContext(UserContext);

  return useMemo(() => {
    if (isPlatformAdminOrSupportPersonnel(user?.platform_role)) return true;
    if (!user?.allowed_capabilities) return false;
    return user.allowed_capabilities.includes(capability);
  }, [user?.allowed_capabilities, user?.platform_role, capability]);
}

export function useCanManageSuperagent(
  agent: Pick<SuperagentAgent, 'ownerId'>,
): boolean {
  const user = useContext(UserContext);
  return canManageSuperagent(agent, user);
}

export function useCanCreateManagedTelegramBot(
  agent: Pick<SuperagentAgent, 'ownerId'>,
): boolean {
  const user = useContext(UserContext);
  return canCreateManagedTelegramBot(agent, user);
}

/**
 * Whether the user's tier can select the "best" Superagent models (tier ≥ Builder).
 * Derived from the injected `/me` user, mirroring the web `useSuperagentModelAccess`
 * (prefer `subscription_pricing_tier`, fall back to `subscription_tier`).
 */
export function useSuperagentModelAccess(): {
  canSelectBestModel: boolean;
  effectiveTier: string | null;
} {
  const user = useContext(UserContext);
  const effectiveTier = user?.subscription_pricing_tier || user?.subscription_tier || null;
  return useMemo(
    () => ({
      canSelectBestModel: tierAllowsBestSuperagentModels(effectiveTier),
      effectiveTier,
    }),
    [effectiveTier],
  );
}
