<script lang="ts">
	import Check from "$icon/check";
	import Copy from "$icon/copy";
	import Download from "$icon/download";
	import { hasRenderedView, hasTextView, type BlobKind, type BlobViewMode } from "$lib/api/blob";
	import { createCopyFeedback } from "$lib/copy.svelte";
	import Button from "$lib/components/ui/Button.svelte";
	import ButtonGroup from "$lib/components/ui/ButtonGroup.svelte";
	import Checkbox from "$lib/components/ui/Checkbox.svelte";
	import { LANGUAGE_COLORS, LANGUAGE_COLOR_FALLBACK } from "./language-colors";
	import RefChip from "./RefChip.svelte";
	import RepoCrumbs from "./RepoCrumbs.svelte";
	import { baseName, rawBlobHref } from "./urls";

	interface Props {
		ownerHandle: string;
		repoName: string;
		ref: string;
		path: string;
		kind: BlobKind;
		// enry language name. the blob xrpc does not expose one yet
		language?: string | null;
		sizeLabel?: string | null;
		lines?: number | null;
		view?: BlobViewMode;
		wrap?: boolean;
		showWrap?: boolean;
		copyText?: string | null;
	}

	let {
		ownerHandle,
		repoName,
		ref,
		path,
		kind,
		language = null,
		sizeLabel = null,
		lines = null,
		view = $bindable("code"),
		wrap = $bindable(false),
		showWrap = false,
		copyText = null
	}: Props = $props();

	const rawHref = $derived(rawBlobHref(ownerHandle, repoName, ref, path));
	const fileName = $derived(baseName(path));

	const showLines = $derived(lines !== null && view === "code");
	const showWrapToggle = $derived(showWrap && hasTextView(kind) && view === "code");
	const languageColor = $derived(
		language ? (LANGUAGE_COLORS[language] ?? LANGUAGE_COLOR_FALLBACK) : null
	);

	const copyFeedback = createCopyFeedback();
	const copyContents = () => {
		if (copyText !== null) void copyFeedback.copy(copyText);
	};
</script>

<div class="flex flex-wrap items-center justify-between gap-2 typography-paragraph-regular mb-2">
	<div class="flex min-w-0 items-center gap-3">
		<RepoCrumbs {ownerHandle} {repoName} {ref} {path} />

		<div class="flex items-center gap-2 text-foreground-muted">
			{#if sizeLabel}
				<span>{sizeLabel}</span>
			{/if}
			{#if sizeLabel && showLines}
				<span class="select-none" aria-hidden="true">&middot;</span>
			{/if}
			{#if showLines}
				<span>{lines} {lines === 1 ? "line" : "lines"}</span>
			{/if}
		</div>
	</div>

	<div class="flex flex-wrap items-center gap-2 whitespace-nowrap max-md:order-3 max-md:w-full">
		{#if showWrapToggle}
			<Checkbox bind:checked={wrap} class="px-2 text-foreground-muted">Wrap</Checkbox>
		{/if}
		<RefChip {ownerHandle} {repoName} {ref} />
		{#if language && languageColor}
			<div
				class="flex w-fit items-center gap-2 rounded border border-border-default bg-background-canvas px-2 py-1 whitespace-nowrap"
			>
				<div
					class="size-2 rounded-full"
					style:background="radial-gradient(circle at 35% 35%, color-mix(in srgb, {languageColor} 70%,
					white), {languageColor} 30%, color-mix(in srgb, {languageColor} 85%, black))"
				></div>
				{language}
			</div>
		{/if}
		{#if kind !== "submodule"}
			<ButtonGroup>
				{#if hasRenderedView(kind)}
					<Button size="sm" onclick={() => (view = view === "code" ? "rendered" : "code")}>
						View {view === "rendered" ? "code" : "rendered"}
					</Button>
				{/if}
				<Button size="sm" href={rawHref}>View raw</Button>
				{#if copyText !== null}
					<Button
						size="sm"
						onclick={copyContents}
						title="Copy contents"
						aria-label="Copy contents"
						icon={copyFeedback.copied !== null ? Check : Copy}
					/>
				{/if}
				<Button
					size="sm"
					href={rawHref}
					download={fileName}
					title="Download"
					aria-label="Download"
					icon={Download}
				/>
			</ButtonGroup>
		{/if}
	</div>
</div>
