<script lang="ts">
	import { 
		Presentation, 
		Slide, 
		FitText, 
		Step, 
		Notes, 
		Media,
		Code
	} from '@components'
	import { signal } from '@motion'
	import StateNotes from "./notes/state.notes.svelte"
	import useReducerImg from "@assets/useReducer.png";

	const circle = signal(
		{ x: 0, y: 200, r: 80, fill: '#00ffff' },
		{ duration: 2000 }
	)

	async function animate() {
		await circle.to({ x: 400, fill: '#ffff00' }, { delay: 600 })
		await circle.to({ x: 0, fill: '#00ffff' }, { delay: 300 })
	}

	function resetAnimation() {
		circle.reset()
	}
</script>

<Presentation>
	<Slide animate>
		<p class="font-bold text-8xl text-pink-700">React Builtin Hooks</p>
	</Slide>

	<!-- <Slide on:in={animate} on:out={resetAnimation} animate>
		<p class="font-bold text-6xl">React Builtin Hooks</p>

		<div>
			<ul>
				<li>useState()</li>
			</ul>
		</div>
	</Slide> -->
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-pink-700">React Builtin Hooks</p>
		<ul class="mx-auto w-[200px] list-disc">
			<Step>
				<li>useState()</li>
			</Step>			
			<Step>
				<li>useEffect()</li>
			</Step>
			<Step>
				<li>useContext()</li>
			</Step>
			<Step>
				<li>useReducer()</li>
			</Step>
			<Step>
				<li>useRef()</li>
			</Step>
			<Step>
				<li>useMemo()</li>
			</Step>
			<Step>
				<li>useCallback()</li>
			</Step>
		</ul>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-pink-700">What is a State?</p>
		<Notes>
			<ul>
				<li>
					State is something which holds the info or details about a Component's State at a TIME
				</li>
				<li>
					It can change over time.
				</li>
				<li>
					Whenever the state changes the COMPONENT attached to it re-renders
				</li>
			</ul>
		</Notes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-pink-700">useState()</p>
		<div class="mx-auto w-[800px]">
			<Code lang="js" lines="3">
				{`
				import React, {useState} from 'react';

				const [value, setValue] = useState(null);
				`}
			</Code>
		</div>
		<StateNotes></StateNotes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-pink-700">useState()</p>
		<div class="mx-auto w-[800px]">
			<Code lang="js" lines="3-6">
				{`
					import React, {useState} from 'react';
				
					const [value, setValue] = useState({
						id: 12,
						name: "YouName"
					})
				`}
			</Code>
		</div>
		<StateNotes></StateNotes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-pink-700">useState()</p>
		<div class="mx-auto">
			<Code lang="js" lines="7|3-5|3-7">
				{`
				import React, {useState} from 'react';

				function calculateValue() {
					return Math.sqrt(64);
				}

				const [value, setValue] = useState(calculateValue());
				`}
			</Code>
		</div>
		<StateNotes></StateNotes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">Side Effects</p>
		<Media
			class="h-[600px] w-full"
			src="https://giphy.com/embed/39sYm1hvWRPN3NxHdI"
			type="iframe"
		>			
		</Media>
		<Notes>
			<ul>
				<li>
					Something which is outside the scope of REACT
					<ul>
						<li>
							Calling AJAX requests
						</li>
						<li>
							Calling Web API stuffs (document.get...)
						</li>
						<li>
							localStorage etc...
						</li>
						<li>
							setTimeout, setInterval
						</li>
					</ul>
				</li>
				<li>
					Everything which is not part of React Library
				</li>
				<li>
					Fun Fact - What happens if you call setTimeout without any arguments
					<ul>
						<li>
							Executes outside the execution queue
						</li>
					</ul>
				</li>
			</ul>
		</Notes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				})
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}) ← No Arguments means this will be called each time 
				     this component re-renders
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}, []) ← An empty array as an argument will run the 
				       effect once the component is mounted
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}, [prop1]) ← We can pass value
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}, [prop1, state1]) ← Actually we can pass multiple-values
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}, [prop1, state1]) ← This is called dependency list
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect"
				}, [prop1, state1]) ← Effect will run whenever any
										of the values on dependency list changes
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useEffect</p>
		<div class="mx-auto">
			<Code lang="js" lines="4-6">
				{`
				useEffect(() => {
					document.title = "Hey There, I'm from useEffect";

					return () => {
						// Clean Up function 🧹
					}
				}, [prop1, state1]);
				`}
			</Code>
		</div>
		<Notes>
			<ul>
				<li>
					You can do removeListeners, unsubscribes, reset layouts etc
				</li>
				<li>
					This will be called by default when component unmouts.
				</li>
			</ul>
		</Notes>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useContext</p>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useContext</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-4">
				{`
				import { createContext, useContext, useState } from 'react';

				const AppContext = createContext(null);
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useContext</p>
		<div class="mx-auto">
			<Code lang="js" lines="5-18">
				{`
				import React, { createContext, useContext, useState } from 'react';

				export const AppContext = createContext(null);

				export default function MyApp() {
					const [someState, setSomeState] = useState('hello');
					return (
						<>
						<AppContext.Provider value={someState}>
							<MyComponent />
						</AppContext.Provider>
						<Button onClick={() => {
							setTheme(someState === 'hello' ? 'World' : 'Blah');
						}}>
						</Button>
						</>
					)
				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useContext</p>
		<div class="mx-auto">
			<Code lang="js" lines="6">
				{`
				import React, { useContext, useState } from 'react';
				
				import {AppContext} from "./MyApp";

				export default function MyComponent() {
					const appContext = useContext(AppContext)
					return (
						<div>{appContext}</div>
					)
				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useContext</p>
		<div class="mx-auto">
			<Code lang="js" lines="8">
				{`
				import React, { useContext, useState } from 'react';
				
				import {AppContext} from "./MyApp";

				export default function MyComponent() {
					const appContext = useContext(AppContext)
					return (
						<div>{appContext}</div>
					)
				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<Media
			class="h-[501px] w-[891px]"
			src={useReducerImg}
			type="iframe"
		/>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" lines="1">
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							data: "Switch on"
						}
					} else if(action.type === "of") {
						return {
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" lines="15-31">
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							data: "Switch on"
						}
					} else if(action.type === "of") {
						return {
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" lines="3-13">
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							data: "Switch on"
						}
					} else if(action.type === "of") {
						return {
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" >
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							data: "Switch on"
						}
					} else if(action.type === "of") {
						return {
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" lines="4-14">
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							...state,
							data: "Switch on",
						}
					} else if(action.type === "of") {
						return {
							...state,
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
	<Slide on:in={animate} animate>
		<p class="font-bold text-6xl mb-4 text-yellow-500">useReducer</p>
		<div class="mx-auto">
			<Code lang="js" lines="6|11">
				{`
				import {useReducer} from "react";

				function myReducer(state, action) {
					if(action.type === "on") {
						return {
							...state,
							data: "Switch on",
						}
					} else if(action.type === "of") {
						return {
							...state,
							data: "Switch Off"
						}
					}
				}

				export function MyComponent(props) {
					const [state, dispatch] = useReducer(myReducer, {});

					function onSwitchToggle(status) {
						dispatch({
							type: status
						})
					}

					return(
						<div>
							<button onClick={onSwitchToggle("on")}>ON</button>
							<button onClick={onSwitchToggle("off")}>Off</button>
						</div>
					)

				}
				`}
			</Code>
		</div>
	</Slide>
</Presentation>
