import axios from 'axios'
import { useEffect, useState } from 'react'
import type {
  Settings,
  HomepageContent,
  Treatment,
  Package,
  GalleryImage,
  Testimonial,
  TeamMember,
  BlogPost,
  Faq,
  LegalPage,
} from './types'
import {
  defaultSettings,
  defaultHomepage,
  defaultTreatments,
  defaultPackages,
  defaultGallery,
  defaultTestimonials,
  defaultTeam,
  defaultBlog,
  defaultFaqs,
  defaultLegal,
} from './defaults'

export const api = axios.create({ baseURL: '/api', timeout: 8000 })

// In-memory cache so each resource is fetched once per session.
const cache = new Map<string, unknown>()

async function fetchWithFallback<T>(path: string, fallback: T): Promise<T> {
  if (cache.has(path)) return cache.get(path) as T
  try {
    const { data } = await api.get(path)
    const value = (data?.data ?? data) as T
    cache.set(path, value)
    return value
  } catch {
    // API unreachable (static demo / local design work) — render defaults.
    cache.set(path, fallback)
    return fallback
  }
}

export const getSettings = () => fetchWithFallback<Settings>('/settings', defaultSettings)
export const getHomepage = () => fetchWithFallback<HomepageContent>('/homepage', defaultHomepage)
export const getTreatments = () => fetchWithFallback<Treatment[]>('/treatments', defaultTreatments)
export const getPackages = () => fetchWithFallback<Package[]>('/packages', defaultPackages)
export const getGallery = () => fetchWithFallback<GalleryImage[]>('/gallery', defaultGallery)
export const getTestimonials = () =>
  fetchWithFallback<Testimonial[]>('/testimonials', defaultTestimonials)
export const getTeam = () => fetchWithFallback<TeamMember[]>('/team', defaultTeam)
export const getBlog = () => fetchWithFallback<BlogPost[]>('/blog', defaultBlog)
export const getFaqs = () => fetchWithFallback<Faq[]>('/faqs', defaultFaqs)
export const getLegalPage = async (slug: string): Promise<LegalPage> => {
  const fallback = defaultLegal.find((p) => p.slug === slug) ?? defaultLegal[0]
  return fetchWithFallback<LegalPage>(`/pages/${slug}`, fallback)
}

export interface ContactPayload {
  name: string
  email: string
  phone?: string
  message: string
}

export async function submitContact(payload: ContactPayload): Promise<boolean> {
  try {
    await api.post('/contact', payload)
    return true
  } catch {
    return false
  }
}

/** Fetch a resource with loading state; falls back to bundled defaults offline. */
export function useContent<T>(fetcher: () => Promise<T>): T | null {
  const [data, setData] = useState<T | null>(null)
  useEffect(() => {
    let alive = true
    fetcher().then((d) => {
      if (alive) setData(d)
    })
    return () => {
      alive = false
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
  return data
}
