<script lang="ts">
	import { sendUserToast } from '$lib/utils'
	import { Button, Alert } from '$lib/components/common'
	import Label from '$lib/components/Label.svelte'
	import ClipboardPanel from '$lib/components/details/ClipboardPanel.svelte'
	import { Save, ExternalLink } from 'lucide-svelte'

	interface Props {
		serviceName: string
		serviceDisplayName: string
		existingConfig?: {
			client_id: string
			client_secret: string
			base_url: string
		} | null
		redirectUri: string
		onConfigSaved: (oauthData: any) => Promise<void>
		requiresBaseUrl?: boolean
		baseUrlLabel?: string
		baseUrlPlaceholder?: string
		baseUrlSettingsPath?: string
		clientIdPlaceholder?: string
		clientSecretPlaceholder?: string
		setupInstructions?: string[]
	}

	let {
		serviceName,
		serviceDisplayName,
		existingConfig,
		onConfigSaved,
		redirectUri,
		requiresBaseUrl = true,
		baseUrlLabel = `${serviceDisplayName} base URL`,
		baseUrlPlaceholder = `https://your-${serviceName}.example.com`,
		baseUrlSettingsPath = '/settings/admin/security',
		clientIdPlaceholder = `Generated by ${serviceDisplayName} OAuth app`,
		clientSecretPlaceholder = `Generated by ${serviceDisplayName} OAuth app`,
		setupInstructions
	}: Props = $props()

	let saving = $state(false)
	let clientId = $state('')
	let clientSecret = $state('')
	let baseUrl = $state('')
	$effect(() => {
		if (existingConfig) {
			clientId = existingConfig.client_id
			clientSecret = existingConfig.client_secret
			baseUrl = existingConfig.base_url
		}
	})

	let canSave = $derived(
		!saving &&
			!!clientId.trim() &&
			!!clientSecret.trim() &&
			(!requiresBaseUrl || !!baseUrl.trim())
	)

	async function saveConfig() {
		if (!canSave) {
			sendUserToast('Please fill in all required fields', true)
			return
		}

		saving = true
		try {
			const oauthData: Record<string, string> = {
				client_id: clientId.trim(),
				client_secret: clientSecret.trim(),
				base_url: requiresBaseUrl ? baseUrl.trim().replace(/\/+$/, '') : '',
				redirect_uri: redirectUri.trim()
			}

			await onConfigSaved(oauthData)
			resetForm()
		} catch (err: any) {
			sendUserToast(`Failed to configure OAuth client: ${err.message}`, true)
		} finally {
			saving = false
		}
	}

	function resetForm() {
		clientId = ''
		clientSecret = ''
	}


</script>

<div class="space-y-4">
	<div class="flex justify-between items-center">
		<h4 class="text-md font-medium text-primary">{serviceDisplayName} OAuth Client Configuration</h4
		>
	</div>

	{#if !existingConfig}
		<Alert type="warning" title="OAuth client required">
			<p class="text-sm mb-2">
				Before you can connect to {serviceDisplayName}, you need to configure an OAuth client.
			</p>
			{#if setupInstructions}
				<ol class="list-decimal list-inside space-y-1 text-sm">
					{#each setupInstructions as instruction}
						<li>{@html instruction}</li>
					{/each}
				</ol>
			{/if}
		</Alert>
	{/if}

	<div class="space-y-4">
		<div class="space-y-4">
			{#if requiresBaseUrl}
				<div class="flex flex-col gap-1">
					<Label label={baseUrlLabel} />
					<p class="text-xs font-normal text-secondary"
						>The base URL of your {serviceDisplayName} instance (without trailing slash)</p
					>
					<input
						type="url"
						bind:value={baseUrl}
						placeholder={baseUrlPlaceholder}
						class="windmill-input"
						disabled={saving}
					/>
					{#if baseUrl && baseUrlSettingsPath}
						<Button
							wrapperClasses="self-start"
							href={`${baseUrl}${baseUrlSettingsPath}`}
							target="_blank"
							startIcon={{ icon: ExternalLink }}
						>
							{serviceDisplayName} OAuth Settings
						</Button>
					{/if}
				</div>
			{/if}

			<div class="flex flex-col gap-1">
				<Label label="Redirect URI" />
				<p class="text-xs font-normal text-secondary"
					>Use this URL when creating the OAuth app in {serviceDisplayName}</p
				>
				<ClipboardPanel content={redirectUri} size="sm" />
			</div>

			<div class="flex flex-col gap-1">
				<Label label="Client ID" />
				<input
					type="text"
					bind:value={clientId}
					placeholder={clientIdPlaceholder}
					class="windmill-input"
					disabled={saving}
				/>
			</div>

			<div class="flex flex-col gap-1">
				<Label label="Client secret" />
				<input
					type="password"
					bind:value={clientSecret}
					placeholder={clientSecretPlaceholder}
					class="windmill-input"
					disabled={saving}
				/>
			</div>

			<div class="flex gap-2">
				<Button
					color="blue"
					onclick={saveConfig}
					disabled={!canSave}
					startIcon={{ icon: Save }}
				>
					{saving ? 'Saving...' : 'Save configuration'}
				</Button>
			</div>
		</div>
	</div>

	{#if existingConfig}
		<Alert type="success" title="OAuth client configured">
			<p class="text-sm">
				OAuth client is configured for {serviceDisplayName}. You can now connect this workspace to
				{serviceDisplayName}.
			</p>
		</Alert>
	{/if}
</div>
