"use client";

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

import AutoForm, { AutoFormSubmit } from "@/components/auto-form";
import { UserDataContext } from "@/components/providers/userdata-provider";
import { ToastBox, toastType } from "@/components/ui/toast-box";
import { useToast } from "@/components/ui/use-toast";
import type {
	IApiLoginReq,
	IApiLoginRes,
	IApiRegisterReq,
	IApiRegisterRes,
} from "@/interfaces/api.interface";
import { EReturnState, type IStandardisedReturn } from "@/interfaces/general.interface";
import type { IUserData } from "@/interfaces/userdata.interface";
import ApiRequest from "@/services/apiRequest";
import { useLocalStorage } from "@/services/localStorage";
import { Bug, RefreshCw } from "lucide-react";
import Link from "next/link";
import React, { type Dispatch, type SetStateAction, useContext, useState } from "react";
import * as z from "zod";
import Image from "next/image";

const loginSchema = z.object({
	email: z
		.string({
			required_error: "Email is needed.",
		})
		.email({
			message: "Should be a valid email.",
		})
		.describe("Your account email."),
	password: z
		.string({
			required_error: "Password is needed.",
		})
		.describe("Your account password."),
});

const registerSchema = z.object({
	firstName: z.string({
		required_error: "First name is required.",
	}).describe("First name"),
	lastName: z.string({
		required_error: "Last name is required.",
	}).describe("Last name"),
	pseudo: z.string({
		required_error: "Nickname is required.",
	}).describe("Nickname"),
	email: z
		.string({
			required_error: "Email is required.",
		})
		.email("Email must be valid."),
	password: z
		.string({
			required_error: "Password is required.",
		})
		.min(8, "Password must be at least 8 characters.")
		.max(32, "Password must be less than 32 characters.")
		.regex(/[A-Z]/, "Password must contain at least one uppercase letter.")
		.regex(/[a-z]/, "Password must contain at least one lowercase letter.")
		.regex(/[0-9]/, "Password must contain at least one number.")
		.regex(/[^a-zA-Z0-9]/, "Password must contain at least one special character.")
		.describe("Your account password."),

	promoCode: z
		.string().max(255, "Your promotional code is too long.").optional(),
});

export function AuthForms() {
	const [isLoading, setIsLoading] = useState(false);
	const [sub, setSub] = useLocalStorage<string | undefined>("sub", "");
	const userContext = useContext(UserDataContext);
	const { toast } = useToast();

	async function doRegister(
		registerData: IApiRegisterReq,
		userDataSetter: Dispatch<SetStateAction<IUserData | null>>,
	): Promise<IStandardisedReturn<IApiRegisterRes>> {
		console.trace(registerData);
		try {
			const ReqRes = await ApiRequest.standard.post.json<
				IApiRegisterReq,
				IApiRegisterRes
			>("auth/sign-up", registerData);
			console.trace(ReqRes.data);
			if (ReqRes.data.user) {
				userDataSetter({
					...ReqRes.data.user,
					wallet: {
						uat: Date.now(),
						update_interval: 30_000,
						owned_cryptos: [],
					},
				});

				setSub(ReqRes.data.access_token);
			}
			console.debug(ReqRes.data.message || "Not additional message from request");
			return {
				state: EReturnState.done,
				resolved: ReqRes.data,
			};
		} catch (error) {
			console.error("Error during registration:", error);
			return {
				state: EReturnState.serverError,
				message: error as string,
			};
		}
	}

	async function doLogin(
		loginData: IApiLoginReq,
	): Promise<IStandardisedReturn<IApiLoginRes>> {
		try {
			const ReqRes = await ApiRequest.standard.post.json<IApiLoginReq, IApiLoginRes>(
				"auth/sign-in",
				loginData,
			);
			console.trace(ReqRes.data);
			if (ReqRes.data.access_token) {
				setSub(ReqRes.data.access_token);
			}
			return {
				state: EReturnState.done,
			};
		} catch (err) {
			console.error("Error during login:", err);
			return {
				state: EReturnState.serverError,
				message: err as string,
			};
		}
	}

	if (!userContext || !userContext.setUserData) {
		return (
			<div
				className={
					"bg-destructive text-destructive-foreground p-3 gap-2 border rounded flex flex-row justify-center items-center"
				}
			>
				<Bug />
				<p>It seems that the context is missing..</p>
			</div>
		);
	}

	return (
		<section className={"flex flex-col gap-6 items-center justify-center"}>
			<Link href={"/"} className={"hidden sm:visible sm:flex flex-row justify-center md:justify-start items-center w-fit gap-2"}>
				<Image src={"neptune.svg"} alt={"Logo of Neptune"} className={"w-24 h-24"} width={128} height={128} />
				<h1 className={"font-bold text-xl lg:text-2xl align-middle text-center text-wrap"}>
					Neptune Crypto
				</h1>
			</Link>
			<Tabs defaultValue="login" className="w-full p-2 gap-4 flex flex-col justify-center sm:p-4 rounded bg-card text-card-foreground md:w-[400px] my-4">
				<TabsList className="grid w-full grid-cols-2">
					<TabsTrigger value="login">Login</TabsTrigger>
					<TabsTrigger value="register">Register</TabsTrigger>
				</TabsList>
				<TabsContent value="login">
					<AutoForm
						// I pass the Zod schema to the form
						formSchema={loginSchema}
						onSubmit={(data: IApiLoginReq) => {
							setIsLoading(true);
							doLogin(data).then((res) => {
								if (res.state !== EReturnState.done) {
									toast({
										description: res.message || "An unexpected error occurred..",
										variant: "destructive",
									});
									setIsLoading(false);
									return;
								}
								//toast.custom(<ToastBox message={"Login successful ! \n You will be redirected."} type={toastType.success}/>)
								toast({
									description: "Login successful ! \n You will be redirected to the home page.",
								});
								setTimeout(() => {
									setIsLoading(false);
									location.href = "/";
									console.log("Moving to home.");
								}, 3_000);
							});
						}}
						fieldConfig={{
							password: {
								inputProps: {
									type: "password",
									placeholder: "••••••••",
								},
							},
						}}
					>
						<AutoFormSubmit
							disabled={!!isLoading}
							className={"gap-2 disabled:bg-secondary"}
						>
							{/* biome-ignore lint/style/useTemplate: <explanation> */}
							<RefreshCw className={"animate-spin" + isLoading && "hidden"} />
							<p>Login</p>
						</AutoFormSubmit>
					</AutoForm>
				</TabsContent>
				<TabsContent value="register">
					<AutoForm
						// Pass the schema to the form
						formSchema={registerSchema}
						onSubmit={(data: IApiRegisterReq) => {
							setIsLoading(true);
							doRegister(
								data,
								userContext.setUserData as Dispatch<SetStateAction<IUserData | null>>,
							).then((res) => {
								if (res.state !== EReturnState.done) {
									//toast.custom(<ToastBox message={res.message || "An unexpected error occurred.."} type={toastType.error}/>)
									setIsLoading(false);
									return;
								}
								//toast.custom(<ToastBox message={"Register successful ! \n You will be redirected."} type={toastType.success}/>)
								setTimeout(() => {
									setIsLoading(false);
									//location.href = "/"
									console.log("Moving to home.");
								}, 5_000);
							});
						}}
						fieldConfig={{
							password: {
								inputProps: {
									type: "password",
									placeholder: "••••••••",
								},
							},
						}}
					>
						<AutoFormSubmit
							disabled={!!isLoading}
							className={"gap-2 disabled:bg-secondary"}
						>
							{/* biome-ignore lint/style/useTemplate: <explanation> */}
							<RefreshCw className={"animate-spin" + !isLoading && "hidden"} />
							<p>Register</p>
						</AutoFormSubmit>
						<p className="text-gray-500 text-sm">
							By submitting this form, you agree to the{" "}
							<Link title={"Go to legal page"} href="/legal" className="text-primary underline">
								GDPR Compliance Policy & Usage Policy
							</Link>
							.
						</p>
					</AutoForm>
				</TabsContent>
			</Tabs>
		</section>
	);
}
