import React from "react";
import { Image, Pressable, View } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { useColorScheme } from "nativewind";
import { EntropyMark } from "./entropy-mark";
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip";
const PROVIDERS = [
    // The real `>_` company mark, not a stand-in glyph. This is a first-party
    // sign-in sitting next to three brand marks; anything generic reads as a
    // placeholder rather than as an option worth picking.
    { key: "entropy", label: "Entropy", icon: null },
    { key: "apple", label: "Apple", icon: "logo-apple" },
    { key: "google", label: "Google", icon: "logo-google" },
    { key: "microsoft", label: "Microsoft", icon: "logo-microsoft" },
];
/**
 * The providers to render, in {@link PROVIDERS} order.
 *
 * Exported and pure so the visibility rules are testable without a render
 * runtime — the component itself pulls in `@expo/vector-icons` and reanimated,
 * which the unit-suite transform does not process.
 *
 * Order comes from `PROVIDERS`, not from the caller's flags, so the row cannot
 * reshuffle between renders or between consumers.
 */
export function visibleProviders(shown) {
    return PROVIDERS.filter(({ key }) => shown[key]);
}
/**
 * What a caller-supplied provider's button should draw.
 *
 * Pure, exported and separate from the component for the same reason
 * {@link visibleProviders} is: the fallback rule is the part worth testing, and
 * the component pulls in `@expo/vector-icons` and reanimated, which the unit
 * suite's transform does not process.
 *
 * A blank or whitespace-only URL counts as absent, not as a URL to fetch: an
 * operator who clears the field in a form leaves `""` behind far more often
 * than `null`, and `<Image source={{uri: ""}}>` is a request that fails
 * silently on web and renders an empty square on native.
 */
export function customIcon(iconUrl, failed) {
    const uri = iconUrl?.trim();
    if (!uri || failed) {
        return { kind: "fallback" };
    }
    return { kind: "image", uri };
}
/**
 * Button row for federated sign-in: Entropy / Apple / Google / Microsoft.
 *
 * Each handler is optional — a provider with no handler still renders but fires
 * no action, which is the "coming soon" UX the consumer apps use during a
 * staged rollout. All four route through ONE endpoint on the server
 * (`/api/auth/oidc/start?connector=…`); the difference between them is a hint
 * passed to Access, not a separate flow.
 *
 * To render only some providers, use the `show*` flags — one per provider, all
 * defaulting to `true`. A consumer that knows which upstream connectors are
 * configured (Entropy Access does, per tenant) should pass them, or it will
 * draw brand marks for providers that cannot complete a sign-in.
 *
 * The buttons are icon-only, so each carries a tooltip AND an
 * `accessibilityLabel`. The two are not redundant: the tooltip is for a sighted
 * user hovering on web or long-pressing on native, the label is what a screen
 * reader announces. Without the tooltip these are four unlabelled squares, and
 * a user has to guess which mark is which.
 */
export function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, showEntropy = true, showApple = true, showGoogle = true, showMicrosoft = true, custom = [], }) {
    const { colorScheme } = useColorScheme();
    const isDark = colorScheme === "dark";
    const handlers = {
        entropy: onEntropy,
        apple: onApple,
        google: onGoogle,
        microsoft: onMicrosoft,
    };
    // One map rather than four `key !== "x" || showX` clauses: the filter used
    // to name `entropy` explicitly, which read fine for one exception and would
    // be four boolean conditions for four. `ProviderVisibility` requires every
    // key, so adding a provider to PROVIDERS without deciding its flag is a type
    // error rather than a button nobody can turn off.
    const shown = {
        entropy: showEntropy,
        apple: showApple,
        google: showGoogle,
        microsoft: showMicrosoft,
    };
    return (<View className="w-full flex-row items-center justify-center gap-3">
      {visibleProviders(shown).map(({ key, icon, label }) => (<Tooltip key={key} delayDuration={200}>
            <TooltipTrigger asChild>
              <Pressable onPress={handlers[key]} className="h-12 w-12 items-center justify-center rounded-lg border border-border dark:border-neutral-600 active:opacity-70" accessibilityRole="button" accessibilityLabel={`Continue with ${label}`}>
                {icon ? (<Ionicons name={icon} size={22} color={isDark ? "#FFFFFF" : "#000000"}/>) : (
            // driftScale 0 collapses the echo offsets onto the mark. The
            // drift is a boot-animation effect and at 18px it just reads as
            // a smear, which next to three crisp brand glyphs looks like a
            // rendering fault rather than a logo.
            <EntropyMark size={20} driftScale={0}/>)}
              </Pressable>
            </TooltipTrigger>
            <TooltipContent>{`Continue with ${label}`}</TooltipContent>
          </Tooltip>))}
      {custom.map((provider) => (<CustomProviderButton 
        // Namespaced so a caller's key cannot collide with a built-in's and
        // silently replace it in the reconciler.
        key={`custom:${provider.key}`} provider={provider} isDark={isDark}/>))}
    </View>);
}
/**
 * One caller-supplied provider.
 *
 * Its own component because it holds state the built-ins do not: whether the
 * remote icon failed. A broken URL has to degrade to the neutral glyph, and
 * `onError` can only be observed per image.
 */
function CustomProviderButton({ provider, isDark, }) {
    const [iconFailed, setIconFailed] = React.useState(false);
    const tint = isDark ? "#FFFFFF" : "#000000";
    const icon = customIcon(provider.iconUrl, iconFailed);
    return (<Tooltip delayDuration={200}>
      <TooltipTrigger asChild>
        <Pressable onPress={provider.onPress} className="h-12 w-12 items-center justify-center rounded-lg border border-border dark:border-neutral-600 active:opacity-70" accessibilityRole="button" accessibilityLabel={`Continue with ${provider.label}`}>
          {icon.kind === "image" ? (<Image source={{ uri: icon.uri }} style={{ width: 22, height: 22 }} 
        // `contain` rather than `cover`: an operator's mark is whatever
        // aspect ratio they have, and cropping somebody's logo to a
        // square is worse than letterboxing it.
        resizeMode="contain" onError={() => setIconFailed(true)} accessibilityIgnoresInvertColors/>) : (
        // The neutral fallback. A key rather than a globe or a puzzle
        // piece: this is a sign-in credential, and the glyph should say so
        // without implying a vendor.
        <Ionicons name="key-outline" size={22} color={tint}/>)}
        </Pressable>
      </TooltipTrigger>
      <TooltipContent>{`Continue with ${provider.label}`}</TooltipContent>
    </Tooltip>);
}
export default SocialConnections;
//# sourceMappingURL=social-connections.jsx.map