import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import file from "~/lib/api/client/file";
import server from "~/lib/api/client/server";
import { ModalType, useModalStore } from "~/stores/modal-store";
import { Button } from "../ui/button";
import {
    Dialog,
    DialogClose,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "../ui/dialog";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "../ui/form";
import { IconUploadField } from "../ui/icon-upload-field";
import { Input } from "../ui/input";

const schema = z.object({
    name: z.string().min(1).max(32),
    icon: z.instanceof(File).optional(),
});

export default function CreateServerModal() {
    const { type, isOpen, onClose } = useModalStore();

    const isModalOpen = type === ModalType.CREATE_SERVER && isOpen;

    let form = useForm<z.infer<typeof schema>>({
        resolver: zodResolver(schema),
    });

    const onOpenChange = (openState: boolean) => {
        form.reset();
        onClose();
    };

    const onSubmit = async (values: z.infer<typeof schema>) => {
        let iconId = undefined;
        if (values.icon) {
            iconId = (await file.uploadFile(values.icon))[0];
        }

        const response = await server.create({
            name: values.name,
            iconId,
        });

        form.reset();
        onClose();
    };

    return (
        <Dialog open={isModalOpen} onOpenChange={onOpenChange}>
            <DialogContent className="sm:max-w-md">
                <DialogHeader>
                    <DialogTitle>Create server</DialogTitle>
                    <DialogDescription>Give your server a name and choose a server icon.</DialogDescription>
                </DialogHeader>

                <Form {...form}>
                    <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
                        <FormField
                            control={form.control}
                            name="icon"
                            render={({ field, fieldState }) => (
                                <FormItem>
                                    <FormLabel required={!schema.shape.icon.isOptional()}>Icon</FormLabel>
                                    <FormControl>
                                        <div className="flex flex-col items-center justify-center">
                                            <IconUploadField field={field} error={fieldState.error} />
                                        </div>
                                    </FormControl>
                                    <FormMessage />
                                </FormItem>
                            )}
                        />
                        <FormField
                            control={form.control}
                            name="name"
                            render={({ field }) => (
                                <FormItem>
                                    <FormLabel required={!schema.shape.name.isOptional()}>Name</FormLabel>
                                    <FormControl>
                                        <Input {...field} />
                                    </FormControl>
                                    <FormMessage />
                                </FormItem>
                            )}
                        />
                        <DialogFooter className=" justify-between">
                            <DialogClose asChild>
                                <Button type="button" variant="secondary">
                                    Close
                                </Button>
                            </DialogClose>
                            <Button type="submit" disabled={form.formState.isSubmitting}>
                                {form.formState.isSubmitting ? "Creating..." : "Create"}
                            </Button>
                        </DialogFooter>
                    </form>
                </Form>
            </DialogContent>
        </Dialog>
    );
}
