"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserProfileCard = exports.ProfileCardProvider = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const expo_image_1 = require("expo-image");
const react_1 = require("react");
const react_native_1 = require("react-native");
const __1 = require("../..");
const useAvatars_1 = require("../../hooks/useAvatars");
const icon_bsky_1 = tslib_1.__importDefault(require("../../icons/icon-bsky"));
const atoms_1 = require("../../lib/theme/atoms");
const livestream_store_1 = require("../../livestream-store");
const streamplace_store_1 = require("../../streamplace-store");
const ui_1 = require("../../ui");
const format_handle_1 = require("../../utils/format-handle");
const ui_2 = require("../ui");
const dropdown_1 = require("../ui/dropdown");
const text_1 = require("../ui/text");
const badge_1 = require("./badge");
const BADGE_META = {
    "place.stream.badge.defs#mod": {
        label: "Moderator",
        issuedBy: "{issuer} for {streamer}",
    },
    "place.stream.badge.defs#bot": {
        label: "Bot",
        description: "This account has been marked as automated by its owner.",
    },
    "place.stream.badge.defs#streamer": {
        label: "Streamer",
    },
    "place.stream.badge.defs#vip": {
        label: "VIP",
        description: "This user is clearly a very important person.",
    },
};
const OpenCardContext = (0, react_1.createContext)({
    openCard: null,
    setOpenCard: () => { },
});
function useProfileCardData(author, badges) {
    const nodeUrl = (0, streamplace_store_1.useUrl)();
    const serviceDid = nodeUrl
        ? `did:web:${nodeUrl.replace(/^https?:\/\//, "")}`
        : null;
    const streamer = (0, livestream_store_1.useLivestreamStore)((x) => x.livestream?.author);
    const issuerDids = (0, react_1.useMemo)(() => badges?.map((b) => b.issuer).filter((did) => did && did !== serviceDid) ??
        [], [badges, serviceDid]);
    const allDids = (0, react_1.useMemo)(() => (author.did ? [author.did, ...issuerDids] : issuerDids), [author.did, issuerDids]);
    const profiles = (0, useAvatars_1.useAvatars)(allDids);
    const allBadges = (badges ?? []);
    return {
        author,
        profile: profiles[author.did],
        profiles,
        serviceDid,
        allBadges,
        streamer,
    };
}
const BadgeRow = ({ streamer, badge, serviceDid, issuerProfiles, }) => {
    const isServiceIssued = badge.issuer === serviceDid;
    const meta = BADGE_META[badge.badgeType];
    const label = meta?.label ?? badge.name ?? badge.badgeType.split("#")[1];
    const description = meta?.description ?? badge.description;
    let issuerLabel = isServiceIssued
        ? "Streamplace"
        : issuerProfiles[badge.issuer]?.handle
            ? `@${issuerProfiles[badge.issuer].handle}`
            : badge.issuer;
    const issuedByTemplate = meta?.issuedBy ?? "Issued by {issuer}";
    issuerLabel = issuedByTemplate
        .replace("{issuer}", issuerLabel)
        .replace("{streamer}", streamer?.handle ? (0, format_handle_1.formatHandleWithAt)(streamer) : "the streamer");
    return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
            atoms_1.gap.all[3],
            atoms_1.pl[2],
            { flexDirection: "row", alignItems: "center" },
        ], children: [(0, jsx_runtime_1.jsx)(badge_1.Badge, { badgeType: badge.badgeType, size: 32, imageUrl: badge.imageUrl }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [{ flex: 1 }], children: [(0, jsx_runtime_1.jsx)(text_1.Text, { size: "xs", children: label }), (0, jsx_runtime_1.jsx)(text_1.Text, { size: "xs", color: "muted", children: issuerLabel }), description && ((0, jsx_runtime_1.jsx)(text_1.Text, { size: "xs", color: "muted", children: description }))] })] }));
};
const ProfileCardContent = ({ data, theme, }) => {
    const { author, profile, profiles, serviceDid, allBadges, streamer } = data;
    return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [__1.zero.pb[1]], children: [profile?.banner ? ((0, jsx_runtime_1.jsx)(expo_image_1.Image, { source: { uri: profile.banner }, style: [atoms_1.h[20], { width: "100%" }, react_native_1.Platform.OS != "web" && __1.zero.r.md] })) : ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
                    atoms_1.h[20],
                    { width: "100%", backgroundColor: theme.colors.muted },
                ] })), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
                    atoms_1.px[3],
                    {
                        flexDirection: "row",
                        alignItems: "flex-end",
                        justifyContent: "space-between",
                        marginTop: -24,
                    },
                ], children: profile?.avatar ? ((0, jsx_runtime_1.jsx)(expo_image_1.Image, { source: { uri: profile.avatar }, style: [
                        atoms_1.w[12],
                        atoms_1.h[12],
                        atoms_1.r.full,
                        { borderWidth: 2, borderColor: theme.colors.card },
                    ] })) : ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [
                        atoms_1.w[12],
                        atoms_1.h[12],
                        atoms_1.r.full,
                        {
                            borderWidth: 2,
                            borderColor: theme.colors.card,
                            backgroundColor: theme.colors.mutedForeground,
                        },
                    ] })) }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [atoms_1.px[3]], children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
                            __1.zero.layout.flex.row,
                            __1.zero.layout.flex.alignCenter,
                            __1.zero.layout.flex.justify.between,
                            atoms_1.gap.all[2],
                        ], children: [(0, jsx_runtime_1.jsxs)(text_1.Text, { children: ["@", author.handle] }), react_native_1.Platform.OS === "web" && ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: { position: "absolute", right: 2, bottom: 7 }, children: (0, jsx_runtime_1.jsx)(ui_2.Button, { size: "pill", variant: "secondary", style: { aspectRatio: 1 }, onPress: () => {
                                        react_native_1.Linking.openURL(`https://bsky.app/profile/${author.handle}`);
                                    }, children: (0, jsx_runtime_1.jsx)(icon_bsky_1.default, { size: 18 }) }) }))] }), allBadges.length > 0 ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [__1.zero.py[2]], children: (0, jsx_runtime_1.jsx)(ui_2.MenuGroup, { children: allBadges.map((badge, i) => ((0, jsx_runtime_1.jsx)(BadgeRow, { badge: badge, serviceDid: serviceDid ?? "", streamer: streamer, issuerProfiles: profiles }, i))) }) })) : null] }), react_native_1.Platform.OS !== "web" && ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: [atoms_1.px[3], atoms_1.pt[2]], children: (0, jsx_runtime_1.jsx)(ui_2.Button, { variant: "secondary", size: "sm", onPress: () => {
                        react_native_1.Linking.openURL(`https://bsky.app/profile/${author.handle}`);
                    }, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [
                            __1.zero.gap.all[2],
                            __1.zero.layout.flex.row,
                            __1.zero.layout.flex.alignCenter,
                        ], children: [(0, jsx_runtime_1.jsx)(icon_bsky_1.default, { size: 20 }), (0, jsx_runtime_1.jsx)(text_1.Text, { children: "View Profile" })] }) }) }))] }));
};
// Web only overlay rendered in a React portal
const ProfileCardOverlay = ({ card, onClose, }) => {
    const { theme } = (0, ui_1.useTheme)();
    const data = useProfileCardData(card.author, card.badges);
    const [portalContainer, setPortalContainer] = (0, react_1.useState)(null);
    (0, react_1.useEffect)(() => {
        if (typeof document !== "undefined") {
            setPortalContainer(document.body);
        }
    }, []);
    if (!portalContainer)
        return null;
    const viewportWidth = typeof window !== "undefined" ? window.innerWidth : 400;
    const viewportHeight = typeof window !== "undefined" ? window.innerHeight : 600;
    const cardWidth = 300;
    const left = Math.max(8, Math.min(card.anchorX, viewportWidth - cardWidth - 8));
    const flipUp = viewportHeight - card.anchorY < 280;
    const verticalStyle = flipUp
        ? { bottom: viewportHeight - card.anchorY + 4 }
        : { top: card.anchorY + 4 };
    const { createPortal } = require("react-dom");
    return createPortal((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { onPress: onClose, style: {
                    position: "fixed",
                    top: 0,
                    left: 0,
                    right: 0,
                    bottom: 0,
                    zIndex: 9998,
                } }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { style: [
                    atoms_1.r.md,
                    atoms_1.borders.width.thin,
                    atoms_1.shadows.lg,
                    {
                        position: "fixed",
                        left,
                        ...verticalStyle,
                        width: cardWidth,
                        zIndex: 9999,
                        backgroundColor: theme.colors.popover,
                        borderColor: theme.colors.border,
                        overflow: "hidden",
                    },
                ], children: (0, jsx_runtime_1.jsx)(ProfileCardContent, { data: data, theme: theme }) })] }), portalContainer);
};
const ProfileCardProvider = ({ children, }) => {
    const [openCard, setOpenCard] = (0, react_1.useState)(null);
    const value = (0, react_1.useMemo)(() => ({ openCard, setOpenCard }), [openCard]);
    return ((0, jsx_runtime_1.jsxs)(OpenCardContext.Provider, { value: value, children: [children, openCard && react_native_1.Platform.OS === "web" && ((0, jsx_runtime_1.jsx)(ProfileCardOverlay, { card: openCard, onClose: () => setOpenCard(null) }))] }));
};
exports.ProfileCardProvider = ProfileCardProvider;
const UserProfileCard = ({ uri, author, badges, children, }) => {
    const { theme } = (0, ui_1.useTheme)();
    const data = useProfileCardData(author, badges);
    const { setOpenCard } = (0, react_1.useContext)(OpenCardContext);
    const [hovered, setHovered] = (0, react_1.useState)(false);
    // web: ref for measuring anchor position
    const triggerRef = (0, react_1.useRef)(null);
    // native: ref for the dropdown trigger
    const dropdownRef = (0, react_1.useRef)(null);
    const openWebCard = (0, react_1.useCallback)(() => {
        if (triggerRef.current) {
            triggerRef.current.measureInWindow((x, y, width, height) => {
                setOpenCard({ uri, author, badges, anchorX: x, anchorY: y + height });
            });
        }
    }, [uri, author, badges, setOpenCard]);
    // Native: use DropdownMenu for built-in positioning and interactions.
    // * important ! all data must be computed outside the dropdown and passed in!
    if (react_native_1.Platform.OS !== "web") {
        return ((0, jsx_runtime_1.jsxs)(dropdown_1.DropdownMenu, { children: [(0, jsx_runtime_1.jsx)(dropdown_1.DropdownMenuTrigger, { ref: dropdownRef, asChild: true, children: (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { style: { flexDirection: "row", alignItems: "center" }, onPress: () => { }, children: children }) }), (0, jsx_runtime_1.jsx)(dropdown_1.DropdownMenuContent, { style: { minWidth: 280, maxWidth: 320 }, children: (0, jsx_runtime_1.jsx)(ProfileCardContent, { data: data, theme: theme }) })] }));
    }
    // Web: Pressable that pushes card data + anchor coords into context for the portal overlay.
    return ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { ref: triggerRef, onPress: openWebCard, onHoverIn: () => setHovered(true), onHoverOut: () => setHovered(false), style: [
            atoms_1.gap.all[1],
            atoms_1.px[1],
            atoms_1.pb[1],
            hovered ? atoms_1.r.sm : undefined,
            {
                flexDirection: "row",
                alignItems: "center",
                marginLeft: -3,
                marginRight: -2,
                marginBottom: -4,
                ...(hovered ? { backgroundColor: "rgba(255,255,255,0.15)" } : {}),
            },
        ], children: children }));
};
exports.UserProfileCard = UserProfileCard;
//# sourceMappingURL=user-profile-card.js.map