<template>
	<ModalWrapper ref="modal" :header="'Import from CurseForge Profile Code'">
		<div class="modal-body">
			<div class="input-row">
				<p class="input-label">Profile Code</p>
				<div class="iconified-input">
					<SearchIcon aria-hidden="true" class="text-lg" />
					<input ref="codeInput" v-model="profileCode" autocomplete="off" class="h-12 card-shadow"
						spellcheck="false" type="text" placeholder="Enter CurseForge profile code" maxlength="20"
						@keyup.enter="importProfile" />
					<Button v-if="profileCode" class="r-btn" @click="() => (profileCode = '')">
						<XIcon />
					</Button>
				</div>
			</div>

			<div v-if="metadata && !importing" class="profile-info">
				<h3>Profile Information</h3>
				<p><strong>Name:</strong> {{ metadata.name }}</p>
			</div>

			<div v-if="error" class="error-message">
				<p>{{ error }}</p>
			</div>

			<div v-if="importing && importProgress.visible" class="progress-section">
				<div class="progress-info">
					<span class="progress-text">{{ importProgress.message }}</span>
					<span class="progress-percentage">{{ Math.floor(importProgress.percentage) }}%</span>
				</div>
				<div class="progress-bar-container">
					<div class="progress-bar" :style="{ width: `${importProgress.percentage}%` }"></div>
				</div>
			</div>

			<div class="button-row">
				<Button @click="hide" :disabled="importing">
					<XIcon />
					Cancel
				</Button>
				<Button v-if="!metadata" @click="fetchMetadata" :disabled="!profileCode.trim() || fetching"
					color="secondary">
					<SearchIcon v-if="!fetching" />
					{{ fetching ? 'Checking...' : 'Check Profile' }}
				</Button>
				<Button v-if="metadata" @click="importProfile" :disabled="importing" color="primary">
					<DownloadIcon v-if="!importing" />
					{{ importing ? 'Importing...' : 'Import Profile' }}
				</Button>
			</div>
		</div>
	</ModalWrapper>
</template>

<script setup>
import { ref, nextTick, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { Button } from '@modrinth/ui'
import {
	XIcon,
	SearchIcon,
	DownloadIcon
} from '@modrinth/assets'
import {
	fetch_curseforge_profile_metadata,
	import_curseforge_profile
} from '@/helpers/import.js'
import { trackEvent } from '@/helpers/analytics'
import { loading_listener } from '@/helpers/events.js'

const props = defineProps({
	closeParent: {
		type: Function,
		default: null
	}
})

const router = useRouter()
const modal = ref(null)
const codeInput = ref(null)
const profileCode = ref('')
const metadata = ref(null)
const fetching = ref(false)
const importing = ref(false)
const error = ref('')
const importProgress = ref({
	visible: false,
	percentage: 0,
	message: 'Starting import...',
	totalMods: 0,
	downloadedMods: 0
})

let unlistenLoading = null
let activeLoadingBarId = null
let progressFallbackTimer = null

defineExpose({
	show: () => {
		profileCode.value = ''
		metadata.value = null
		fetching.value = false
		importing.value = false
		error.value = ''
		importProgress.value = {
			visible: false,
			percentage: 0,
			message: 'Starting import...',
			totalMods: 0,
			downloadedMods: 0
		}
		modal.value?.show()

		nextTick(() => {
			setTimeout(() => {
				codeInput.value?.focus()
			}, 100)
		})

		trackEvent('CurseForgeProfileImportStart', { source: 'ImportModal' })
	},
})

const hide = () => {
	modal.value?.hide()
}

const fetchMetadata = async () => {
	if (!profileCode.value.trim()) return

	fetching.value = true
	error.value = ''

	try {
		const result = await fetch_curseforge_profile_metadata(profileCode.value.trim())
		metadata.value = result
		trackEvent('CurseForgeProfileMetadataFetched', {
			profileCode: profileCode.value.trim()
		})
	} catch (err) {
		console.error('Failed to fetch CurseForge profile metadata:', err)
		error.value = 'Failed to fetch profile information. Please check the code and try again.'
		handleError(err)
	} finally {
		fetching.value = false
	}
}

const importProfile = async () => {
	if (!profileCode.value.trim()) return

	importing.value = true
	error.value = ''
	activeLoadingBarId = null // Reset for new import session
	importProgress.value = {
		visible: true,
		percentage: 0,
		message: 'Starting import...',
		totalMods: 0,
		downloadedMods: 0
	}

	// Fallback progress timer in case loading events don't work
	progressFallbackTimer = setInterval(() => {
		if (importing.value && importProgress.value.percentage < 90) {
			// Slowly increment progress as a fallback
			importProgress.value.percentage = Math.min(90, importProgress.value.percentage + 1)
		}
	}, 1000)

	try {
		const { result, profilePath } = await import_curseforge_profile(profileCode.value.trim())

		trackEvent('CurseForgeProfileImported', {
			profileCode: profileCode.value.trim()
		})

		hide()

		// Close the parent modal if provided
		if (props.closeParent) {
			props.closeParent()
		}

		// Navigate to the imported profile
		await router.push(`/instance/${encodeURIComponent(profilePath)}`)
	} catch (err) {
		console.error('Failed to import CurseForge profile:', err)
		error.value = 'Failed to import profile. Please try again.'
		handleError(err)
	} finally {
		importing.value = false
		importProgress.value.visible = false
		if (progressFallbackTimer) {
			clearInterval(progressFallbackTimer)
			progressFallbackTimer = null
		}
		activeLoadingBarId = null
	}
}

onMounted(async () => {
	// Listen for loading events to update progress
	unlistenLoading = await loading_listener((event) => {
		console.log('Loading event received:', event) // Debug log

		// Handle all loading events that could be related to CurseForge profile import
		const isCurseForgeEvent = event.event?.type === 'curseforge_profile_download'
		const hasProfileName = event.event?.profile_name && importing.value

		if ((isCurseForgeEvent || hasProfileName) && importing.value) {
			// Store the loading bar ID for this import session
			if (!activeLoadingBarId) {
				activeLoadingBarId = event.loader_uuid
			}

			// Only process events for our current import session
			if (event.loader_uuid === activeLoadingBarId) {
				if (event.fraction !== null && event.fraction !== undefined) {
					const baseProgress = (event.fraction || 0) * 100

					// Calculate custom progress based on the message
					let finalProgress = baseProgress
					const message = event.message || 'Importing profile...'

					// Custom progress calculation for different stages
					if (message.includes('Fetching') || message.includes('metadata')) {
						finalProgress = Math.min(10, baseProgress)
					} else if (message.includes('Downloading profile ZIP') || message.includes('profile ZIP')) {
						finalProgress = Math.min(15, 10 + (baseProgress - 10) * 0.5)
					} else if (message.includes('Extracting') || message.includes('ZIP')) {
						finalProgress = Math.min(20, 15 + (baseProgress - 15) * 0.5)
					} else if (message.includes('Configuring') || message.includes('profile')) {
						finalProgress = Math.min(30, 20 + (baseProgress - 20) * 0.5)
					} else if (message.includes('Copying') || message.includes('files')) {
						finalProgress = Math.min(40, 30 + (baseProgress - 30) * 0.5)
					} else if (message.includes('Downloaded mod') && message.includes(' of ')) {
						// Parse "Downloaded mod X of Y" message
						const match = message.match(/Downloaded mod (\d+) of (\d+)/)
						if (match) {
							const current = parseInt(match[1])
							const total = parseInt(match[2])
							// Mods take 40% of progress (from 40% to 80%)
							const modProgress = (current / total) * 40
							finalProgress = 40 + modProgress
						} else {
							finalProgress = Math.min(80, 40 + (baseProgress - 40) * 0.5)
						}
					} else if (message.includes('Downloading mod') || message.includes('mods')) {
						// General mod downloading stage (40% to 80%)
						finalProgress = Math.min(80, 40 + (baseProgress - 40) * 0.4)
					} else if (message.includes('Installing Minecraft') || message.includes('Minecraft')) {
						finalProgress = Math.min(95, 80 + (baseProgress - 80) * 0.75)
					} else if (message.includes('Finalizing') || message.includes('completed')) {
						finalProgress = Math.min(100, 95 + (baseProgress - 95))
					} else {
						// Default: use the base progress but ensure minimum progression
						finalProgress = Math.max(importProgress.value.percentage, baseProgress)
					}

					importProgress.value.percentage = Math.min(100, Math.max(0, finalProgress))
					importProgress.value.message = message
				} else {
					// Loading complete
					importProgress.value.percentage = 100
					importProgress.value.message = 'Import completed!'
					activeLoadingBarId = null
				}
			}
		}
	})
})

onUnmounted(() => {
	if (unlistenLoading) {
		unlistenLoading()
	}
	if (progressFallbackTimer) {
		clearInterval(progressFallbackTimer)
	}
})
</script>

<style lang="scss" scoped>
.modal-body {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding: 1rem;
}

.input-row {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.input-label {
	font-weight: 600;
	color: var(--color-contrast);
	margin: 0;
}

.profile-info {
	background: var(--color-bg);
	border: 1px solid var(--color-button);
	border-radius: var(--radius-md);
	padding: 1rem;

	h3 {
		margin: 0 0 0.5rem 0;
		color: var(--color-contrast);
	}

	p {
		margin: 0.25rem 0;
		color: var(--color-base);
	}
}

.error-message {
	background: var(--color-red);
	border: 1px solid var(--color-red);
	border-radius: var(--radius-md);
	padding: 0.75rem;

	p {
		margin: 0;
		color: var(--color-contrast);
		font-weight: 500;
	}
}

.progress-section {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

.progress-info {
	display: flex;
	justify-content: space-between;
	align-items: center;

	.progress-text {
		color: var(--color-base);
		font-size: 0.875rem;
	}

	.progress-percentage {
		color: var(--color-contrast);
		font-size: 0.875rem;
		font-weight: 600;
	}
}

.progress-bar-container {
	width: 100%;
	height: 4px;
	background: var(--color-button);
	border-radius: 2px;
	overflow: hidden;
}

.progress-bar {
	height: 100%;
	background: var(--color-brand);
	border-radius: 2px;
  transition: width 0.3s ease;
  min-width: 0;
}

.button-row {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
  margin-top: auto;
}
</style>
