import type { InjectionKey, Plugin } from 'vue'
import { Bagel } from '@bagelink/sdk'
import FloatingVue from 'floating-vue'
import { inject } from 'vue'

import lightboxPlugin from '../components/lightbox/index'
import { ripple, pattern } from '../directives'
import { useLang } from '../utils'
import clickOutside from '../utils/clickOutside'

export const bagelInjectionKey = Symbol('bagel') as InjectionKey<Bagel>
export const i18nTInjectionKey = Symbol('bagel') as InjectionKey<(key: string) => string>

export function useBagel(injectionKey: InjectionKey<Bagel> = bagelInjectionKey): Bagel {
	const bagel = inject(injectionKey)
	if (!bagel) throw new Error('No bagel provided')
	return bagel
}

export function useI18nT(injectionKey: typeof i18nTInjectionKey = i18nTInjectionKey) {
	const i18nT = inject(injectionKey)
	if (!i18nT) throw new Error('No i18nT provided')
	return i18nT
}

export interface BagelOptions {
	availableLangs?: string[]
	defaultLang?: string
	language?: string
	host?: string
	fileBaseUrl?: string
	onError?: (err: Error) => void

	i18nT?: (key: string) => string
}
export const BagelVue: Plugin<BagelOptions> = {
	install: (app, options) => {
		const bagel = new Bagel({ host: options.host, fileBaseUrl: options.fileBaseUrl, onError: options.onError })
		app.directive('click-outside', clickOutside)
		app.directive('ripple', ripple)
		app.directive('pattern', pattern)
		app.use(lightboxPlugin)
		app.use(FloatingVue, {
			themes: {
				'bgl-theme': {
					triggers: ['click'],
					autoHide: true,
					placement: 'bottom',
				},
			},
		})
		const { availableLangs, defaultLang, lang } = useLang()
		if (options.availableLangs) availableLangs.value = options.availableLangs
		if (options.defaultLang) defaultLang.value = options.defaultLang
		if (options.language) lang.value = options.language
		app.config.globalProperties.$bagel = bagel
		app.provide(bagelInjectionKey, bagel)
		app.config.globalProperties.$i18T
			= options.i18nT || ((key?: string) => key)
		app.provide(i18nTInjectionKey, options.i18nT || ((key: string) => key))
	},
}
