1<script lang="ts">
  2	import { RemoveButton } from '$lib/components/app';
  3	import { formatFileSize, getFileTypeLabel, getPreviewText, isTextFile } from '$lib/utils';
  4	import { AttachmentType } from '$lib/enums';
  5
  6	interface Props {
  7		class?: string;
  8		id: string;
  9		onClick?: (event?: MouseEvent) => void;
 10		onRemove?: (id: string) => void;
 11		name: string;
 12		readonly?: boolean;
 13		size?: number;
 14		textContent?: string;
 15		// Either uploaded file or stored attachment
 16		uploadedFile?: ChatUploadedFile;
 17		attachment?: DatabaseMessageExtra;
 18	}
 19
 20	let {
 21		class: className = '',
 22		id,
 23		onClick,
 24		onRemove,
 25		name,
 26		readonly = false,
 27		size,
 28		textContent,
 29		uploadedFile,
 30		attachment
 31	}: Props = $props();
 32
 33	let isText = $derived(isTextFile(attachment, uploadedFile));
 34
 35	let fileTypeLabel = $derived.by(() => {
 36		if (uploadedFile?.type) {
 37			return getFileTypeLabel(uploadedFile.type);
 38		}
 39
 40		if (attachment) {
 41			if ('mimeType' in attachment && attachment.mimeType) {
 42				return getFileTypeLabel(attachment.mimeType);
 43			}
 44
 45			if (attachment.type) {
 46				return getFileTypeLabel(attachment.type);
 47			}
 48		}
 49
 50		return getFileTypeLabel(name);
 51	});
 52
 53	let pdfProcessingMode = $derived.by(() => {
 54		if (attachment?.type === AttachmentType.PDF) {
 55			const pdfAttachment = attachment as DatabaseMessageExtraPdfFile;
 56
 57			return pdfAttachment.processedAsImages ? 'Sent as Image' : 'Sent as Text';
 58		}
 59		return null;
 60	});
 61</script>
 62
 63{#if isText}
 64	{#if readonly}
 65		<!-- Readonly mode (ChatMessage) -->
 66		<button
 67			class="cursor-pointer rounded-lg border border-border bg-muted p-3 transition-shadow hover:shadow-md {className} w-full max-w-2xl"
 68			onclick={onClick}
 69			aria-label={`Preview ${name}`}
 70			type="button"
 71		>
 72			<div class="flex items-start gap-3">
 73				<div class="flex min-w-0 flex-1 flex-col items-start text-left">
 74					<span class="w-full truncate text-sm font-medium text-foreground">{name}</span>
 75
 76					{#if size}
 77						<span class="text-xs text-muted-foreground">{formatFileSize(size)}</span>
 78					{/if}
 79
 80					{#if textContent}
 81						<div class="relative mt-2 w-full">
 82							<div
 83								class="overflow-hidden font-mono text-xs leading-relaxed break-words whitespace-pre-wrap text-muted-foreground"
 84							>
 85								{getPreviewText(textContent)}
 86							</div>
 87
 88							{#if textContent.length > 150}
 89								<div
 90									class="pointer-events-none absolute right-0 bottom-0 left-0 h-6 bg-gradient-to-t from-muted to-transparent"
 91								></div>
 92							{/if}
 93						</div>
 94					{/if}
 95				</div>
 96			</div>
 97		</button>
 98	{:else}
 99		<!-- Non-readonly mode (ChatForm) -->
100		<button
101			class="group relative rounded-lg border border-border bg-muted p-3 {className} {textContent
102				? 'max-h-24 max-w-72'
103				: 'max-w-36'} cursor-pointer text-left"
104			onclick={onClick}
105		>
106			<div class="absolute top-2 right-2 opacity-0 transition-opacity group-hover:opacity-100">
107				<RemoveButton {id} {onRemove} />
108			</div>
109
110			<div class="pr-8">
111				<span class="mb-3 block truncate text-sm font-medium text-foreground">{name}</span>
112
113				{#if textContent}
114					<div class="relative">
115						<div
116							class="overflow-hidden font-mono text-xs leading-relaxed break-words whitespace-pre-wrap text-muted-foreground"
117							style="max-height: 3rem; line-height: 1.2em;"
118						>
119							{getPreviewText(textContent)}
120						</div>
121
122						{#if textContent.length > 150}
123							<div
124								class="pointer-events-none absolute right-0 bottom-0 left-0 h-4 bg-gradient-to-t from-muted to-transparent"
125							></div>
126						{/if}
127					</div>
128				{/if}
129			</div>
130		</button>
131	{/if}
132{:else}
133	<button
134		class="group flex items-center gap-3 rounded-lg border border-border bg-muted p-3 {className} relative"
135		onclick={onClick}
136	>
137		<div
138			class="flex h-8 w-8 items-center justify-center rounded bg-primary/10 text-xs font-medium text-primary"
139		>
140			{fileTypeLabel}
141		</div>
142
143		<div class="flex flex-col gap-0.5">
144			<span
145				class="max-w-24 truncate text-sm font-medium text-foreground {readonly
146					? ''
147					: 'group-hover:pr-6'} md:max-w-32"
148			>
149				{name}
150			</span>
151
152			{#if pdfProcessingMode}
153				<span class="text-left text-xs text-muted-foreground">{pdfProcessingMode}</span>
154			{:else if size}
155				<span class="text-left text-xs text-muted-foreground">{formatFileSize(size)}</span>
156			{/if}
157		</div>
158
159		{#if !readonly}
160			<div class="absolute top-2 right-2 opacity-0 transition-opacity group-hover:opacity-100">
161				<RemoveButton {id} {onRemove} />
162			</div>
163		{/if}
164	</button>
165{/if}