<script lang="ts">
	import { untrack } from "svelte";
	import { resolve } from "$app/paths";
	import Button from "$lib/components/ui/Button.svelte";
	import Input from "$lib/components/ui/Input.svelte";
	import Select from "$lib/components/ui/Select.svelte";
	import Toggle from "$lib/components/ui/Toggle.svelte";
	import SettingsEmpty from "$lib/components/settings/SettingsEmpty.svelte";
	import SettingsSection from "$lib/components/settings/SettingsSection.svelte";
	import SettingsBlock from "$lib/components/settings/SettingsBlock.svelte";
	import SettingsList from "$lib/components/settings/SettingsList.svelte";
	import SettingsRow from "$lib/components/settings/SettingsRow.svelte";
	import SettingsSaveBar from "$lib/components/settings/SettingsSaveBar.svelte";
	import Plus from "$icon/plus";
	import X from "$icon/x";
	import Pencil from "$icon/pencil";
	import Trash from "$icon/trash-2";

	let { data } = $props();

	const base = $derived(`/${data.repo.ownerHandle}/${data.repo.name}/settings`);
	const path = (p: string) => resolve(p as "/");

	// mocked — repo settings have no write path in the rewrite yet, so the form is
	// seeded from the repo once rather than tracking it
	const initial = {
		description: "",
		website: "",
		topics: "",
		defaultBranch: untrack(() => data.repo.defaultBranch)
	};
	let form = $state({ ...initial });
	const dirty = $derived(JSON.stringify(form) !== JSON.stringify(initial));
	const reset = () => (form = { ...initial });

	let labels = $state([
		{
			name: "documentation",
			color: "#06b6d4",
			meta: "Basic · sh.tangled.repo.issue",
			subscribed: true
		},
		{
			name: "duplicate",
			color: "#ef4444",
			meta: "Basic · sh.tangled.repo.issue",
			subscribed: true
		},
		{
			name: "good-first-issue",
			color: "#8b5cf6",
			meta: "Basic · sh.tangled.repo.issue",
			subscribed: true
		},
		{ name: "wontfix", color: "#3b82f6", meta: "Basic · sh.tangled.repo.issue", subscribed: true },
		{
			name: "assignee",
			color: "#10b981",
			meta: "string type · DID format · Multiple · sh.tangled.repo.issue, sh.tangled.repo.pull",
			subscribed: true
		}
	]);

	const unsubscribeAll = () => {
		labels = labels.map((l) => ({ ...l, subscribed: false }));
	};

	const branches = $derived([data.repo.defaultBranch, "develop", "trunk"]);
</script>

<div class="flex min-h-9 w-full items-center justify-between gap-4">
	<h1 class="typography-heading-2 text-foreground-default">General</h1>
	<SettingsSaveBar {dirty} onreset={reset} />
</div>

<div class="flex w-full flex-col gap-10">
	<!-- the leading pair of cards carries no heading in the design -->
	<div class="flex w-full flex-col gap-4">
		<SettingsList>
			<SettingsRow title="Description" stack>
				<Input
					bind:value={form.description}
					placeholder="What this project is about"
					class="w-full sm:w-80"
				/>
			</SettingsRow>
			<SettingsRow title="Website" stack>
				<Input bind:value={form.website} placeholder="URL" class="w-full sm:w-80" />
			</SettingsRow>
			<SettingsRow title="Topics" description="List of topics separated by spaces." stack>
				<Input
					bind:value={form.topics}
					placeholder="infra, social, decentralized"
					class="w-full sm:w-80"
				/>
			</SettingsRow>
		</SettingsList>

		<SettingsList>
			<SettingsRow
				title="Default branch"
				description={[
					'The default branch is considered the "base" branch in your repository, against which all pull requests and code commits are automatically made, unless you specify a different branch.'
				]}
				stack
			>
				<Select
					rich
					bind:value={form.defaultBranch}
					options={branches.map((branch) => ({ value: branch }))}
					label="Default branch"
					searchPlaceholder="Find a branch…"
					emptyLabel="No branch matches"
					class="w-full sm:w-80"
				/>
			</SettingsRow>
		</SettingsList>
	</div>

	<SettingsSection title="Labels" framed={false} headingGap="4">
		<div class="flex w-full flex-col gap-4">
			<SettingsBlock
				title="Default labels"
				titleSize="large"
				description={[
					"Manage your issues and pulls by creating labels to categorize them. Only repository owners may configure labels.",
					"You may choose to subscribe to default labels, or create entirely custom labels."
				]}
			>
				{#snippet action()}
					<Button icon={X} onclick={unsubscribeAll}>Unsubscribe all</Button>
				{/snippet}

				<SettingsList>
					{#each labels as item (item.name)}
						<SettingsRow>
							{#snippet label()}
								<span class="flex min-w-0 flex-col gap-1">
									<span class="flex items-center gap-2">
										<span
											class="size-2 shrink-0 rounded-full"
											style="background-color: {item.color}"
											aria-hidden="true"
										></span>
										<span class="typography-paragraph-regular text-foreground-default">
											{item.name}
										</span>
									</span>
									<span class="typography-paragraph-regular text-foreground-muted">
										{item.meta}
									</span>
								</span>
							{/snippet}
							<Toggle bind:checked={item.subscribed} aria-label={item.name} />
						</SettingsRow>
					{/each}
				</SettingsList>
			</SettingsBlock>

			<SettingsBlock title="Custom labels" titleSize="large">
				{#snippet action()}
					<Button icon={Plus} href={path(`${base}/labels/new`)}>Add custom label</Button>
				{/snippet}
				<SettingsEmpty message="No custom labels added yet" />
			</SettingsBlock>
		</div>
	</SettingsSection>

	<hr class="w-full border-0 border-t border-border-default" />

	<SettingsSection title="Danger zone" headingGap="4">
		<SettingsRow title="Rename">
			<Button icon={Pencil} href={path(`${base}/rename`)}>Rename repository</Button>
		</SettingsRow>
		<SettingsRow
			title="Delete"
			description="Deleting a repository is irreversible and permanent. Be certain before deleting a repository."
			stack
		>
			<Button variant="danger" icon={Trash}>Delete repository</Button>
		</SettingsRow>
	</SettingsSection>
</div>

<div class="flex w-full justify-end">
	<SettingsSaveBar {dirty} onreset={reset} />
</div>
