<script lang="ts">
	import { Modal, Button, FormField } from '$lib/components';
	import { createTenant, updateTenant, getPiModels } from '$lib/api/admin';
	import { toast } from '$lib/stores/toast.svelte';
	import { data as appData } from '$lib/stores/data.svelte';
	import type { Tenant, Credential } from '$lib/types';

	interface Props {
		open: boolean;
		tenant: Tenant | null;
		credentials: Credential[];
		onclose: () => void;
		onsave: () => void;
	}

	let { open, tenant, credentials, onclose, onsave }: Props = $props();

	let saving = $state(false);
	let errors = $state<Record<string, string>>({});

	function validate(): boolean {
		const e: Record<string, string> = {};
		if (isCreate() && !id.trim()) e.id = 'ID is required';
		else if (isCreate() && !/^[a-z][a-z0-9_-]*$/.test(id)) e.id = 'Lowercase letters, numbers, hyphens and underscores only';
		if (!name.trim()) e.name = 'Name is required';
		errors = e;
		return Object.keys(e).length === 0;
	}

	function isCreate() {
		return tenant === null;
	}

	function modalTitle() {
		return isCreate() ? 'Create Tenant' : `Edit Tenant: ${tenant?.id ?? ''}`;
	}

	// Form fields
	let id = $state('');
	let name = $state('');
	let email = $state('');
	let autoName = $state('');
	let autoEmail = $state('');
	// '' => inherit global default provider
	let provider = $state<'' | 'claude' | 'codex' | 'pi'>('');
	let pi_backend = $state('');
	// Pi model registry
	let piProviders = $state<{ id: string; label: string; modelCount: number }[]>([]);
	let piModelsByProvider = $state<Record<string, { id: string; name: string }[]>>({});
	let loadingPiModels = $state(false);
	let discord_user_id = $state('');
	let tenant_type = $state<'standard' | 'bot'>('standard');
	let discord_bot_token = $state('');
	let max_memory_mb = $state(4096);
	let cpu_quota = $state('200%');
	let cpu_weight = $state(100);
	let max_disk_mb = $state(4096);
	let max_concurrent = $state(1);
	let daily_requests = $state<number | ''>('');
	let daily_duration_mins = $state<number | ''>('');
	let status = $state<'active' | 'suspended' | 'archived'>('active');
	let credential_id = $state('');
	let model = $state('');
	let is_admin = $state(false);
	let show_progress_messages = $state(false);
	let provision_discord = $state(true);

	const effectiveProvider = $derived.by(() => provider || appData.settings?.default_provider || 'codex');

	$effect(() => {
		if ((provider === 'pi' || (!provider && appData.settings?.default_provider === 'pi')) && piProviders.length === 0 && !loadingPiModels) {
			loadingPiModels = true;
			getPiModels().then(result => {
				piProviders = result.providers;
				piModelsByProvider = result.models;
				loadingPiModels = false;
			}).catch(() => { loadingPiModels = false; });
		}
	});

	$effect(() => {
		if (isCreate() && id && !tenant) {
			const titleCase = id
				.split(/[-_]/)
				.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
				.join(' ');
			const suggestedEmail = `${id}@fireping.net`;

			if (!name || name === autoName) {
				name = titleCase;
				autoName = titleCase;
			} else {
				autoName = titleCase;
			}

			if (!email || email === autoEmail) {
				email = suggestedEmail;
				autoEmail = suggestedEmail;
			} else {
				autoEmail = suggestedEmail;
			}
		}
	});

	$effect(() => {
		if (open) {
			errors = {};
			if (tenant) {
				id = tenant.id;
				name = tenant.name;
				email = tenant.email ?? '';
				provider = (tenant.provider ?? '') as any;
				pi_backend = tenant.pi_backend ?? '';
				discord_user_id = tenant.discord_user_id ?? '';
				tenant_type = tenant.tenant_type ?? 'standard';
				discord_bot_token = tenant.discord_bot_token ?? '';
				max_memory_mb = tenant.max_memory_mb;
				cpu_quota = tenant.cpu_quota;
				cpu_weight = tenant.cpu_weight;
				max_disk_mb = tenant.max_disk_mb;
				max_concurrent = tenant.max_concurrent;
				daily_requests = tenant.daily_usage?.limit_requests ?? '';
				daily_duration_mins = tenant.daily_usage?.limit_duration_ms
					? Math.round(tenant.daily_usage.limit_duration_ms / 60000)
					: '';
				status = tenant.status;
				credential_id = tenant.credential_id ?? '';
				model = tenant.model ?? '';
				is_admin = !!tenant.is_admin;
				show_progress_messages = !!tenant.show_progress_messages;
				provision_discord = true;
			} else {
				id = '';
				name = '';
				email = '';
				provider = '';
				pi_backend = '';
				discord_user_id = '';
				tenant_type = 'standard';
				discord_bot_token = '';
				max_memory_mb = 4096;
				cpu_quota = '200%';
				cpu_weight = 100;
				max_disk_mb = 4096;
				max_concurrent = 1;
				daily_requests = '';
				daily_duration_mins = '';
				status = 'active';
				credential_id = '';
				model = '';
				is_admin = false;
				show_progress_messages = false;
				provision_discord = true;
			}
		}
	});

	async function handleSave() {
		if (!validate()) return;
		saving = true;
		try {
			const data: Record<string, any> = {
				name,
				email: email || undefined,
				discord_user_id: discord_user_id || undefined,
				tenant_type,
				max_memory_mb,
				cpu_quota,
				cpu_weight,
				max_disk_mb,
				max_concurrent,
				status,
				is_admin: is_admin ? 1 : 0,
				show_progress_messages: show_progress_messages ? 1 : 0,
				credential_id: credential_id || undefined,
				model: model || undefined,
				pi_backend: pi_backend || undefined,
			};

			// Provider: allow inheriting the global default (unset for create; null to clear on update).
			if (isCreate()) {
				if (provider) data.provider = provider;
			} else {
				data.provider = provider ? provider : null;
			}

			if (tenant_type === 'bot') {
				data.discord_bot_token = discord_bot_token || undefined;
			}

			if (daily_requests !== '') {
				data.daily_requests = Number(daily_requests);
			}
			if (daily_duration_mins !== '') {
				data.daily_duration_mins = Number(daily_duration_mins);
			}

			if (isCreate()) {
				data.id = id;
				data.provision_discord = provision_discord;
				const result = await createTenant(data as any);
				toast.success(result.message);
				if (result.inviteUrl) {
					toast.info(`Discord invite: ${result.inviteUrl}`);
				}
			} else {
				await updateTenant(tenant!.id, data as any);
				toast.success(`Tenant ${tenant!.id} updated`);
			}

			await onsave();
			onclose();
		} catch (err: any) {
			toast.error(err.message ?? 'Failed to save tenant');
		} finally {
			saving = false;
		}
	}
</script>

<Modal {open} title={modalTitle()} width="620px" {onclose}>
	{#snippet children()}
		<form onsubmit={(e) => { e.preventDefault(); handleSave(); }} id="tenant-form">
			<section class="section">
				<h4 class="section-title">Identity</h4>
				<div class="fields">
					{#if isCreate()}
						<FormField label="ID" required error={errors.id} hint={errors.id ? undefined : "Lowercase, alphanumeric, used as Linux user and folder name"}>
							<input type="text" bind:value={id} placeholder="my-tenant" oninput={() => { if (errors.id) validate(); }} />
						</FormField>
					{/if}
					<FormField label="Name" required error={errors.name}>
						<input type="text" bind:value={name} placeholder="Display name" oninput={() => { if (errors.name) validate(); }} />
					</FormField>
					<FormField label="Email">
						<input type="email" bind:value={email} placeholder="contact@example.com" />
					</FormField>
					<FormField label="Provider">
						<select bind:value={provider}>
							<option value="">Default (global)</option>
							<option value="claude">Claude</option>
							<option value="codex">Codex</option>
							<option value="pi">Pi</option>
						</select>
						{#if provider === 'pi' || (!provider && appData.settings?.default_provider === 'pi')}
							{#if loadingPiModels}
								<span class="hint">Loading backends...</span>
							{:else}
							<select bind:value={pi_backend}>
								<option value="">Default ({appData.settings?.default_pi_backend ?? 'anthropic'})</option>
								{#each piProviders as p}
									<option value={p.id}>{p.label} ({p.modelCount} models)</option>
								{/each}
							</select>
							{/if}
						{/if}
						{#if !provider}
							<div class="hint">Effective: <span class="mono">{effectiveProvider}</span></div>
						{/if}
					</FormField>
					<FormField label="Discord User ID">
						<input type="text" bind:value={discord_user_id} placeholder="123456789012345678" />
					</FormField>
				</div>
			</section>

			<section class="section">
				<h4 class="section-title">Type</h4>
				<div class="fields">
					<FormField label="Tenant Type">
						<select bind:value={tenant_type}>
							<option value="standard">Standard</option>
							<option value="bot">Bot</option>
						</select>
					</FormField>
					{#if tenant_type === 'bot'}
						<FormField label="Discord Bot Token" hint="Own Discord application token for bot tenants">
							<input type="password" bind:value={discord_bot_token} placeholder="Bot token..." />
						</FormField>
					{/if}
				</div>
			</section>

			<section class="section">
				<h4 class="section-title">Resources</h4>
				<div class="fields grid-2">
					<FormField label="Memory (MB)">
						<input type="number" bind:value={max_memory_mb} min="128" step="128" />
					</FormField>
					<FormField label="CPU Quota">
						<input type="text" bind:value={cpu_quota} placeholder="50%" />
					</FormField>
					<FormField label="CPU Weight">
						<input type="number" bind:value={cpu_weight} min="1" max="1000" />
					</FormField>
					<FormField label="Disk (MB)">
						<input type="number" bind:value={max_disk_mb} min="128" step="128" />
					</FormField>
					<FormField label="Max Concurrent">
						<input type="number" bind:value={max_concurrent} min="1" max="10" />
					</FormField>
				</div>
			</section>

			<section class="section">
				<h4 class="section-title">Limits</h4>
				<div class="fields grid-2">
					<FormField label="Daily Requests" hint="Leave empty for unlimited">
						<input type="number" bind:value={daily_requests} min="0" placeholder="Unlimited" />
					</FormField>
					<FormField label="Daily Duration (mins)" hint="Leave empty for unlimited">
						<input type="number" bind:value={daily_duration_mins} min="0" placeholder="Unlimited" />
					</FormField>
				</div>
			</section>

			<section class="section">
				<h4 class="section-title">Settings</h4>
				<div class="fields">
					<FormField label="Status">
						<select bind:value={status}>
							<option value="active">Active</option>
							<option value="suspended">Suspended</option>
							<option value="archived">Archived</option>
						</select>
					</FormField>
					<FormField label="Credential">
						<select bind:value={credential_id}>
							<option value="">Pool (auto)</option>
							{#each credentials.filter((cred) => (cred.provider ?? 'claude') === effectiveProvider) as cred}
								<option value={cred.id}>{cred.id} ({cred.type}{cred.label ? ` - ${cred.label}` : ''})</option>
							{/each}
						</select>
					</FormField>
					<FormField label="Model">
						{#if effectiveProvider === 'pi' && piProviders.length > 0}
							<select bind:value={model}>
								<option value="">Default for backend</option>
								{#each (piModelsByProvider[pi_backend || (appData.settings?.default_pi_backend ?? 'anthropic')] ?? []) as m}
									<option value={m.id}>{m.name}</option>
								{/each}
							</select>
						{:else}
							<input
								type="text"
								bind:value={model}
								placeholder={effectiveProvider === 'codex' ? 'gpt-5.4' : effectiveProvider === 'pi' ? 'Loading...' : 'claude-sonnet-4-6'}
							/>
						{/if}
					</FormField>
					<label class="checkbox-row">
						<input type="checkbox" bind:checked={is_admin} />
						<span>Admin tenant</span>
					</label>
					<label class="checkbox-row">
						<input type="checkbox" bind:checked={show_progress_messages} />
						<span>Show progress messages</span>
					</label>
				</div>
			</section>

			{#if isCreate()}
				<section class="section">
					<h4 class="section-title">Discord</h4>
					<div class="fields">
						<label class="checkbox-row">
							<input type="checkbox" bind:checked={provision_discord} />
							<span>Provision Discord category and channel</span>
						</label>
					</div>
				</section>
			{/if}
		</form>
	{/snippet}

	{#snippet footer()}
		<Button variant="ghost" onclick={onclose}>Cancel</Button>
		<Button variant="primary" loading={saving} type="submit" form="tenant-form">
			{isCreate() ? 'Create Tenant' : 'Save Changes'}
		</Button>
	{/snippet}
</Modal>

<style>
	.section {
		margin-bottom: 20px;
	}
	.section:last-child {
		margin-bottom: 0;
	}
	.section-title {
		font-size: var(--font-size-sm);
		font-weight: 600;
		color: var(--text-bright);
		margin-bottom: 10px;
		text-transform: uppercase;
		letter-spacing: 0.05em;
	}
	.fields {
		display: flex;
		flex-direction: column;
		gap: 12px;
	}
	.grid-2 {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 12px;
	}
	.checkbox-row {
		display: flex;
		align-items: center;
		gap: 8px;
		cursor: pointer;
		font-size: var(--font-size-sm);
		color: var(--text);
	}
	.checkbox-row input[type='checkbox'] {
		accent-color: var(--accent);
	}
	.hint {
		margin-top: 6px;
		font-size: var(--font-size-xs);
		color: var(--text-dim);
	}
	.mono { font-family: var(--font-mono); }
</style>
