"use client";
import React, { useState, useCallback, useImperativeHandle, ForwardedRef } from "react";
import { Ban as BanIcon } from "lucide-react";
import { useForm, FormProvider } from "react-hook-form";
import { Form } from "react-compose-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import {
    Dialog,
    DialogClose,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { FormSubmit } from "@/components/form";
import { InputControl } from "@/components/form/control/input.control";
import { client } from "@/lib/auth/auth-client";
import { api } from "@/lib/trpc/client";
import type { AppRouterOutput } from "@/server/trpc/types";

type User = NonNullable<AppRouterOutput['user']['get']>;

const UserBanSchema = z.object({
    reason: z.string().min(1)
});

type UserBanValues = z.infer<typeof UserBanSchema>;

export type UserBanDialogRef = {
    open: (users: User[]) => void;
};

export type UserBanDialogProps = {
    ref?: ForwardedRef<UserBanDialogRef>;
};

export const UserBanDialog: React.FC<UserBanDialogProps> = (props) => {
    const {
        ref
    } = props;

    const [open, setOpen] = useState(false),
          [toBan, setToBan] = useState<User[]>([]);

    const utils = api.useUtils();

    const form = useForm<UserBanValues>({
        resolver: zodResolver(UserBanSchema)
    });

    const handleSubmit = useCallback(async (data: UserBanValues) => {
        try {
            for(const user of toBan) {
                await client.admin.banUser({
                    userId: user.id,
                    banReason: data.reason,
                    banExpiresIn: 60 * 60 * 24 * 7
                });
            }
        }
        finally {
            await Promise.all([
                utils.user.list.invalidate()
            ]);
        }
    }, [toBan, utils]);

    useImperativeHandle(ref, () => {
        return {
            open: (users) => {
                setOpen(true);
                setToBan(users);
            }
        };
    });

    return (
        <Dialog open={open} onOpenChange={setOpen}>
            <DialogContent>
                <FormProvider {...form}>
                    <DialogHeader>
                        <DialogTitle>Are you absolutely sure?</DialogTitle>

                        <DialogDescription>
                            This action cannot be undone. This will permanently delete your{' '}
                        </DialogDescription>
                    </DialogHeader>

                    <Form<UserBanValues>
                      formControl={form}
                      onSubmit={handleSubmit}>
                        <InputControl label="Ban reason" name="reason" />
                    </Form>

                    <DialogFooter>
                        <DialogClose asChild>
                            <Button variant="outline">
                                Cancel
                            </Button>
                        </DialogClose>

                        <FormSubmit variant='destructive' aria-label='Ban selected users'>
                            <BanIcon /> Ban
                        </FormSubmit>
                    </DialogFooter>
                </FormProvider>
            </DialogContent>
        </Dialog>
    );
};
