import { inject } from 'vue';
import type { InjectionKey } from 'vue';

export type KviewToastType = 'success' | 'error' | 'warning' | 'info';

export interface KviewToastPayload {
    id?: string;
    type?: KviewToastType;
    title?: string;
    message?: string;
    icon?: string;
    duration?: number;
}

export type KviewToastInput = string | KviewToastPayload;
export type KviewToastResolver<T> = KviewToastInput | ((value: T) => KviewToastInput);

export interface KviewToastPromiseStates<T> {
    loading?: KviewToastInput;
    success?: KviewToastResolver<T>;
    error?: KviewToastResolver<unknown>;
}

export interface KviewToastApi {
    show: (input: KviewToastInput, overrides?: KviewToastPayload) => string;
    update: (id: string, input?: KviewToastInput, overrides?: KviewToastPayload) => string;
    dismiss: (id: string) => void;
    promise: <T>(promise: PromiseLike<T>, states?: KviewToastPromiseStates<T>) => Promise<T>;
    success: (input: KviewToastInput, overrides?: KviewToastPayload) => string;
    error: (input: KviewToastInput, overrides?: KviewToastPayload) => string;
    warning: (input: KviewToastInput, overrides?: KviewToastPayload) => string;
    info: (input: KviewToastInput, overrides?: KviewToastPayload) => string;
}

export const kviewToastKey: InjectionKey<KviewToastApi> = Symbol('KviewToast');

export const useKviewToast = (): KviewToastApi => {
    const api = inject(kviewToastKey, null);

    if (!api) {
        throw new Error('useKviewToast() requires an ancestor KviewToastProvider.');
    }

    return api;
};
