import { Schema as S } from "@effect/schema";
import { Me } from "common/api";
import { Effect, Fiber, Option as O, Option, pipe } from "effect";
import { useLocation } from "preact-iso";
import { useEffect, useMemo } from "preact/hooks";
import { useStore } from "../store";
import * as style from "./Home.css";

export const Home = () => {

	const { route } = useLocation();

	const user = Option.getOrNull(useStore(state => state.user));
	const setUser = useStore(state => state.setUser);

	useEffect(() => {
		if (user !== null) return;

		const effect = Effect.gen(function* () {
			const res = yield* Effect.promise((signal) => fetch("http://localhost:3000/me", {
				method: "GET",
				signal,
				credentials: "include",
			}));

			if (!res.ok) {
				route("/login");
				return;
			}

			const responseData = yield* pipe(
				Effect.promise(() => res.json()),
				Effect.flatMap(S.decodeUnknown(Me.props.response[200].schema)),
				Effect.orDie,
			);

			setUser(O.some(responseData));
		});

		const fiber = Effect.runFork(effect);
		return () => Effect.runFork(Fiber.interrupt(fiber), { immediate: true });
	}, []);

	const logoutEffect = useMemo(() => Effect.gen(function* () {
		const res = yield* Effect.promise((signal) => fetch("http://localhost:3000/logout", {
			method: "POST",
			signal,
			credentials: "include",
		}));

		if (!res.ok) {
			yield* Effect.die(new Error("Response was not ok"));
		}

		setUser(O.none());

		route("/login");
	}), []);

	const onLogoutClick = () => {
		Effect.runFork(logoutEffect);
	};

	if (user === null) {
		return (
			<div class={style.container}>
				<div class={style.loading}>Ładowanie…</div>
			</div>
		);
	}

	return (
		<div class={style.container}>
			<div class={style.content}>
				Użytkownik: {user.username}
				<button type="button" onClick={onLogoutClick}>Wyloguj się</button>
			</div>
		</div>
	);
};
