import { useForm, SubmitHandler } from "react-hook-form"
import { rpc } from "../api"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { Layout2 } from "@/components/Layout2"
import {
    Card,
    CardContent,
    CardHeader,
    CardTitle,
    CardDescription,
    CardFooter,
} from "@/components/ui/card"
import {
    Form,
    FormField,
    FormItem,
    FormLabel,
    FormControl,
    FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { ArrowLeft, EyeOffIcon, EyeIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { useNavigate } from "react-router-dom"
import { useState } from "react"
import { Header } from "../components"

const changePasswordSchema = z
    .object({
        currentPassword: z.string().min(1, "Current password is required"),
        newPassword: z.string().min(1, "New password is required"),
        newPasswordConfirm: z.string(),
    })
    .refine((data) => data.newPassword === data.newPasswordConfirm, {
        message: "New password and confirm new password must match",
        path: ["newPasswordConfirm"],
    })

type FormFields = z.infer<typeof changePasswordSchema>

export const ChangePassword = () => {
    const navigate = useNavigate()

    const [showCurrentPassword, setShowCurrentPassword] = useState(false)
    const [showNewPassword, setShowNewPassword] = useState(false)
    const [showConfirmNewPassword, setShowConfirmNewPassword] = useState(false)

    const form = useForm<FormFields>({
        resolver: zodResolver(changePasswordSchema),
    })
    const {
        handleSubmit,
        reset,
        formState: { isSubmitting },
        control,
        setError,
    } = form

    const onSubmit: SubmitHandler<FormFields> = async ({
        currentPassword,
        newPassword,
    }) => {
        try {
            await rpc.client.changePassword(currentPassword, newPassword)
            reset()
            navigate("/settings")
        } catch (e) {
            setError("currentPassword", {
                type: "server",
                message: "Current password is incorrect",
            })
        }
    }

    return (
        <Layout2 innerClassName="bg-muted">
            <Header />
            <Form {...form}>
                <form className="relative grow" onSubmit={handleSubmit(onSubmit)}>
                    <Card className="border-none bg-muted h-full flex flex-col flex-grow w-full max-w-md shadow-none">
                        <CardHeader>
                            <CardTitle>Change Password</CardTitle>
                        </CardHeader>

                        <CardContent className="content-center flex flex-col flex-grow justify-start">
                            <FormField
                                control={control}
                                name="currentPassword"
                                render={({ field, fieldState }) => (
                                    <FormItem className="grid gap-2 mb-4">
                                        <FormControl>
                                            <div className="relative">
                                                <Input
                                                    {...field}
                                                    aria-label="Current Password"
                                                    type={showCurrentPassword ? "text" : "password"}
                                                    className="pr-10"
                                                    placeholder="Enter current password"
                                                />
                                                <button
                                                    className="absolute -translate-y-1/2 top-1/2 -translate-x-1/2 right-2"
                                                    onClick={() => setShowCurrentPassword(!showCurrentPassword)}
                                                >
                                                    {showCurrentPassword ? (
                                                        <EyeOffIcon className="w-5 h-5" />
                                                    ) : (
                                                        <EyeIcon className="w-5 h-5" />
                                                    )}
                                                </button>
                                            </div>
                                        </FormControl>
                                        {fieldState.invalid && fieldState.error?.message && (
                                            <span className="text-xs text-red-500">
                                                {fieldState.error?.message}
                                            </span>
                                        )}
                                    </FormItem>
                                )}
                            />
                            <FormField
                                control={control}
                                name="newPassword"
                                render={({ field, fieldState }) => (
                                    <FormItem className="grid gap-2 mb-4">
                                        <FormControl>
                                            <div className="relative">
                                                <Input
                                                    {...field}
                                                    aria-label="New Password"
                                                    type={showNewPassword ? "text" : "password"}
                                                    className="pr-10"
                                                    placeholder="Enter new password"
                                                />
                                                <button
                                                    className="absolute -translate-y-1/2 top-1/2 -translate-x-1/2 right-2"
                                                    onClick={() => setShowNewPassword(!showNewPassword)}
                                                >
                                                    {showNewPassword ? (
                                                        <EyeOffIcon className="w-5 h-5" />
                                                    ) : (
                                                        <EyeIcon className="w-5 h-5" />
                                                    )}
                                                </button>
                                            </div>
                                        </FormControl>
                                        {fieldState.invalid && fieldState.error?.message && (
                                            <span className="text-xs text-red-500">
                                                {fieldState.error?.message}
                                            </span>
                                        )}
                                    </FormItem>
                                )}
                            />
                            <FormField
                                control={control}
                                name="newPasswordConfirm"
                                render={({ field, fieldState }) => (
                                    <FormItem className="grid gap-2 mb-4">
                                        <FormControl>
                                            <div className="relative">
                                                <Input
                                                    {...field}
                                                    aria-label="Confirm New Password"
                                                    type={showConfirmNewPassword ? "text" : "password"}
                                                    className="pr-10"
                                                    placeholder="Confirm new password"
                                                />
                                                <button
                                                    onClick={() => setShowConfirmNewPassword(!showConfirmNewPassword)}
                                                    className="absolute -translate-y-1/2 top-1/2 -translate-x-1/2 right-2"
                                                >
                                                    {showConfirmNewPassword ? (
                                                        <EyeOffIcon className="w-5 h-5" />
                                                    ) : (
                                                        <EyeIcon className="w-5 h-5" />
                                                    )}
                                                </button>
                                            </div>
                                        </FormControl>
                                        {fieldState.invalid && fieldState.error?.message && (
                                            <span className="text-xs text-red-500">
                                                {fieldState.error?.message}
                                            </span>
                                        )}
                                    </FormItem>
                                )}
                            />
                        </CardContent>
                        <CardFooter className="flex flex-col space-y-4 justify-end">
                            <Button disabled={isSubmitting} type="submit" size="full" className={cn("text-lg py-3")}>
                                Change Password
                            </Button>
                            <Button
                                disabled={isSubmitting}
                                variant="secondary"
                                size="full"
                                className={cn("text-lg py-3")}
                                onClick={() => navigate("/settings")}
                            >
                                <ArrowLeft
                                    className="w-5 h-5 mr-2"
                                    aria-hidden="true"
                                />
                                Back
                            </Button>
                        </CardFooter>
                    </Card>
                </form>
            </Form>
        </Layout2>
    )
}
