"use client";

import * as React from "react";
import * as Dialog from "@radix-ui/react-dialog";

type ConfirmOptions = {
    title: string;
    description?: string;
    confirmText?: string;
    cancelText?: string;
    tone?: "default" | "danger";
};

type ConfirmRequest = ConfirmOptions & {
    resolve: (value: boolean) => void;
};

type ConfirmFn = (options: ConfirmOptions) => Promise<boolean>;

const ConfirmContext = React.createContext<ConfirmFn | null>(null);

export function useConfirm(): ConfirmFn {
    const context = React.useContext(ConfirmContext);
    if (!context) {
        throw new Error("useConfirm must be used within ConfirmProvider");
    }
    return context;
}

export function ConfirmProvider({ children }: { children: React.ReactNode }) {
    const [request, setRequest] = React.useState<ConfirmRequest | null>(null);
    const [open, setOpen] = React.useState(false);

    const closeWith = React.useCallback(
        (value: boolean) => {
            if (request) {
                request.resolve(value);
                setRequest(null);
            }
            setOpen(false);
        },
        [request]
    );

    const confirm = React.useCallback<ConfirmFn>((options) => {
        return new Promise<boolean>((resolve) => {
            setRequest({ ...options, resolve });
            setOpen(true);
        });
    }, []);

    return (
        <ConfirmContext.Provider value={confirm}>
            {children}

            <Dialog.Root
                open={open}
                onOpenChange={(nextOpen) => {
                    if (!nextOpen) closeWith(false);
                    setOpen(nextOpen);
                }}
            >
                <Dialog.Portal>
                    <Dialog.Overlay className="fixed inset-0 z-[100] bg-black/45 backdrop-blur-[2px] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
                    <Dialog.Content className="fixed left-1/2 top-1/2 z-[101] w-[92vw] max-w-[460px] -translate-x-1/2 -translate-y-1/2 ui-card p-6 shadow-2xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95">
                        <Dialog.Title className="text-xl font-semibold tracking-tight text-foreground">{request?.title}</Dialog.Title>
                        {request?.description && (
                            <Dialog.Description className="mt-2 text-sm leading-relaxed text-muted-foreground">
                                {request.description}
                            </Dialog.Description>
                        )}

                        <div className="mt-6 flex justify-end gap-2">
                            <button type="button" onClick={() => closeWith(false)} className="ui-btn-secondary" aria-label={request?.cancelText || "取消"}>
                                {request?.cancelText || "取消"}
                            </button>
                            <button
                                type="button"
                                onClick={() => closeWith(true)}
                                className={request?.tone === "danger" ? "ui-btn-danger" : "ui-btn-primary"}
                                aria-label={request?.confirmText || "确认"}
                            >
                                {request?.confirmText || "确认"}
                            </button>
                        </div>
                    </Dialog.Content>
                </Dialog.Portal>
            </Dialog.Root>
        </ConfirmContext.Provider>
    );
}
