<script lang="ts">
	import { SvelteDate } from 'svelte/reactivity';
	import { apiFetch } from '$lib/utils/api';
	import { toast } from 'svelte-sonner';
	import { Button } from '$lib/components/ui/button';
	import * as Card from '$lib/components/ui/card';
	import { Input } from '$lib/components/ui/input';
	import * as Label from '$lib/components/ui/label';
	import * as Textarea from '$lib/components/ui/textarea';
	import { Skeleton } from '$lib/components/ui/skeleton';
	import * as Modal from '$lib/components/ui/dialog';
	import StatusBadge from '$lib/components/ui/StatusBadge.svelte';

	type Campaign = {
		id: string;
		name: string;
		description: string;
		campaign_type: 'time_based' | 'milestone';
		discount_percent: number;
		scope: string;
		start_date: string;
		end_date: string;
		milestone_type: string;
		milestone_value: number;
		milestone_unit: string;
		status: 'draft' | 'active' | 'completed' | 'cancelled';
		max_redemptions: number;
		times_redeemed: number;
		created_at: string;
		updated_at: string;
	};

	type CampaignStats = {
		campaign: Campaign;
		total_discount_amount: number;
		booking_count: number;
	};

	const MILESTONE_UNIT_MAP: Record<string, string[]> = {
		per_user_booking_count: ['bookings'],
		global_booking_count: ['bookings'],
		anniversary: ['months', 'years']
	};

	const MILESTONE_LABELS: Record<string, string> = {
		per_user_booking_count: 'Per-user bookings',
		global_booking_count: 'Global bookings',
		anniversary: 'Anniversary'
	};

	let campaigns = $state<Campaign[]>([]);
	let loading = $state(true);
	let actionInProgress = $state<string | null>(null);

	let showModal = $state(false);
	let showStatsModal = $state(false);
	let submitting = $state(false);
	let statsLoading = $state(false);

	let editingCampaign = $state<Campaign | null>(null);
	let statsData = $state<CampaignStats | null>(null);

	let form = $state({
		name: '',
		description: '',
		campaign_type: 'time_based' as 'time_based' | 'milestone',
		discount_percent: 5,
		scope: 'all_bookings',
		start_date: '',
		end_date: '',
		milestone_type: 'per_user_booking_count',
		milestone_value: 0,
		milestone_unit: 'bookings',
		max_redemptions: 0
	});

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

	$effect(() => {
		if (form.milestone_type in MILESTONE_UNIT_MAP) {
			const allowed = MILESTONE_UNIT_MAP[form.milestone_type];
			if (!allowed.includes(form.milestone_unit)) {
				form.milestone_unit = allowed[0];
			}
		}
	});

	const isFormValid = $derived.by(() => {
		if (!form.name.trim()) return false;
		if (form.discount_percent <= 0 || form.discount_percent > 100) return false;
		if (form.campaign_type === 'time_based') {
			if (!form.start_date || !form.end_date) return false;
			if (new SvelteDate(form.end_date) < new SvelteDate(form.start_date)) return false;
		}
		if (form.campaign_type === 'milestone') {
			if (form.milestone_value <= 0) return false;
		}
		return true;
	});

	async function loadCampaigns() {
		loading = true;
		try {
			const res = await apiFetch('/api/admin/discount-campaigns');
			if (res.ok) campaigns = await res.json();
			else toast.error('Failed to load campaigns');
		} catch {
			toast.error('Failed to load campaigns');
		} finally {
			loading = false;
		}
	}

	function openCreateModal() {
		editingCampaign = null;
		form = {
			name: '',
			description: '',
			campaign_type: 'time_based',
			discount_percent: 5,
			scope: 'all_bookings',
			start_date: '',
			end_date: '',
			milestone_type: 'per_user_booking_count',
			milestone_value: 0,
			milestone_unit: 'bookings',
			max_redemptions: 0
		};
		errors = {};
		showModal = true;
	}

	async function submitForm() {
		errors = {};
		if (!form.name.trim()) errors.name = 'Required';
		if (form.discount_percent <= 0) errors.discount_percent = 'Must be > 0';
		if (form.discount_percent > 100) errors.discount_percent = 'Max 100';
		if (form.campaign_type === 'time_based') {
			if (!form.start_date) errors.start_date = 'Required';
			if (!form.end_date) errors.end_date = 'Required';
			if (form.start_date && form.end_date && new Date(form.end_date) < new Date(form.start_date)) {
				errors.end_date = 'Must be after start';
			}
		}
		if (form.campaign_type === 'milestone' && form.milestone_value <= 0) {
			errors.milestone_value = 'Must be > 0';
		}
		if (Object.keys(errors).length > 0) return;

		submitting = true;
		try {
			const payload: Record<string, unknown> = {
				name: form.name.trim(),
				description: form.description.trim() || undefined,
				campaign_type: form.campaign_type,
				discount_percent: form.discount_percent
			};
			if (form.campaign_type === 'time_based') {
				payload.scope = form.scope;
				payload.start_date = form.start_date + 'T00:00:00.000Z';
				payload.end_date = form.end_date + 'T23:59:59.999Z';
			} else {
				payload.milestone_type = form.milestone_type;
				payload.milestone_value = form.milestone_value;
				payload.milestone_unit = form.milestone_unit;
			}
			if (form.max_redemptions > 0) payload.max_redemptions = form.max_redemptions;

			const url = editingCampaign
				? `/api/admin/discount-campaigns/${editingCampaign.id}`
				: '/api/admin/discount-campaigns';
			const method = editingCampaign ? 'PUT' : 'POST';

			const res = await apiFetch(url, {
				method,
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify(payload)
			});

			if (res.ok) {
				toast.success(editingCampaign ? 'Campaign updated' : 'Campaign created');
				showModal = false;
				await loadCampaigns();
			} else {
				const text = await res.text();
				toast.error(text || 'Failed to save campaign');
			}
		} catch {
			toast.error('Failed to save campaign');
		} finally {
			submitting = false;
		}
	}

	async function updateStatus(c: Campaign, status: string) {
		actionInProgress = c.id;
		try {
			const res = await apiFetch(`/api/admin/discount-campaigns/${c.id}`, {
				method: 'PUT',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({ status })
			});
			if (res.ok) {
				toast.success(`Campaign ${status}`);
				await loadCampaigns();
			} else toast.error('Failed to update status');
		} catch {
			toast.error('Failed to update status');
		} finally {
			actionInProgress = null;
		}
	}

	async function cancelCampaign(c: Campaign) {
		actionInProgress = c.id;
		try {
			const res = await apiFetch(`/api/admin/discount-campaigns/${c.id}`, {
				method: 'DELETE'
			});
			if (res.ok) {
				toast.success('Campaign cancelled');
				await loadCampaigns();
			} else toast.error('Failed to cancel campaign');
		} catch {
			toast.error('Failed to cancel campaign');
		} finally {
			actionInProgress = null;
		}
	}

	async function viewStats(c: Campaign) {
		statsLoading = true;
		showStatsModal = true;
		try {
			const res = await apiFetch(`/api/admin/discount-campaigns/${c.id}/stats`);
			if (res.ok) statsData = await res.json();
			else toast.error('Failed to load stats');
		} catch {
			toast.error('Failed to load stats');
		} finally {
			statsLoading = false;
		}
	}

	function typeLabel(c: Campaign): string {
		if (c.campaign_type === 'time_based') return 'Time-based';
		return MILESTONE_LABELS[c.milestone_type] || c.milestone_type;
	}

	function redemptionDisplay(c: Campaign): string {
		const max = c.max_redemptions > 0 ? `/${c.max_redemptions}` : '/∞';
		return `${c.times_redeemed}${max}`;
	}

	$effect(() => {
		loadCampaigns();
	});
</script>

<Card.Root>
	<Card.Header>
		<div class="flex w-full flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
			<div>
				<Card.Title>Discount Campaigns</Card.Title>
				<Card.Description>Manage loyalty discounts, sales, and milestone campaigns</Card.Description
				>
			</div>
			<Button onclick={openCreateModal} class="w-full sm:w-auto">Create Campaign</Button>
		</div>
	</Card.Header>
	<Card.Content>
		{#if loading}
			<div class="space-y-3">
				{#each Array(3) as _, i (i)}
					<Skeleton class="h-16 w-full" />
				{/each}
			</div>
		{:else if campaigns.length === 0}
			<div class="py-8 text-center text-sm text-gray-500">
				No campaigns yet. Create one to get started.
			</div>
		{:else}
			<!-- Desktop table -->
			<div class="hidden w-full overflow-x-auto md:block">
				<table class="w-full table-auto border-collapse text-sm">
					<thead>
						<tr class="border-b text-left text-xs text-gray-500">
							<th class="py-3">Name</th>
							<th class="py-3">Type</th>
							<th class="py-3">Discount</th>
							<th class="py-3">Status</th>
							<th class="py-3">Redeemed</th>
							<th class="py-3 text-right">Actions</th>
						</tr>
					</thead>
					<tbody>
						{#each campaigns as c (c.id)}
							<tr class="border-b">
								<td class="py-3 font-medium">{c.name}</td>
								<td class="py-3 text-gray-600">{typeLabel(c)}</td>
								<td class="py-3">{c.discount_percent}%</td>
								<td class="py-3"><StatusBadge status={c.status} /></td>
								<td class="py-3 text-gray-600">{redemptionDisplay(c)}</td>
								<td class="py-3">
									<div class="flex justify-end gap-1">
										{#if c.status === 'draft'}
											<Button
												size="sm"
												variant="outline"
												disabled={actionInProgress === c.id}
												onclick={() => updateStatus(c, 'active')}
											>
												Activate
											</Button>
										{/if}
										{#if c.status === 'active'}
											<Button
												size="sm"
												variant="outline"
												disabled={actionInProgress === c.id}
												onclick={() => updateStatus(c, 'completed')}
											>
												Complete
											</Button>
										{/if}
										{#if c.status !== 'cancelled'}
											<Button
												size="sm"
												variant="destructive"
												disabled={actionInProgress === c.id}
												onclick={() => cancelCampaign(c)}
											>
												Cancel
											</Button>
										{/if}
										{#if c.status === 'active' || c.status === 'completed'}
											<Button size="sm" variant="ghost" onclick={() => viewStats(c)}>Stats</Button>
										{/if}
									</div>
								</td>
							</tr>
						{/each}
					</tbody>
				</table>
			</div>

			<!-- Mobile cards -->
			<div class="space-y-3 md:hidden">
				{#each campaigns as c (c.id)}
					<div class="rounded-lg border p-4">
						<div class="mb-2 flex items-start justify-between">
							<div class="font-medium">{c.name}</div>
							<StatusBadge status={c.status} />
						</div>
						<div class="mb-3 grid grid-cols-2 gap-2 text-xs text-gray-600">
							<div>Type: {typeLabel(c)}</div>
							<div>Discount: {c.discount_percent}%</div>
							<div>Redeemed: {redemptionDisplay(c)}</div>
						</div>
						<div class="flex flex-wrap gap-2">
							{#if c.status === 'draft'}
								<Button
									size="sm"
									variant="outline"
									disabled={actionInProgress === c.id}
									onclick={() => updateStatus(c, 'active')}
								>
									Activate
								</Button>
							{/if}
							{#if c.status === 'active'}
								<Button
									size="sm"
									variant="outline"
									disabled={actionInProgress === c.id}
									onclick={() => updateStatus(c, 'completed')}
								>
									Complete
								</Button>
							{/if}
							{#if c.status !== 'cancelled'}
								<Button
									size="sm"
									variant="destructive"
									disabled={actionInProgress === c.id}
									onclick={() => cancelCampaign(c)}
								>
									Cancel
								</Button>
							{/if}
							{#if c.status === 'active' || c.status === 'completed'}
								<Button size="sm" variant="ghost" onclick={() => viewStats(c)}>Stats</Button>
							{/if}
						</div>
					</div>
				{/each}
			</div>
		{/if}
	</Card.Content>
</Card.Root>

<!-- Create/Edit Modal -->
<Modal.Root bind:open={showModal}>
	<Modal.Content class="max-h-[90vh] max-w-sm overflow-y-auto md:max-w-lg">
		<Modal.Header>
			<Modal.Title>{editingCampaign ? 'Edit Campaign' : 'Create Campaign'}</Modal.Title>
			<Modal.Description>Configure discount rules and campaign parameters</Modal.Description>
		</Modal.Header>

		<div class="space-y-4 py-4">
			<!-- Name -->
			<div class="space-y-2">
				<Label.Root for="dc-name">Name *</Label.Root>
				<Input id="dc-name" bind:value={form.name} placeholder="e.g. Easter Sale" />
				{#if errors.name}<p class="text-xs text-red-500">{errors.name}</p>{/if}
			</div>

			<!-- Description -->
			<div class="space-y-2">
				<Label.Root for="dc-desc">Description</Label.Root>
				<Textarea.Root
					id="dc-desc"
					bind:value={form.description}
					placeholder="Optional notes"
					rows={2}
				/>
			</div>

			<!-- Campaign Type -->
			<div class="space-y-2">
				<Label.Root>Campaign Type *</Label.Root>
				<div class="flex gap-2">
					<button
						type="button"
						class="flex-1 rounded-md border px-3 py-2 text-sm transition-colors {form.campaign_type ===
						'time_based'
							? 'border-emerald-500 bg-emerald-50 text-emerald-700'
							: 'hover:bg-gray-50'}"
						onclick={() => {
							form.campaign_type = 'time_based';
						}}
					>
						Time-based
					</button>
					<button
						type="button"
						class="flex-1 rounded-md border px-3 py-2 text-sm transition-colors {form.campaign_type ===
						'milestone'
							? 'border-emerald-500 bg-emerald-50 text-emerald-700'
							: 'hover:bg-gray-50'}"
						onclick={() => {
							form.campaign_type = 'milestone';
						}}
					>
						Milestone
					</button>
				</div>
			</div>

			<!-- Discount Percent -->
			<div class="space-y-2">
				<Label.Root for="dc-pct">Discount Percent *</Label.Root>
				<div class="flex items-center gap-2">
					<Input
						id="dc-pct"
						type="number"
						inputmode="numeric"
						min="1"
						max="100"
						bind:value={form.discount_percent}
						class="w-24"
					/>
					<span class="text-sm text-gray-500">%</span>
				</div>
				{#if errors.discount_percent}<p class="text-xs text-red-500">
						{errors.discount_percent}
					</p>{/if}
			</div>

			<!-- Time-based fields -->
			{#if form.campaign_type === 'time_based'}
				<div class="space-y-3 rounded-lg border p-3">
					<p class="text-xs font-medium text-gray-500">TIME-BASED SETTINGS</p>

					<!-- Scope -->
					<div class="space-y-2">
						<Label.Root for="dc-scope">Scope</Label.Root>
						<select
							id="dc-scope"
							bind:value={form.scope}
							class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs ring-offset-background transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
						>
							<option value="all_bookings">All bookings</option>
							<option value="first_booking_only">First booking only</option>
							<option value="new_customers_only">New customers only</option>
						</select>
					</div>

					<!-- Dates -->
					<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
						<div class="space-y-2">
							<Label.Root for="dc-start">Start Date *</Label.Root>
							<Input id="dc-start" type="date" bind:value={form.start_date} />
							{#if errors.start_date}<p class="text-xs text-red-500">{errors.start_date}</p>{/if}
						</div>
						<div class="space-y-2">
							<Label.Root for="dc-end">End Date *</Label.Root>
							<Input id="dc-end" type="date" bind:value={form.end_date} />
							{#if errors.end_date}<p class="text-xs text-red-500">{errors.end_date}</p>{/if}
						</div>
					</div>
				</div>
			{/if}

			<!-- Milestone fields -->
			{#if form.campaign_type === 'milestone'}
				<div class="space-y-3 rounded-lg border p-3">
					<p class="text-xs font-medium text-gray-500">MILESTONE SETTINGS</p>

					<!-- Milestone Type -->
					<div class="space-y-2">
						<Label.Root for="dc-ms-type">Milestone Type *</Label.Root>
						<select
							id="dc-ms-type"
							bind:value={form.milestone_type}
							class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs ring-offset-background transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
						>
							<option value="per_user_booking_count">Per-user booking count</option>
							<option value="global_booking_count">Global booking count</option>
							<option value="anniversary">Anniversary</option>
						</select>
					</div>

					<!-- Milestone Value + Unit -->
					<div class="grid grid-cols-2 gap-3">
						<div class="space-y-2">
							<Label.Root for="dc-ms-val">Value *</Label.Root>
							<Input
								id="dc-ms-val"
								type="number"
								inputmode="numeric"
								min="1"
								bind:value={form.milestone_value}
							/>
							{#if errors.milestone_value}<p class="text-xs text-red-500">
									{errors.milestone_value}
								</p>{/if}
						</div>
						<div class="space-y-2">
							<Label.Root for="dc-ms-unit">Unit</Label.Root>
							{#if form.milestone_type === 'anniversary'}
								<select
									id="dc-ms-unit"
									bind:value={form.milestone_unit}
									class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-xs ring-offset-background transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
								>
									<option value="months">Months</option>
									<option value="years">Years</option>
								</select>
							{:else}
								<Input id="dc-ms-unit" value="bookings" disabled class="bg-gray-50" />
							{/if}
						</div>
					</div>

					<p class="text-xs text-gray-500">
						{#if form.milestone_type === 'per_user_booking_count'}
							Discount applies when a user completes their {form.milestone_value}th booking
						{:else if form.milestone_type === 'global_booking_count'}
							Discount applies on the {form.milestone_value}th completed booking across all users
						{:else}
							Discount applies on a user's first booking after {form.milestone_value}
							{form.milestone_unit} since their first visit
						{/if}
					</p>
				</div>
			{/if}

			<!-- Max Redemptions -->
			<div class="space-y-2">
				<Label.Root for="dc-max">Max Redemptions (campaign total)</Label.Root>
				<Input
					id="dc-max"
					type="number"
					inputmode="numeric"
					min="0"
					bind:value={form.max_redemptions}
					class="w-32"
				/>
				<p class="text-xs text-gray-500">0 = unlimited across all users</p>
			</div>
		</div>

		<Modal.Footer>
			<Button
				variant="outline"
				onclick={() => {
					showModal = false;
				}}>Cancel</Button
			>
			<Button onclick={submitForm} disabled={!isFormValid || submitting}>
				{submitting ? 'Saving...' : editingCampaign ? 'Update' : 'Create'}
			</Button>
		</Modal.Footer>
	</Modal.Content>
</Modal.Root>

<!-- Stats Modal -->
<Modal.Root bind:open={showStatsModal}>
	<Modal.Content class="sm:max-w-sm">
		<Modal.Header>
			<Modal.Title>Campaign Stats</Modal.Title>
		</Modal.Header>
		{#if statsLoading}
			<div class="space-y-3 py-4">
				<Skeleton class="h-12 w-full" />
				<Skeleton class="h-12 w-full" />
			</div>
		{:else if statsData}
			<div class="space-y-4 py-4">
				<div class="rounded-lg bg-gray-50 p-4 text-center">
					<p class="text-sm text-gray-500">Total Discount Given</p>
					<p class="text-2xl font-bold text-emerald-600">
						£{statsData.total_discount_amount.toFixed(2)}
					</p>
				</div>
				<div class="rounded-lg bg-gray-50 p-4 text-center">
					<p class="text-sm text-gray-500">Bookings Discounted</p>
					<p class="text-2xl font-bold">{statsData.booking_count}</p>
				</div>
			</div>
		{/if}
		<Modal.Footer>
			<Button
				onclick={() => {
					showStatsModal = false;
				}}>Close</Button
			>
		</Modal.Footer>
	</Modal.Content>
</Modal.Root>
