import React, { useState, useMemo, useCallback } from "react";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, FormProvider } from "react-hook-form";
import { Form } from "react-compose-form";
import { FormSubmit } from "@/components/form/form-submit";
import { DateControl } from "@/components/form/control/date.control";
import { Dialog, DialogTitle, DialogDescription, DialogContent, DialogHeader, DialogFooter, DialogClose } from "@/components/ui/dialog";
import type { AppRouterOutput } from "@/lib/trpc/router";
import { api } from "@/lib/trpc/client";
import { Input } from "@/components/ui/input";
import CopyButton from "@/components/ui/copy-button";

type Post = NonNullable<AppRouterOutput["posts"]["get"]>;
type Token = NonNullable<AppRouterOutput["paywallBypassToken"]["create"]>;

const PostGuestLinkDialogSchema = z.object({
    expiresAt: z.date().nullable().optional()
});

type PostGuestLinkDialogProps = {
    post: Post | null;
    onClose?: () => void;
};

export const PostGuestLinkDialog: React.FC<PostGuestLinkDialogProps> = (props) => {
    const {
        post,
        onClose
    } = props;

    const [token, setToken] = useState<Token>();

    const form = useForm<z.infer<typeof PostGuestLinkDialogSchema>>({
        resolver: zodResolver(PostGuestLinkDialogSchema)
    });

    const generatedUrl = useMemo(() => {
        if(!post || !token || token.postId !== post.id) {
            return "";
        }

        const url = new URL(process.env.NEXT_PUBLIC_APP_URL!);

        url.pathname = `${post.topic}/${post.slug}`;
        url.searchParams.set("token", token.id);

        return url.toString();
    }, [post, token]);

    const tokenCreateMutation = api.paywallBypassToken.create.useMutation();

    const handleSubmit = useCallback(async (data: z.infer<typeof PostGuestLinkDialogSchema>) => {
        if(!post) {
            return;
        }

        const token = await tokenCreateMutation.mutateAsync({
            data: {
                ...data,
                postId: post.id
            }
        });

        setToken(token);
    }, [post, tokenCreateMutation]);

    return (
        <Dialog
          open={!!post}
          onOpenChange={(open) => {
            if(!open) {
                onClose?.();
                setToken(undefined);
            }
          }}>
            {post && !generatedUrl && (
                <DialogContent onSubmit={(e) => e.stopPropagation()}>
                    <FormProvider {...form}>
                        <DialogHeader>
                            <DialogTitle>
                                Guest Link
                            </DialogTitle>

                            <DialogDescription>
                                Generate a guest link for the post <span className="font-medium text-foreground">{post.title}</span>
                            </DialogDescription>
                        </DialogHeader>

                        <Form<z.infer<typeof PostGuestLinkDialogSchema>, HTMLFormElement>
                          formControl={form}
                          id="gust-link-form"
                          onSubmit={handleSubmit}>
                            <DateControl
                              label="Expiration"
                              name="expiresAt" />
                        </Form>

                        <DialogFooter>
                            <DialogClose>Close</DialogClose>

                            <FormSubmit form="gust-link-form">
                                Generate
                            </FormSubmit>
                        </DialogFooter>
                    </FormProvider>
                </DialogContent>
            )}

            {generatedUrl && post && (
                <DialogContent>
                    <DialogHeader>
                        <DialogTitle>
                            Guest Link
                        </DialogTitle>

                        <DialogDescription>
                            Here is the guest link for the post <span className="font-medium text-foreground">{post.title}</span>
                        </DialogDescription>
                    </DialogHeader>

                    <div className="flex items-center gap-2">
                        <Input readOnly value={generatedUrl} />
                        <CopyButton textToCopy={generatedUrl} />
                    </div>

                    <DialogFooter>
                        <DialogClose>Close</DialogClose>
                    </DialogFooter>
                </DialogContent>
            )}
        </Dialog>
    );
};
