"use client";
import React, { useState, useCallback, useImperativeHandle, ForwardedRef } from "react";
import { FormProvider } from "react-hook-form";
import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { FormSubmit } from "@/components/form";
import { Button } from "@/components/ui/button";
import { useTranslations } from "next-intl";
import { useTagForm, TagForm, TagFormValues } from "@/components/dashboard/tag/forms/tag.form";
import { api } from "@/lib/trpc/client";
import type { AppRouterOutput } from "@/server/trpc/types";

type Tag = NonNullable<AppRouterOutput["tags"]["get"]>;

export type TagModalEditorRef = {
    open: (data?: Tag) => void;
};

type TagModalEditorProps = {
    ref?: ForwardedRef<TagModalEditorRef>;
    onCreate?: (tag: Tag) => void;
};

export const TagModalEditor: React.FC<TagModalEditorProps> = (props) => {
    const t = useTranslations("dashboard.tag");
    const {
        ref,
        onCreate
    } = props;

    const [isOpen, setOpen] = useState(false),
          [tagId, setTagId] = useState<string>();

    const form = useTagForm({});

    const utils = api.useUtils();
    const createMutation = api.tags.create.useMutation({
        async onSuccess(tag) {
            setOpen(false);

            if(onCreate) {
                onCreate(tag);
            }

            await Promise.all([
                utils.tags.list.invalidate(),
                utils.tags.count.invalidate(),
                utils.tags.paginate.invalidate()
            ]);
        },
        onError(error) {
            console.log(error);
        }
    });

    const updateMutation = api.tags.update.useMutation({
        async onSuccess() {
            setOpen(false);
            setTagId(undefined)

            await Promise.all([
                utils.tags.list.invalidate(),
                utils.tags.count.invalidate()
            ]);
        }
    });

    const handleOpen = useCallback((data?: Tag) => {
        const {
            id = undefined,
            name = ""
        } = data || {};

        form.setValue("name", name);

        setOpen(true);
        setTagId(id);
    }, [form]);

    const handleOpenChange = useCallback((open: boolean) => {
        setOpen(open);
    }, []);

    const handleSubmit = useCallback(async (data: TagFormValues) => {
        if(!tagId) {
            await createMutation.mutateAsync({
                data
            });
        }
        else {
            await updateMutation.mutateAsync({
                id: tagId,
                data
            });
        }
    }, [tagId, createMutation, updateMutation]);

    useImperativeHandle(ref, (): TagModalEditorRef => {
        return {
            open: handleOpen
        };
    }, [handleOpen]);

    return (
        <Dialog
          open={isOpen}
          onOpenChange={handleOpenChange}>
            <DialogContent
              onSubmit={(e) => e.stopPropagation()}>
                <FormProvider {...form}>
                    <DialogHeader>
                        <DialogTitle>
                            { !tagId ? t("editor.create.title") : t("editor.edit.title") }
                        </DialogTitle>
                    </DialogHeader>

                    <TagForm
                      id="create-tag"
                      formControl={form}
                      onSubmit={handleSubmit} />

                    <DialogFooter>
                        <DialogClose asChild>
                            <Button variant="outline">{t("actions.cancel")}</Button>
                        </DialogClose>

                        <FormSubmit form="create-tag">
                            {t("actions.create")}
                        </FormSubmit>
                    </DialogFooter>
                </FormProvider>
            </DialogContent>
        </Dialog>
    );
};
