/*
 * Copyright (C) 2026 Fluxer Contributors
 *
 * This file is part of Fluxer.
 *
 * Fluxer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fluxer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
 */

import * as ModalActionCreators from '@app/actions/ModalActionCreators';
import {modal} from '@app/actions/ModalActionCreators';
import {CustomStatusDisplay} from '@app/components/common/custom_status_display/CustomStatusDisplay';
import {UserProfileModal} from '@app/components/modals/UserProfileModal';
import {UserProfileBadges} from '@app/components/popouts/UserProfileBadges';
import {UserProfileMembershipInfo, UserProfilePreviewBio} from '@app/components/popouts/UserProfileShared';
import styles from '@app/components/profile/ProfilePreview.module.css';
import {ProfileCardBanner} from '@app/components/profile/profile_card/ProfileCardBanner';
import {ProfileCardContent} from '@app/components/profile/profile_card/ProfileCardContent';
import {ProfileCardFooter} from '@app/components/profile/profile_card/ProfileCardFooter';
import {ProfileCardLayout} from '@app/components/profile/profile_card/ProfileCardLayout';
import {ProfileCardUserInfo} from '@app/components/profile/profile_card/ProfileCardUserInfo';
import {useProfileCardDisplayState} from '@app/components/profile/useProfileCardDisplayState';
import {Button} from '@app/components/uikit/button/Button';
import FocusRing from '@app/components/uikit/focus_ring/FocusRing';
import {Tooltip} from '@app/components/uikit/tooltip/Tooltip';
import {useAutoplayExpandedProfileAnimations} from '@app/hooks/useAutoplayExpandedProfileAnimations';
import type {CustomStatus} from '@app/lib/CustomStatus';
import type {GuildMemberRecord} from '@app/records/GuildMemberRecord';
import type {ProfileRecord} from '@app/records/ProfileRecord';
import type {UserRecord} from '@app/records/UserRecord';
import GuildStore from '@app/stores/GuildStore';
import * as NicknameUtils from '@app/utils/NicknameUtils';
import type {ProfilePreviewOverrides} from '@app/utils/ProfileDisplayUtils';
import {type BadgeSettings, createMockProfile} from '@app/utils/ProfileUtils';
import type {UserProfile} from '@fluxer/schema/src/domains/user/UserResponseSchemas';
import {Trans, useLingui} from '@lingui/react/macro';
import {ChatTeardropIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {useCallback, useMemo} from 'react';

interface ProfilePreviewProps {
	user: UserRecord;
	previewAvatarUrl?: string | null;
	previewBannerUrl?: string | null;
	hasClearedAvatar?: boolean;
	hasClearedBanner?: boolean;
	previewBio?: string | null;
	previewPronouns?: string | null;
	previewAccentColor?: number | null;
	previewGlobalName?: string | null;
	previewNick?: string | null;
	guildId?: string | null;
	guildMember?: GuildMemberRecord | null;
	guildMemberProfile?: UserProfile | null;
	previewBadgeSettings?: BadgeSettings;
	ignoreGuildAvatarInPreview?: boolean;
	ignoreGuildBannerInPreview?: boolean;
	showMembershipInfo?: boolean;
	showMessageButton?: boolean;
	showPreviewLabel?: boolean;
	previewCustomStatus?: CustomStatus | null;
}

export const ProfilePreview: React.FC<ProfilePreviewProps> = observer(
	({
		user,
		previewAvatarUrl,
		previewBannerUrl,
		hasClearedAvatar,
		hasClearedBanner,
		previewBio,
		previewPronouns,
		previewAccentColor,
		previewGlobalName,
		previewNick,
		guildId,
		guildMember,
		guildMemberProfile,
		previewBadgeSettings,
		ignoreGuildAvatarInPreview,
		ignoreGuildBannerInPreview,
		showMembershipInfo = true,
		showMessageButton = true,
		showPreviewLabel = true,
		previewCustomStatus,
	}) => {
		const {t} = useLingui();

		const previewOverrides = useMemo<ProfilePreviewOverrides>(
			() => ({
				previewAvatarUrl,
				previewBannerUrl,
				hasClearedAvatar,
				hasClearedBanner,
				ignoreGuildAvatar: ignoreGuildAvatarInPreview,
				ignoreGuildBanner: ignoreGuildBannerInPreview,
			}),
			[
				previewAvatarUrl,
				previewBannerUrl,
				hasClearedAvatar,
				hasClearedBanner,
				ignoreGuildAvatarInPreview,
				ignoreGuildBannerInPreview,
			],
		);

		const previewUser = useMemo(() => {
			const bio = previewBio !== undefined ? previewBio : user.bio;
			const pronouns = previewPronouns !== undefined ? previewPronouns : user.pronouns;
			const globalName = previewGlobalName !== undefined ? previewGlobalName : user.globalName;
			return user.withUpdates({bio, pronouns, global_name: globalName});
		}, [user, previewBio, previewPronouns, previewGlobalName]);

		const mockProfile = useMemo(() => {
			const profile = createMockProfile(previewUser, {
				previewBannerUrl,
				hasClearedBanner,
				previewBio,
				previewPronouns,
				previewAccentColor,
				previewBadgeSettings,
			});

			if (guildId && guildMemberProfile) {
				return profile
					.withUpdates({
						guild_member_profile: {
							bio: previewBio !== undefined ? previewBio : guildMemberProfile.bio,
							banner: previewBannerUrl || guildMemberProfile.banner,
							pronouns: previewPronouns !== undefined ? previewPronouns : guildMemberProfile.pronouns,
							accent_color: previewAccentColor !== undefined ? previewAccentColor : guildMemberProfile.accent_color,
						},
					})
					.withGuildId(guildId);
			}

			return profile;
		}, [
			previewUser,
			previewBannerUrl,
			hasClearedBanner,
			previewBio,
			previewPronouns,
			previewAccentColor,
			previewBadgeSettings,
			guildId,
			guildMemberProfile,
		]);

		const shouldAutoplayProfileAnimations = useAutoplayExpandedProfileAnimations();

		const {
			avatarUrl: finalAvatarUrl,
			hoverAvatarUrl: finalHoverAvatarUrl,
			bannerUrl: finalBannerUrl,
			accentColor,
		} = useProfileCardDisplayState({
			user,
			profile: mockProfile,
			guildId,
			guildMember,
			guildMemberProfile: mockProfile.getGuildMemberProfile() ?? guildMemberProfile,
			previewOverrides,
			accentUser: previewUser,
			shouldAutoplayProfileAnimations,
		});

		const openMockProfile = useCallback(() => {
			ModalActionCreators.push(
				modal(() => (
					<UserProfileModal
						userId={user.id}
						guildId={guildId || undefined}
						disableEditProfile={true}
						previewOverrides={{
							previewAvatarUrl,
							previewBannerUrl,
							hasClearedAvatar,
							hasClearedBanner,
						}}
						previewUser={previewUser}
					/>
				)),
			);
		}, [user.id, guildId, previewAvatarUrl, previewBannerUrl, hasClearedAvatar, hasClearedBanner, previewUser]);

		const pronouns = previewPronouns !== undefined ? previewPronouns : user.pronouns;
		const displayName = previewNick || NicknameUtils.getNickname(previewUser, guildId ?? undefined);

		const borderColor = accentColor;
		const bannerColor = accentColor;

		const selectedGuild = guildId ? GuildStore.getGuild(guildId) : null;

		const hasPreviewStatus = previewCustomStatus !== undefined;

		const handlePreviewKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
			if (event.key === 'Enter' || event.key === ' ') {
				event.preventDefault();
				openMockProfile();
			}
		};

		return (
			<FocusRing offset={-2}>
				<div
					className={styles.previewInteractive}
					role="group"
					aria-label={t`Profile preview (press Enter to open full preview)`}
					onKeyDown={handlePreviewKeyDown}
				>
					<ProfileCardLayout borderColor={borderColor} showPreviewLabel={showPreviewLabel}>
						<ProfileCardBanner
							bannerUrl={finalBannerUrl}
							bannerColor={bannerColor}
							user={user}
							avatarUrl={finalAvatarUrl}
							hoverAvatarUrl={finalHoverAvatarUrl}
							isClickable={true}
							onAvatarClick={openMockProfile}
						/>

						<UserProfileBadges user={previewUser} profile={mockProfile} />

						<ProfileCardContent>
							<ProfileCardUserInfo
								displayName={displayName}
								user={previewUser}
								pronouns={pronouns}
								showUsername={true}
								isClickable={true}
								onDisplayNameClick={openMockProfile}
								onUsernameClick={openMockProfile}
							/>
							<div className={styles.profileCustomStatus}>
								<CustomStatusDisplay
									userId={hasPreviewStatus ? undefined : user.id}
									customStatus={hasPreviewStatus ? previewCustomStatus : undefined}
									className={styles.profileCustomStatusText}
									allowJumboEmoji
									maxLines={0}
									alwaysAnimate={shouldAutoplayProfileAnimations}
								/>
							</div>
							<UserProfilePreviewBio profile={mockProfile} onShowMore={openMockProfile} />
							{showMembershipInfo && (
								<UserProfileMembershipInfo
									profile={{...mockProfile, guild: selectedGuild, guildMember} as ProfileRecord}
									user={previewUser}
								/>
							)}
						</ProfileCardContent>

						{showMessageButton && (
							<ProfileCardFooter>
								<Tooltip text={t`You can't message yourself`} maxWidth="xl">
									<div className={styles.messageButtonWrapper}>
										<Button
											small={true}
											fitContainer={true}
											leftIcon={<ChatTeardropIcon className={styles.messageIcon} />}
											disabled={true}
										>
											<Trans>Message</Trans>
										</Button>
									</div>
								</Tooltip>
							</ProfileCardFooter>
						)}
					</ProfileCardLayout>
				</div>
			</FocusRing>
		);
	},
);
