<script lang="ts">
	import { z } from 'zod'
	import AdminPage from './AdminPage.svelte'
	import AdminSegmentedControl from './AdminSegmentedControl.svelte'
	import Input from './Input.svelte'
	import DropdownSelectField from './DropdownSelectField.svelte'
	import AutoSaveStatus from './AutoSaveStatus.svelte'
	import UnifiedMediaModal from './UnifiedMediaModal.svelte'
	import SmartImage from '../SmartImage.svelte'
	import Composer from './composer'
	import type { Album, Media } from '@prisma/client'
	import type { JSONContent } from '@tiptap/core'

	interface Props {
		album?: Album | null
		mode: 'create' | 'edit'
	}

	let { album = null, mode }: Props = $props()

	// State
	let isLoading = $state(mode === 'edit')
	let showBulkAlbumModal = $state(false)
	let albumMedia = $state<Array<{ media: Media; displayOrder: number }>>([])
	let editorInstance = $state<{ save: () => Promise<JSONContent>; clear: () => void } | undefined>()
	let activeTab = $state('metadata')
	let pendingMediaIds = $state<number[]>([]) // Photos to add after album creation

	const tabOptions = [
		{ value: 'metadata', label: 'Metadata' },
		{ value: 'content', label: 'Content' }
	]

	const statusOptions = [
		{
			value: 'draft',
			label: 'Draft',
			description: 'Only visible to you'
		},
		{
			value: 'published',
			label: 'Published',
			description: 'Visible on your public site'
		}
	]

	// Form data
	let formData = $state({
		title: '',
		slug: '',
		year: '',
		location: '',
		showInUniverse: false,
		status: 'draft' as 'draft' | 'published',
		content: { type: 'doc', content: [{ type: 'paragraph' }] } as JSONContent
	})

	// Derived state for existing media IDs
	const existingMediaIds = $derived(albumMedia.map((item) => item.media.id))

	// Watch for album changes and populate form data
	$effect(() => {
		if (album && mode === 'edit') {
			populateFormData(album)
			loadAlbumMedia()
		} else if (mode === 'create') {
			isLoading = false
		}
	})

	// Watch for title changes and update slug
	$effect(() => {
		if (formData.title && mode === 'create') {
			formData.slug = formData.title
				.toLowerCase()
				.replace(/[^a-z0-9]+/g, '-')
				.replace(/^-+|-+$/g, '')
		}
	})

	function populateFormData(data: Album) {
		formData = {
			title: data.title || '',
			slug: data.slug || '',
			year: data.date ? new Date(data.date).getFullYear().toString() : '',
			location: data.location || '',
			showInUniverse: data.showInUniverse || false,
			status: (data.status as 'draft' | 'published') || 'draft',
			content: (data.content as JSONContent) || { type: 'doc', content: [{ type: 'paragraph' }] }
		}

		isLoading = false
	}

	async function loadAlbumMedia() {
		if (!album) return

		try {
		const response = await fetch(`/api/albums/${album.id}`, {
			credentials: 'same-origin'
		})
			if (response.ok) {
				const data = await response.json()
				albumMedia = data.media || []
			}
		} catch (err) {
			console.error('Failed to load album media:', err)
		}
	}

	async function handleBulkAlbumSave() {
		// Reload album to get updated photo count
		if (album && mode === 'edit') {
			await loadAlbumMedia()
		}
	}

	function handleContentUpdate(content: JSONContent) {
		formData.content = content
	}

	function handlePhotoSelection(media: Media[]) {
		pendingMediaIds = media.map((m) => m.id)
	}
</script>

<AdminPage>
	<header slot="header">
		<div class="header-left">
			<h1 class="form-title">{formData.title || 'Untitled Album'}</h1>
		</div>
		<div class="header-center">
			<AdminSegmentedControl
				options={tabOptions}
				value={activeTab}
				onChange={(value) => (activeTab = value)}
			/>
		</div>
		<div class="header-actions">
			{#if !isLoading}
				<AutoSaveStatus
					status="idle"
					lastSavedAt={album?.updatedAt}
				/>
			{/if}
		</div>
	</header>

	<div class="admin-container">
		{#if isLoading}
			<div class="loading">Loading album...</div>
		{:else}
			<div class="tab-panels">
				<!-- Metadata Panel -->
				<div class="panel content-wrapper" class:active={activeTab === 'metadata'}>
					<!-- Album Details -->
					<div class="form-section">
						<Input
							label="Title"
							size="jumbo"
							bind:value={formData.title}
							placeholder="Album title"
							required
						/>

						<Input
							label="Slug"
							bind:value={formData.slug}
							placeholder="url-friendly-name"
							required
							disabled={mode === 'edit'}
						/>

						<div class="form-grid">
							<Input
								label="Location"
								bind:value={formData.location}
								placeholder="e.g. Tokyo, Japan"
							/>
							<Input
								label="Year"
								type="text"
								bind:value={formData.year}
								placeholder="e.g. 2023 or 2023-2025"
							/>
						</div>

						<DropdownSelectField
							label="Status"
							bind:value={formData.status}
							options={statusOptions}
						/>
					</div>

					<!-- Display Settings -->
					<div class="form-section">
						<label class="toggle-label">
							<input
								type="checkbox"
								bind:checked={formData.showInUniverse}
								class="toggle-input"
							/>
							<div class="toggle-content">
								<span class="toggle-title">Show in Universe</span>
								<span class="toggle-description">Display this album in the Universe feed</span>
							</div>
							<span class="toggle-slider"></span>
						</label>
					</div>

					<!-- Photos Grid -->
					<div class="form-section">
						<div class="section-header">
							<h3 class="section-title">
								Photos {albumMedia.length > 0 || pendingMediaIds.length > 0
									? `(${mode === 'edit' ? albumMedia.length : pendingMediaIds.length})`
									: ''}
							</h3>
							<button class="btn-secondary" onclick={() => (showBulkAlbumModal = true)}>
								{mode === 'create' ? 'Select Photos' : 'Manage Photos'}
							</button>
						</div>
						{#if mode === 'edit' && albumMedia.length > 0}
							<div class="photos-grid">
								{#each albumMedia as item}
									<div class="photo-item">
										<SmartImage
											media={item.media}
											alt={item.media.description || item.media.filename}
											sizes="(max-width: 768px) 50vw, 25vw"
										/>
									</div>
								{/each}
							</div>
						{:else if mode === 'create' && pendingMediaIds.length > 0}
							<p class="selected-count">
								{pendingMediaIds.length} photo{pendingMediaIds.length !== 1 ? 's' : ''} selected. They
								will be added when you save the album.
							</p>
						{:else}
							<p class="empty-state">
								No photos {mode === 'create' ? 'selected' : 'added'} yet. Click "{mode === 'create'
									? 'Select Photos'
									: 'Manage Photos'}" to {mode === 'create' ? 'select' : 'add'} photos.
							</p>
						{/if}
					</div>
				</div>

				<!-- Content Panel -->
				<div class="panel panel-content" class:active={activeTab === 'content'}>
					<Composer
						bind:this={editorInstance}
						bind:data={formData.content}
						placeholder="Add album content..."
						onChange={handleContentUpdate}
						albumId={album?.id}
						variant="full"
					/>
				</div>
			</div>
		{/if}
	</div>
</AdminPage>

<!-- Media Modal -->
<UnifiedMediaModal
	bind:isOpen={showBulkAlbumModal}
	albumId={album?.id}
	selectedIds={mode === 'edit' ? existingMediaIds : pendingMediaIds}
	showInAlbumMode={mode === 'edit'}
	onSave={mode === 'edit' ? handleBulkAlbumSave : undefined}
	onSelect={mode === 'create' ? handlePhotoSelection : undefined}
	mode="multiple"
	title={mode === 'create' ? 'Select Photos for Album' : 'Manage Album Photos'}
	confirmText={mode === 'create' ? 'Select Photos' : 'Update Photos'}
/>

<style lang="scss">
	header {
		display: grid;
		grid-template-columns: 250px 1fr 250px;
		align-items: center;
		width: 100%;
		gap: $unit-2x;

		.header-left {
			width: 250px;
			display: flex;
			align-items: center;
			gap: $unit-2x;
		}

		.header-center {
			display: flex;
			justify-content: center;
			align-items: center;
		}

		.header-actions {
			width: 250px;
			display: flex;
			justify-content: flex-end;
			gap: $unit-2x;
		}
	}

	.form-title {
		margin: 0;
		font-size: 1rem;
		font-weight: 500;
		color: $gray-20;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.btn-icon {
		width: 40px;
		height: 40px;
		border: none;
		background: none;
		color: $gray-40;
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 8px;
		transition: all 0.2s ease;

		&:hover {
			background: $gray-90;
			color: $gray-10;
		}
	}

	.admin-container {
		width: 100%;
		margin: 0 auto;
		padding: 0 $unit-2x $unit-4x;
		box-sizing: border-box;

		@include breakpoint('phone') {
			padding: 0 $unit-2x $unit-2x;
		}
	}

	.tab-panels {
		position: relative;

		.panel {
			display: none;
			box-sizing: border-box;

			&.active {
				display: block;
			}
		}
	}

	.content-wrapper {
		background: white;
		border-radius: $unit-2x;
		width: 100%;
		margin: 0 auto;

		@include breakpoint('phone') {
			padding: $unit-3x;
		}
	}

	.loading {
		text-align: center;
		padding: $unit-6x;
		color: $gray-40;
	}

	.form-section {
		display: flex;
		flex-direction: column;
		gap: $unit-4x;

		&:not(:last-child) {
			margin-bottom: $unit-6x;
		}
	}

	.section-title {
		font-size: 1.125rem;
		font-weight: 600;
		color: $gray-10;
		margin: 0;
	}

	.section-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
	}

	.form-grid {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: $unit-3x;

		@include breakpoint('phone') {
			grid-template-columns: 1fr;
		}
	}

	.photos-grid {
		display: grid;
		grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
		gap: $unit-2x;

		@include breakpoint('phone') {
			grid-template-columns: repeat(2, 1fr);
		}
	}

	.photo-item {
		aspect-ratio: 1;
		overflow: hidden;
		border-radius: $unit;
		background: $gray-95;

		:global(img) {
			width: 100%;
			height: 100%;
			object-fit: cover;
		}
	}

	.panel-content {
		background: white;
		padding: 0;
		min-height: 80vh;
		margin: 0 auto;
		display: flex;
		flex-direction: column;

		@include breakpoint('phone') {
			min-height: 600px;
		}
	}

	// Toggle styles
	.toggle-label {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: $unit-3x;
		cursor: pointer;
		user-select: none;
	}

	.toggle-input {
		position: absolute;
		opacity: 0;
		pointer-events: none;

		&:checked + .toggle-content + .toggle-slider {
			background-color: $blue-60;

			&::before {
				transform: translateX(20px);
			}
		}

		&:disabled + .toggle-content + .toggle-slider {
			opacity: 0.5;
			cursor: not-allowed;
		}
	}

	.toggle-slider {
		position: relative;
		width: 44px;
		height: 24px;
		background-color: $gray-80;
		border-radius: 12px;
		transition: background-color 0.2s ease;
		flex-shrink: 0;

		&::before {
			content: '';
			position: absolute;
			top: 2px;
			left: 2px;
			width: 20px;
			height: 20px;
			background-color: white;
			border-radius: 50%;
			transition: transform 0.2s ease;
			box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
		}
	}

	.toggle-content {
		display: flex;
		flex-direction: column;
		gap: $unit-half;

		.toggle-title {
			font-weight: 500;
			color: $gray-10;
			font-size: 0.875rem;
		}

		.toggle-description {
			font-size: 0.75rem;
			color: $gray-50;
			line-height: 1.4;
		}
	}

	// Button styles
	.btn-secondary {
		padding: $unit $unit-2x;
		border: 1px solid $gray-80;
		background: white;
		color: $gray-20;
		border-radius: 8px;
		font-size: 0.875rem;
		cursor: pointer;
		transition: all 0.2s ease;

		&:hover {
			background: $gray-95;
			border-color: $gray-70;
		}

		&:disabled {
			opacity: 0.5;
			cursor: not-allowed;
		}
	}

	.empty-state {
		color: $gray-50;
		font-size: 0.875rem;
		text-align: center;
		padding: $unit-4x;
		background: $gray-95;
		border-radius: $unit;
		margin: 0;
	}

	.selected-count {
		color: $gray-30;
		font-size: 0.875rem;
		padding: $unit-2x;
		margin: 0;
		background: $gray-95;
		border-radius: $unit;
		border: 1px solid $gray-90;
	}
</style>
