'use client'

import { zodResolver } from "@hookform/resolvers/zod"
import { signIn } from 'next-auth/react'
import { useRouter, useSearchParams } from "next/navigation"
import { HTMLAttributes, useState } from 'react'
import { useForm } from 'react-hook-form'
import * as z from "zod"

import { Icons } from '@/components/icons'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ToastAction } from "@/components/ui/toast"
import { toast } from "@/components/ui/use-toast"
import { cn } from '@/lib/utils'
import { userAuthSchema } from "@/lib/validations/auth"
import { sendVerificationEmail } from "@/lib/validations/sendVerificationEmail"

interface UserAuthFormProps extends HTMLAttributes<HTMLDivElement> {
    type: "login" | "signup"
}

type FormData = z.infer<typeof userAuthSchema>


export function UserAuthForm({ type, className, ...props }: UserAuthFormProps) {
    const {
        register,
        handleSubmit,
        setError,
        formState: { errors },
    } = useForm<FormData>({
        resolver: zodResolver(userAuthSchema),
    })
    const [isLoading, setIsLoading] = useState<boolean>(false)
    const [isGitHubLoading, setIsGitHubLoading] = useState<boolean>(false)
    const router = useRouter()
    const searchParams = useSearchParams()
    //muss noch exportiert werden

    async function onSubmit(data: FormData) {
        setIsLoading(true)

        if (type === "signup") {
            const res = await fetch('/api/signup', {
                method: 'POST',
                body: JSON.stringify({
                    username: data.username,
                    email: data.email,
                    password: data.password
                }),
                headers: {
                    'Content-Type': 'application/json'
                }
            })

            if (!res.ok) {
                if (res.status === 422) {
                    setError('email', { type: 'manual', message: 'This email is already in use. Please choose another one.' })
                }

                setIsLoading(false)
                return toast({
                    variant: "destructive",
                    title: "Uh oh! Something went wrong.",
                    description: "Your sign up request failed. Please try again.",
                })
            }
            await sendVerificationEmail(data.email!)
        }

        const signInResult = await signIn("credentials", {
            usernameOrEmail: data.email?.toLowerCase() || data.usernameOrEmail?.toLowerCase(),
            password: data.password,
            redirect: false,
            callbackUrl: searchParams?.get("from") || "/home",
        })

        setIsLoading(false)

        if (signInResult?.error) {
            if (signInResult.error === "user not found") {
                setError('usernameOrEmail', {
                    type: 'manual',
                    message: 'Sorry, we couldn\'t find an account with the provided email / username. Please double-check your input or create a new account.'
                })
            }
            if (signInResult.error === "invalid password") {
                setError('password', {
                    type: 'manual',
                    message: 'Sorry, but it seems like the password you entered is invalid. Please try again.'
                })
            }
            if (signInResult.error === "Email is not verified") {
                return toast({
                    title: "Please Verify your account.",
                    description: "We send you a email to verify your Account. Please check your Mailbox!🚀",
                })
            }
            return toast({
                variant: "destructive",
                title: "Uh oh! Something went wrong.",
                description: "Your log in request failed. Please try again.",
                action: <ToastAction altText="Try again">Try again</ToastAction>,
            })
        }

        router.push("/home")
        router.refresh()

        if (type !== "signup") {
            return toast({
                title: "Login successful.",
                description: "You will be redirected shortly.",
            })
        }
    }

    async function onGitHub() {
        setIsGitHubLoading(true)
        await signIn("github", { callbackUrl: searchParams?.get("from") || "/home" })
    }

    return (
        <div className={cn("grid gap-6", className)} {...props}>
            <form onSubmit={handleSubmit(onSubmit)}>
                <div className="grid gap-2">
                    {type === "login" ?
                        <div className="grid gap-1">
                            <Label className="sr-only" htmlFor="usernameOrEmail">
                                Username or email
                            </Label>
                            <Input
                                id="usernameOrEmail"
                                placeholder="Your username or email"
                                type="text"
                                autoCapitalize="none"
                                autoComplete="username email"
                                autoCorrect="off"
                                disabled={isLoading || isGitHubLoading}
                                {...register("usernameOrEmail", { required: true })}
                            />
                            {errors?.usernameOrEmail && (
                                <p className="px-1 text-xs text-red-600">
                                    {errors.usernameOrEmail.message}
                                </p>
                            )}
                        </div> : null}
                    {type === "signup" ?
                        <>
                            <div className="grid gap-1">
                                <Label className="sr-only" htmlFor="username">
                                    Username
                                </Label>
                                <Input
                                    id="username"
                                    placeholder="Your username"
                                    type="username"
                                    autoCapitalize="none"
                                    autoComplete="username"
                                    autoCorrect="off"
                                    disabled={isLoading || isGitHubLoading}
                                    {...register("username", { required: true })}
                                />
                                {errors?.username && (
                                    <p className="px-1 text-xs text-red-600">
                                        {errors.username.message}
                                    </p>
                                )}
                            </div>
                            <div className="grid gap-1">
                                <Label className="sr-only" htmlFor="email">
                                    Email
                                </Label>
                                <Input
                                    id="email"
                                    placeholder="Your email"
                                    type="email"
                                    autoCapitalize="none"
                                    autoComplete="email"
                                    autoCorrect="off"
                                    disabled={isLoading || isGitHubLoading}
                                    {...register("email", { required: true })}
                                />
                                {errors?.email && (
                                    <p className="px-1 text-xs text-red-600">
                                        {errors.email.message}
                                    </p>
                                )}
                            </div>
                        </> : null}
                    <div className="grid gap-1">
                        <Label className="sr-only" htmlFor="password">
                            Password
                        </Label>
                        <Input
                            id="password"
                            placeholder="Your password"
                            type="password"
                            autoCapitalize="none"
                            autoComplete="new-password"
                            autoCorrect="off"
                            disabled={isLoading || isGitHubLoading}
                            {...register("password", { required: true })}
                        />
                        {errors?.password && (
                            <p className="px-1 text-xs text-red-600">
                                {errors.password.message}
                            </p>
                        )}
                    </div>
                    <Button disabled={isLoading} type="submit">
                        {isLoading && (
                            <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
                        )}
                        {type === "signup" ? "Sign Up" : "Log In"}
                    </Button>
                </div>
            </form>

            <div className="relative">
                <div className="absolute inset-0 flex items-center">
                    <span className="w-full border-t" />
                </div>
                <div className="relative flex justify-center text-xs uppercase">
                    <span className="bg-background px-2 text-muted-foreground">
                        Or continue with
                    </span>
                </div>
            </div>
            <Button
                variant="outline"
                type="button"
                onClick={onGitHub}
                disabled={isLoading || isGitHubLoading}
            >
                {isGitHubLoading ? (
                    <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
                ) : (
                    <Icons.github className="mr-2 h-4 w-4" />
                )}{" "}
                Github
            </Button>
        </div>
    )
}