<script setup lang="ts">
import { CheckCircleIcon, XCircleIcon } from '@modrinth/assets'
import {
	Checkbox,
	defineMessages,
	injectNotificationManager,
	Slider,
	StyledInput,
	useVIntl,
} from '@modrinth/ui'
import { computed, readonly, ref, watch } from 'vue'

import JavaSelector from '@/components/ui/JavaSelector.vue'
import useMemorySlider from '@/composables/useMemorySlider'
import { edit, get_optimal_jre_key } from '@/helpers/profile'
import { get } from '@/helpers/settings.ts'
import { injectInstanceSettings } from '@/providers/instance-settings'

import type { AppSettings } from '../../../helpers/types'

const { handleError } = injectNotificationManager()
const { formatMessage } = useVIntl()

const { instance } = injectInstanceSettings()

const globalSettings = (await get().catch(handleError)) as unknown as AppSettings

const overrideJavaInstall = ref(!!instance.value.java_path)
const optimalJava = readonly(await get_optimal_jre_key(instance.value.path).catch(handleError))
const javaInstall = ref({ path: optimalJava.path ?? instance.value.java_path })

const overrideJavaArgs = ref((instance.value.extra_launch_args?.length ?? 0) > 0)
const javaArgs = ref(
	(instance.value.extra_launch_args ?? globalSettings.extra_launch_args).join(' '),
)

const overrideEnvVars = ref((instance.value.custom_env_vars?.length ?? 0) > 0)
const envVars = ref(
	(instance.value.custom_env_vars ?? globalSettings.custom_env_vars)
		.map((x) => x.join('='))
		.join(' '),
)

const overrideMemorySettings = ref(!!instance.value.memory)
const memory = ref(instance.value.memory ?? globalSettings.memory)
const { maxMemory, snapPoints } = (await useMemorySlider().catch(handleError)) as unknown as {
	maxMemory: number
	snapPoints: number[]
}

const editProfileObject = computed(() => {
	return {
		java_path:
			overrideJavaInstall.value && javaInstall.value.path !== ''
				? javaInstall.value.path.replace('java.exe', 'javaw.exe')
				: null,
		extra_launch_args: overrideJavaArgs.value
			? javaArgs.value.trim().split(/\s+/).filter(Boolean)
			: null,
		custom_env_vars: overrideEnvVars.value
			? envVars.value
					.trim()
					.split(/\s+/)
					.filter(Boolean)
					.map((x) => x.split('=').filter(Boolean))
			: null,
		memory: overrideMemorySettings.value ? memory.value : null,
	}
})

watch(
	[
		overrideJavaInstall,
		javaInstall,
		overrideJavaArgs,
		javaArgs,
		overrideEnvVars,
		envVars,
		overrideMemorySettings,
		memory,
	],
	async () => {
		await edit(instance.value.path, editProfileObject.value)
	},
	{ deep: true },
)

const messages = defineMessages({
	javaInstallation: {
		id: 'instance.settings.tabs.java.java-installation',
		defaultMessage: 'Java installation',
	},
	javaArguments: {
		id: 'instance.settings.tabs.java.java-arguments',
		defaultMessage: 'Java arguments',
	},
	javaEnvironmentVariables: {
		id: 'instance.settings.tabs.java.environment-variables',
		defaultMessage: 'Environment variables',
	},
	javaMemory: {
		id: 'instance.settings.tabs.java.java-memory',
		defaultMessage: 'Memory allocated',
	},
	hooks: {
		id: 'instance.settings.tabs.java.hooks',
		defaultMessage: 'Hooks',
	},
})
</script>

<template>
	<div>
		<h2 id="project-name" class="m-0 mb-2.5 text-lg font-semibold text-contrast block">
			{{ formatMessage(messages.javaInstallation) }}
		</h2>
		<Checkbox v-model="overrideJavaInstall" label="Custom Java installation" class="mb-2.5" />
		<template v-if="!overrideJavaInstall">
			<div class="flex my-2 items-center gap-2 font-semibold">
				<template v-if="javaInstall">
					<CheckCircleIcon class="text-brand-green h-4 w-4" />
					<span>Using default Java {{ optimalJava.major_version }} installation:</span>
				</template>
				<template v-else-if="optimalJava">
					<XCircleIcon class="text-brand-red h-5 w-5" />
					<span
						>Could not find a default Java {{ optimalJava.major_version }} installation. Please set
						one below:</span
					>
				</template>
				<template v-else>
					<XCircleIcon class="text-brand-red h-5 w-5" />
					<span
						>Could not automatically determine a Java installation to use. Please set one
						below:</span
					>
				</template>
			</div>
			<div
				v-if="javaInstall && !overrideJavaInstall"
				class="p-4 bg-bg rounded-xl text-xs text-secondary leading-none font-mono"
			>
				{{ javaInstall.path }}
			</div>
		</template>
		<JavaSelector v-if="overrideJavaInstall || !javaInstall" v-model="javaInstall" />
		<h2 id="project-name" class="mt-6 mb-2.5 text-lg font-semibold text-contrast block">
			{{ formatMessage(messages.javaMemory) }}
		</h2>
		<Checkbox v-model="overrideMemorySettings" label="Custom memory allocation" class="mb-2.5" />
		<Slider
			id="max-memory"
			v-model="memory.maximum"
			:disabled="!overrideMemorySettings"
			:min="512"
			:max="maxMemory"
			:step="64"
			:snap-points="snapPoints"
			:snap-range="512"
			unit="MB"
		/>
		<h2 id="project-name" class="mt-6 mb-2.5 text-lg font-semibold text-contrast block">
			{{ formatMessage(messages.javaArguments) }}
		</h2>
		<Checkbox v-model="overrideJavaArgs" label="Custom java arguments" class="my-2" />
		<StyledInput
			id="java-args"
			v-model="javaArgs"
			autocomplete="off"
			:disabled="!overrideJavaArgs"
			placeholder="Enter java arguments..."
			wrapper-class="w-full"
		/>
		<h2 id="project-name" class="mt-6 mb-2.5 text-lg font-semibold text-contrast block">
			{{ formatMessage(messages.javaEnvironmentVariables) }}
		</h2>
		<Checkbox v-model="overrideEnvVars" label="Custom environment variables" class="mb-2.5" />
		<StyledInput
			id="env-vars"
			v-model="envVars"
			autocomplete="off"
			:disabled="!overrideEnvVars"
			placeholder="Enter environmental variables..."
			wrapper-class="w-full"
		/>
	</div>
</template>
