import { useState } from 'react';

import type { ComAtprotoLabelDefs } from '@atcute/atproto';

import { useConstant } from '#/lib/hooks/use-constant';
import { profileTarget } from '#/lib/routes/targets';

import { useLabelInfo } from '#/state/moderation/use-label-info';
import { useSession } from '#/state/session';

import { relativeMessageParts } from '#/locale/intl/timeAgo';
import { Trans } from '#/locale/Trans';

import * as Dialog from '#/components/Dialog';
import { AppealForm } from '#/components/moderation/AppealForm';
import { Stack } from '#/components/Stack';
import { Text } from '#/components/Text';
import { Button, ButtonText } from '#/components/web/Button';
import { InlineLinkText } from '#/components/web/Link';

import { m } from '#/paraglide/messages';

import * as styles from './LabelsOnMeDialog.css';

export interface LabelsOnMeDialogProps {
	handle: Dialog.DialogHandle;
	labels: ComAtprotoLabelDefs.Label[];
	type: 'account' | 'content';
}

export function LabelsOnMeDialog(props: LabelsOnMeDialogProps) {
	return (
		<Dialog.Root handle={props.handle}>
			<Dialog.Popup size="wide">
				<LabelsOnMeDialogInner {...props} />
			</Dialog.Popup>
		</Dialog.Root>
	);
}

function LabelsOnMeDialogInner({ handle, labels, type }: LabelsOnMeDialogProps) {
	const { currentAccount } = useSession();
	const [appealingLabel, setAppealingLabel] = useState<ComAtprotoLabelDefs.Label | undefined>(undefined);
	const isAccount = type === 'account';
	const containsSelfLabel = labels.some((label) => label.src === currentAccount?.did);

	if (appealingLabel) {
		return (
			<AppealForm handle={handle} label={appealingLabel} onPressBack={() => setAppealingLabel(undefined)} />
		);
	}

	return (
		<Stack gap="lg">
			<Stack gap="xs">
				<Dialog.TitleRow>
					<Dialog.Title>
						{isAccount
							? m['components.moderation.label.titleAccount']()
							: m['components.moderation.label.titleContent']()}
					</Dialog.Title>
					<Dialog.Close />
				</Dialog.TitleRow>
				<Text color="textContrastMedium">
					{containsSelfLabel
						? m['components.moderation.appeal.nonSelfHint']()
						: m['components.moderation.appeal.theseLabelsHint']()}
				</Text>
			</Stack>

			<Stack gap="md">
				{labels.map((label) => (
					<Label
						key={`${label.val}-${label.src}`}
						handle={handle}
						isSelfLabel={label.src === currentAccount?.did}
						label={label}
						onPressAppeal={setAppealingLabel}
					/>
				))}
			</Stack>
		</Stack>
	);
}

function Label({
	handle,
	isSelfLabel,
	label,
	onPressAppeal,
}: {
	handle: Dialog.DialogHandle;
	isSelfLabel: boolean;
	label: ComAtprotoLabelDefs.Label;
	onPressAppeal: (label: ComAtprotoLabelDefs.Label) => void;
}) {
	const { labeler, strings } = useLabelInfo(label);
	const sourceName = labeler ? `@${labeler.creator.handle}` : label.src;
	const now = useConstant(Date.now);

	return (
		<div className={styles.card}>
			<div className={styles.cardTop}>
				<div className={styles.cardInfo}>
					<Text size="md" weight="semiBold">
						{strings.name}
					</Text>
					<Text color="textContrastMedium">{strings.description}</Text>
				</div>
				{!isSelfLabel && (
					<Button
						color="secondary"
						label={m['components.moderation.appeal.action']()}
						onClick={() => onPressAppeal(label)}
						size="small"
						variant="solid"
					>
						<ButtonText>{m['components.moderation.appeal.action']()}</ButtonText>
					</Button>
				)}
			</div>

			<Dialog.Divider />

			<div className={styles.band}>
				{isSelfLabel ? (
					<Text color="textContrastMedium">{m['components.moderation.label.appliedByYou']()}</Text>
				) : (
					<div className={styles.sourceRow}>
						<Text className={styles.sourceText} color="textContrastMedium" numberOfLines={1}>
							<Trans
								message={m['common.moderation.source']}
								inputs={{ source: sourceName }}
								markup={{
									t0: ({ children }) => (
										<InlineLinkText
											label={sourceName}
											onPress={() => handle.close()}
											to={profileTarget(labeler ? labeler.creator.did : label.src)}
										>
											{children}
										</InlineLinkText>
									),
								}}
							/>
						</Text>
						{label.exp && (
							<Text className={styles.expires} color="textContrastMedium" size="sm">
								{m['common.mutedWord.expires'](relativeMessageParts(label.exp, now))}
							</Text>
						)}
					</div>
				)}
			</div>
		</div>
	);
}
