import {
  computed,
  inject,
  provide,
  toRef,
  type ComputedRef,
  type InjectionKey,
  type MaybeRefOrGetter,
  type Ref,
} from 'vue'

/** App-wide localizable strings baked into shipped components. Flat by design. */
export interface TvuLocale {
  previous: string
  next: string
  /** Noun used in the page-size selector, e.g. "10/Page". */
  pageUnit: string
  close: string
  clearValue: string
  removeOption: string
  decrement: string
  increment: string
}

/** English defaults — byte-equal to the previously-hardcoded strings. Frozen. */
export const defaultLocale: Readonly<TvuLocale> = Object.freeze({
  previous: 'Previous',
  next: 'Next',
  pageUnit: 'Page',
  close: 'Close',
  clearValue: 'Clear value',
  removeOption: 'Remove option',
  decrement: 'decrement',
  increment: 'increment',
})

/** Injection key for consumers who prefer `app.provide(TVU_LOCALE_KEY, ref({...}))`. */
export const TVU_LOCALE_KEY: InjectionKey<Ref<Partial<TvuLocale>>> = Symbol('tvu-locale')

/**
 * Provide a locale from a component setup() at (or near) the app root.
 * Accepts a plain object, a ref, or a getter — normalized to a ref so a
 * reactive source propagates to every consuming component.
 */
export function provideTvuLocale(locale: MaybeRefOrGetter<Partial<TvuLocale>>): void {
  provide(TVU_LOCALE_KEY, toRef(locale))
}

/**
 * Read the effective locale inside a component. Returns a ComputedRef of the
 * full dictionary: the injected partial merged over the English defaults.
 */
export function useLocale(): ComputedRef<TvuLocale> {
  const injected = inject(TVU_LOCALE_KEY, null)
  return computed(() => ({ ...defaultLocale, ...(injected?.value ?? {}) }))
}
