import type { App, InjectionKey, Plugin } from 'vue'
import type { PluginOptions as ToastOptions } from 'vue-toastification'
import { inject } from 'vue'
import * as VueToastification from 'vue-toastification'
import CustomToast from '../components/Toast.vue'
import 'vue-toastification/dist/index.css'
import '../styles/toast-overrides.css'

const Toast = (VueToastification as any).default || VueToastification
const { POSITION } = VueToastification as any
const useVueToast = (VueToastification as any).useToast

export interface ToastApi {
	success: (message: string, options?: any) => void
	error: (message: string, options?: any) => void
	info: (message: string, options?: any) => void
	warning: (message: string, options?: any) => void
	show: (message: string, options?: any) => void
	clear: () => void
}

export const ToastSymbol: InjectionKey<ToastApi> = Symbol('toast')

// Global singleton instance as fallback (created on first plugin install)
let globalToastApi: ToastApi | null = null

export function useToast(): ToastApi {
	const toastApi = inject(ToastSymbol, null)
	if (!toastApi) {
		// Fallback to global singleton if injection fails
		if (globalToastApi) {
			return globalToastApi
		}
		throw new Error('Toast API not provided. Make sure ToastPlugin is installed via app.use(ToastPlugin)')
	}
	return toastApi
}

export type BagelToastOptions = Partial<ToastOptions>

function getToastContainer(): HTMLElement | undefined {
	if (typeof document === 'undefined') return undefined
	let el = document.getElementById('bgl-toast-container')
	if (!el) {
		el = document.createElement('div')
		el.setAttribute('popover', 'manual')
		el.setAttribute('id', 'bgl-toast-container')
		document.body.appendChild(el)
	}
	// Re-stack on top of any open dialogs
	try { (el as any).hidePopover() } catch {}
	try { (el as any).showPopover() } catch {}
	return el
}

export const ToastPlugin: Plugin<BagelToastOptions[]> = {
	install: (app: App, options: BagelToastOptions = {}) => {
		const container = getToastContainer()

		const defaultOptions: ToastOptions = {
			position: POSITION.TOP_RIGHT,
			timeout: 5000,
			closeOnClick: true,
			pauseOnFocusLoss: true,
			pauseOnHover: true,
			draggable: true,
			draggablePercent: 0.6,
			showCloseButtonOnHover: false,
			hideProgressBar: true,
			closeButton: false,
			icon: false,
			rtl: false,
			transition: 'Vue-Toastification__fade',
			maxToasts: 5,
			newestOnTop: true,
			toastClassName: 'custom-toast-wrapper',
			bodyClassName: 'custom-toast-body',
			...(container ? { container } : {}),
			...options,
		}

		// Install vue-toastification
		app.use(Toast, defaultOptions)

		function restackToastContainer() {
			const el = typeof document !== 'undefined' ? document.getElementById('bgl-toast-container') : null
			if (el) {
				try { (el as any).hidePopover() } catch {}
				try { (el as any).showPopover() } catch {}
			}
		}

		// Create the API wrapper using lazy evaluation
		const api: ToastApi = {
			success: (message: string, opts?: any) => {
				restackToastContainer()
				const toast = useVueToast()
				return toast({
					component: CustomToast,
					props: {
						message,
						type: 'success',
					},
				}, opts)
			},
			error: (message: string, opts?: any) => {
				restackToastContainer()
				const toast = useVueToast()
				return toast({
					component: CustomToast,
					props: {
						message,
						type: 'error',
					},
				}, opts)
			},
			info: (message: string, opts?: any) => {
				restackToastContainer()
				const toast = useVueToast()
				return toast({
					component: CustomToast,
					props: {
						message,
						type: 'info',
					},
				}, opts)
			},
			warning: (message: string, opts?: any) => {
				restackToastContainer()
				const toast = useVueToast()
				return toast({
					component: CustomToast,
					props: {
						message,
						type: 'warning',
					},
				}, opts)
			},
			show: (message: string, opts?: any) => {
				restackToastContainer()
				const toast = useVueToast()
				return toast({
					component: CustomToast,
					props: {
						message,
						type: 'info',
					},
				}, opts)
			},
			clear: () => {
				const toast = useVueToast()
				toast.clear()
			},
		}

		// Set global singleton on first install
		if (!globalToastApi) {
			globalToastApi = api
		}

		app.provide(ToastSymbol, api)
	},
}
