import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ReactNode,
} from 'react'
import { applyDocumentFavicon } from '@meshkee/dashboard-core'
import { useLocale } from '@meshkee/dashboard-ui'
import { isAbortError } from '../lib/api'
import { getTenantDomain } from '../lib/config'
import { getWebsiteBusinessInfo } from '../services/websiteService'
import { resolveTenantByDomain } from '../services/tenantService'

interface TenantBrandingContextValue {
  businessName: string
  logoUrl: string | null
  faviconUrl: string | null
}

const TenantBrandingContext = createContext<TenantBrandingContextValue | null>(null)

function pickBusinessName(
  ...candidates: Array<string | null | undefined>
): string {
  for (const value of candidates) {
    const trimmed = value?.trim()
    if (trimmed) return trimmed
  }
  return ''
}

export function TenantBrandingProvider({ children }: { children: ReactNode }) {
  const { setLocale } = useLocale()
  const [businessName, setBusinessName] = useState('')
  const [logoUrl, setLogoUrl] = useState<string | null>(null)
  const [faviconUrl, setFaviconUrl] = useState<string | null>(null)
  const defaultLocaleAppliedRef = useRef(false)
  const domain = getTenantDomain()

  useEffect(() => {
    const controller = new AbortController()

    async function loadBranding() {
      try {
        const [tenant, info] = await Promise.all([
          resolveTenantByDomain(domain, controller.signal),
          getWebsiteBusinessInfo(domain, controller.signal).catch(() => null),
        ])

        if (controller.signal.aborted) return

        const name = pickBusinessName(
          info?.nameFa,
          info?.name,
          tenant.nameFa,
          tenant.name,
          domain,
        )

        const nextLogo =
          info?.logoUrl?.trim() || tenant.logoUrl?.trim() || null
        const nextFavicon =
          info?.faviconUrl?.trim() ||
          tenant.faviconUrl?.trim() ||
          nextLogo ||
          null

        setBusinessName(name || domain)
        setLogoUrl(nextLogo)
        setFaviconUrl(nextFavicon)
        applyDocumentFavicon(nextFavicon)

        if (!defaultLocaleAppliedRef.current) {
          defaultLocaleAppliedRef.current = true
          if (tenant.defaultLocale === 'en' || tenant.defaultLocale === 'fa') {
            setLocale(tenant.defaultLocale)
          } else {
            setLocale('fa')
          }
        }
      } catch (err) {
        if (isAbortError(err) || controller.signal.aborted) return
        setBusinessName(domain)
        setLogoUrl(null)
        setFaviconUrl(null)
        applyDocumentFavicon(null)
      }
    }

    void loadBranding()

    return () => {
      controller.abort()
    }
  }, [domain, setLocale])

  const value = useMemo(
    () => ({ businessName, logoUrl, faviconUrl }),
    [businessName, logoUrl, faviconUrl],
  )

  return (
    <TenantBrandingContext.Provider value={value}>{children}</TenantBrandingContext.Provider>
  )
}

export function useTenantBranding() {
  const context = useContext(TenantBrandingContext)
  if (!context) {
    throw new Error('useTenantBranding must be used within TenantBrandingProvider')
  }
  return context
}
