import {GetServerSideProps, NextPage} from 'next'
import {getSession, Session, withPageAuthRequired} from '@auth0/nextjs-auth0';
import {useEffect, useState} from 'react';
import CreateRingtoneTemplate from '../../../../components/templates/CreateRingtone'
import RingtoneClient from '../../../../modules/ringtone/client'
import WaveOscillator from '../../../../utils/sound/WaveOscillator'
import SoundManager from '../../../../utils/sound/SoundManager'
import ComposerClient from '../../../../modules/composer/client'
import {useRouter} from 'next/router';

type Props = {
	session: Partial<Session>,
}

const Page: NextPage<Props> = ({
	session,
}) => {
	const [hydrated, setHydrated] = useState(false)
	const [ringtoneClient, setRingtoneClient] = useState<RingtoneClient>(null)
	const [composerClient, setComposerClient] = useState<ComposerClient>(null)
	const router = useRouter()

	useEffect(() => {
		setHydrated(true)
	}, [])

	useEffect(() => {
		setRingtoneClient(new RingtoneClient(process.env.NEXT_PUBLIC_API_BASE_URL, session))
	}, [hydrated])

	useEffect(() => {
		const audioContext = new AudioContext()
		const gainNode = audioContext.createGain()
		gainNode.gain.value = 0.05
		gainNode.connect(audioContext.destination)
		const oscillator = new WaveOscillator(audioContext, gainNode)
		const soundManager = new SoundManager(oscillator)
		setComposerClient(new ComposerClient(soundManager))
	}, [hydrated])

	return (
		<CreateRingtoneTemplate
			session={session}
			addNote={composerClient ? composerClient.addNote : undefined}
			addRest={composerClient ? composerClient.addRest : undefined}
			togglePlayback={composerClient ? composerClient.togglePlayback : undefined}
			updateSong={composerClient ? composerClient.updateSong : undefined}
			updateTempo={composerClient ? composerClient.updateTempo : undefined}
			updateView={composerClient ? composerClient.updateView : undefined}
			onSubmit={ringtoneClient ? ringtoneClient.save({ router, }) : undefined}
			play={composerClient ? composerClient.play : undefined}
		/>
	)
}

export const getServerSideProps: GetServerSideProps = withPageAuthRequired({
	getServerSideProps: async (ctx) => {
		const { idToken, token_type, user } = getSession(ctx.req, ctx.res)
		const session = {
			idToken,
			token_type,
			user,
		}

		return {
			props: {
				session,
			},
		}
	},
	returnTo: '/my/create/ringtones'
})

export default Page
