import type { CSSProperties } from 'react';

import type { AppBskyFeedDefs, AppBskyFeedPost } from '@atcute/bluesky';
import {
	DisplayContext,
	getDisplayRestrictions,
	moderatePost,
	type ModerationDecision,
} from '@atcute/bluesky-moderation';
import { parseCanonicalResourceUri } from '@atcute/lexicons/syntax';

import { useQueryClient } from '@tanstack/react-query';
import { clsx } from 'clsx';

import { getPostRecord } from '#/lib/api/record-casts';
import type { Richtext } from '#/lib/rich-text';
import { postUriToTarget } from '#/lib/routes/targets';

import { POST_TOMBSTONE, type Shadow, usePostShadow } from '#/state/cache/post-shadow';
import { useModerationOpts } from '#/state/moderation/moderation-opts';
import { unstableCacheProfileView } from '#/state/queries/profile';

import { useOpenComposer } from '#/features/composer/open-composer';

import { BlockLink } from '#/components/BlockLink';
import { GalleryBleed, maybeApplyGalleryOffsetStyles } from '#/components/images/Gallery';
import { LabelsOnMyPost } from '#/components/moderation/LabelsOnMe';
import { PostRepliedTo } from '#/components/Post/PostRepliedTo';
import { PostContent } from '#/components/PostContent';
import { PostControls } from '#/components/PostControls';
import { PostOverflowMenuButton } from '#/components/PostControls/PostOverflowMenuButton';
import * as PostLayout from '#/components/PostLayout';
import { PostMeta } from '#/components/PostMeta';
import { PreviewableUserAvatar } from '#/components/PreviewableUserAvatar';

import * as css from './Post.css';

export function Post({
	post,
	hideTopBorder,
	style,
}: {
	post: AppBskyFeedDefs.PostView;
	hideTopBorder?: boolean;
	/** Chrome override merged onto the row (e.g. the unread-notification highlight). */
	style?: CSSProperties;
}) {
	const moderationOpts = useModerationOpts();
	const record = getPostRecord(post);
	const postShadowed = usePostShadow(post);
	const richText = record
		? {
				text: record.text,
				facets: record.facets,
			}
		: undefined;
	const moderation = moderationOpts ? moderatePost(post, moderationOpts) : undefined;
	if (postShadowed === POST_TOMBSTONE) {
		return null;
	}
	if (record && richText && moderation) {
		return (
			<PostInner
				post={postShadowed}
				record={record}
				richText={richText}
				moderation={moderation}
				hideTopBorder={hideTopBorder}
				style={style}
			/>
		);
	}
	return null;
}

function PostInner({
	post,
	record,
	richText,
	moderation,
	hideTopBorder,
	style,
}: {
	post: Shadow<AppBskyFeedDefs.PostView>;
	record: AppBskyFeedPost.Main;
	richText: Richtext;
	moderation: ModerationDecision;
	hideTopBorder?: boolean;
	style?: CSSProperties;
}) {
	const queryClient = useQueryClient();
	const { openComposer } = useOpenComposer();
	const itemTarget = postUriToTarget(post.uri);
	const replyAuthorDid = record.reply
		? parseCanonicalResourceUri(record.reply.parent?.uri || record.reply.root.uri).repo
		: undefined;

	const onPressReply = () => {
		openComposer({
			replyTo: {
				uri: post.uri,
				cid: post.cid,
				text: record.text,
				author: post.author,
				embed: post.embed,
				moderation,
				langs: record.langs,
			},
		});
	};

	const onBeforePress = () => {
		unstableCacheProfileView(queryClient, post.author);
	};

	const galleryOffsetStyles = maybeApplyGalleryOffsetStyles({
		additionalCauses: [],
		moderation,
		post,
	});
	return (
		<GalleryBleed>
			<BlockLink to={itemTarget} onBeforePress={onBeforePress}>
				<article className={clsx(css.outer, !hideTopBorder && css.outerBorder)} style={style}>
					<PostLayout.Row>
						<PostLayout.AvatarColumn>
							<PreviewableUserAvatar
								size={36}
								profile={post.author}
								moderation={getDisplayRestrictions(moderation, DisplayContext.ProfileMedia)}
								type={post.author.associated?.labeler ? 'labeler' : 'user'}
								tabIndex={-1}
							/>
						</PostLayout.AvatarColumn>
						<PostLayout.ContentColumn style={galleryOffsetStyles?.meta}>
							<div className={css.metaSpacing}>
								<PostMeta
									author={post.author}
									moderation={moderation}
									timestamp={post.indexedAt}
									postTarget={itemTarget}
								/>
								<PostOverflowMenuButton post={post} record={record} richText={richText} />
							</div>
							{replyAuthorDid && <PostRepliedTo parentAuthor={replyAuthorDid} className={css.repliedTo} />}
							<LabelsOnMyPost post={post} />
							<PostContent
								displayContext="view"
								moderation={moderation}
								post={post}
								richText={richText}
								embedStyle={galleryOffsetStyles?.embed}
							/>
							<PostControls post={post} onPressReply={onPressReply} />
						</PostLayout.ContentColumn>
					</PostLayout.Row>
				</article>
			</BlockLink>
		</GalleryBleed>
	);
}
