import { useEffect, useState } from 'react';

import type { AnyProfileView } from '@atcute/bluesky';
import type { ModerationOptions } from '@atcute/bluesky-moderation';
import type { Did } from '@atcute/lexicons';

import { clsx } from 'clsx';

import { profileTarget } from '#/lib/routes/targets';

import { useModerationOpts } from '#/state/moderation/moderation-opts';
import type { FeedDescriptor } from '#/state/queries/feed-descriptor';
import { useSuggestedFollowsByActorWithDismiss } from '#/state/queries/suggested-follows';
import { useGetSuggestedUsersForDiscoverQuery } from '#/state/queries/trending/useGetSuggestedUsersForDiscoverQuery';
import { useSession } from '#/state/session';

import { BlockLink } from '#/components/BlockLink';
import * as Dialog from '#/components/Dialog';
import * as css from '#/components/FeedInterstitials.css';
import { SuggestedFollowsDialog } from '#/components/SuggestedFollowsDialog';
import { Text } from '#/components/Text';
import * as ProfileCard from '#/components/web/ProfileCard';
import * as Skeleton from '#/components/web/Skeleton';

import ArrowRightIcon from '#/icons/central/ArrowRight_round_outlined_radius1_stroke2.svg';
import XIcon from '#/icons/central/CrossLarge_round_outlined_radius1_stroke2.svg';
import { m } from '#/paraglide/messages';

function SuggestedFollowPlaceholder() {
	return (
		<div className={css.cardBase}>
			<div className={css.body}>
				<ProfileCard.AvatarPlaceholder size={88} />
				<div className={css.identity}>
					<Skeleton.Text size="md" width="60%" />
					<div className={css.description}>
						<Skeleton.Lines color="contrast_50" count={2} lastWidth={60} size="sm" />
					</div>
				</div>
			</div>
			<div className={css.followPlaceholder} />
		</div>
	);
}

function SuggestedFollowCard({
	moderationOpts,
	onDismiss,
	profile,
}: {
	moderationOpts: ModerationOptions;
	onDismiss?: (did: string) => void;
	profile: AnyProfileView;
}) {
	return (
		<BlockLink
			className={clsx(css.cardBase, css.cardLink)}
			label={m['common.profile.a11y.viewNamed']({
				name: profile.handle,
			})}
			to={profileTarget(profile.did)}
		>
			<div>
				{onDismiss && (
					<button
						aria-label={m['components.feedInterstitials.action.dismiss']()}
						className={css.dismiss}
						onClick={() => onDismiss(profile.did)}
						type="button"
					>
						<XIcon className={css.xIcon} />
					</button>
				)}
				<div className={css.body}>
					<ProfileCard.Avatar disabledPreview moderationOpts={moderationOpts} profile={profile} size={88} />
					<div className={css.identity}>
						<ProfileCard.Handle profile={profile} />
						<div className={css.description}>
							<ProfileCard.Description
								align="center"
								color="textContrastMedium"
								numberOfLines={2}
								profile={profile}
								size="sm"
							/>
						</div>
					</div>
				</div>
				<ProfileCard.FollowButton profile={profile} variant="text-only" />
			</div>
		</BlockLink>
	);
}

export function SuggestedFollows({ feed }: { feed: FeedDescriptor }) {
	const { currentAccount } = useSession();
	if (feed.type === 'author') {
		if (currentAccount?.did === feed.did) {
			return null;
		}
		return <SuggestedFollowsProfile did={feed.did} />;
	}
	return <SuggestedFollowsHome />;
}

export function SuggestedFollowsProfile({ did }: { did: Did }) {
	const { profiles, onDismiss, isLoading, error } = useSuggestedFollowsByActorWithDismiss({ did });

	return (
		<ProfileGrid
			error={error}
			isSuggestionsLoading={isLoading}
			onDismiss={onDismiss}
			profiles={profiles}
			viewContext="profile"
		/>
	);
}

export function SuggestedFollowsHome() {
	const { isLoading, data, error } = useGetSuggestedUsersForDiscoverQuery();

	const [dismissedDids, setDismissedDids] = useState<Set<string>>(new Set());

	const onDismiss = (did: string) => {
		setDismissedDids((prev) => new Set(prev).add(did));
	};

	const allProfiles = data?.actors ?? [];
	const filteredProfiles = allProfiles.filter((p) => !dismissedDids.has(p.did));

	return (
		<ProfileGrid
			error={error}
			isSuggestionsLoading={isLoading}
			onDismiss={onDismiss}
			profiles={filteredProfiles}
			totalProfileCount={allProfiles.length}
			viewContext="feed"
		/>
	);
}

export function ProfileGrid({
	error,
	isSuggestionsLoading,
	onDismiss,
	onRequestHide,
	profiles,
	totalProfileCount,
	viewContext,
}: {
	error: Error | null;
	isSuggestionsLoading: boolean;
	onDismiss?: (did: string) => void;
	onRequestHide?: () => void;
	profiles: AnyProfileView[];
	totalProfileCount?: number;
	viewContext: 'feed' | 'profile' | 'profileHeader';
}) {
	const moderationOpts = useModerationOpts();
	const followDialogHandle = Dialog.useDialogHandle();

	const isLoading = isSuggestionsLoading || !moderationOpts;
	const isProfileHeaderContext = viewContext === 'profileHeader';

	// the wide grid caps at a single row of 3; the phone scroller and the taller profile-header carousel show more.
	const maxLength = isProfileHeaderContext ? 12 : 6;
	const minLength = 3;

	const content = isLoading
		? Array(maxLength)
				.fill(0)
				// oxlint-disable-next-line react/no-array-index-key -- static skeleton
				.map((_, i) => <SuggestedFollowPlaceholder key={i} />)
		: error || !profiles.length
			? null
			: profiles
					.slice(0, maxLength)
					.map((profile) =>
						moderationOpts ? (
							<SuggestedFollowCard
								key={profile.did}
								moderationOpts={moderationOpts}
								onDismiss={onDismiss}
								profile={profile}
							/>
						) : null,
					);

	// use totalProfileCount (before dismissals) for the minLength check on initial render.
	const profileCountForMinCheck = totalProfileCount ?? profiles.length;

	useEffect(() => {
		if (error || (!isLoading && profileCountForMinCheck < minLength)) {
			onRequestHide?.();
		}
	}, [error, isLoading, onRequestHide, profileCountForMinCheck, minLength]);

	if (error || (!isLoading && profileCountForMinCheck < minLength)) {
		return null;
	}

	return (
		<div className={css.section({ topBorder: !isProfileHeaderContext })}>
			<div className={css.header}>
				<Text size="md_sub" weight="semiBold">
					{m['components.feedInterstitials.title']()}
				</Text>

				<Dialog.Trigger
					aria-label={m['components.feedInterstitials.seeMoreA11y']()}
					className={css.seeMoreTrigger}
					handle={followDialogHandle}
				>
					<Text className={css.seeMoreText} color="primary_600" weight="semiBold" size="md_sub">
						{m['components.feedInterstitials.action.seeMore']()}
					</Text>
				</Dialog.Trigger>
			</div>
			<SuggestedFollowsDialog handle={followDialogHandle} />
			<div className={css.grid}>
				{content}
				<Dialog.Trigger
					aria-label={m['components.feedInterstitials.action.browseMore']()}
					className={css.seeMoreCard}
					handle={followDialogHandle}
				>
					<ArrowRightIcon className={css.arrowRightIcon} />
					<Text align="center" size="md" weight="medium">
						{m['components.feedInterstitials.action.seeMore']()}
					</Text>
				</Dialog.Trigger>
			</div>
		</div>
	);
}
