"use client" import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from "react" import { useTheme } from "next-themes" // Define material types export type MaterialType = { id: string name: string description: string isGlass?: boolean opacity?: number blurAmount?: string cssClass: string lightClass?: string darkClass?: string backgroundPrimary?: { light: string dark: string darkOpacity?: number } } // Define the context type type MaterialContextType = { materials: MaterialType[] selectedMaterial: MaterialType | null setSelectedMaterial: (material: MaterialType) => void getThemeAwareClass: (material: MaterialType) => string getThemeAwareCss: (material: MaterialType) => string getBackgroundPrimaryColor: () => string } // Define available materials const materials: MaterialType[] = [ { id: "flat", name: "Flat", description: "Solid color with no transparency", isGlass: false, cssClass: "flat-material", lightClass: "bg-card", darkClass: "bg-card", backgroundPrimary: { light: "#ffffff", dark: "#0a0a0a" }, }, { id: "glass", name: "Glass", description: "Translucent material with blur effect", isGlass: true, opacity: 0.7, blurAmount: "36px", cssClass: "glass-material", lightClass: "bg-card/70 backdrop-blur-[36px]", darkClass: "bg-card/70 backdrop-blur-[36px]", backgroundPrimary: { light: "rgba(255, 255, 255, 0.7)", dark: "rgba(17, 17, 17, 0.7)", darkOpacity: 0.85 }, }, ] // Create the context const MaterialContext = createContext(undefined) export function MaterialProvider({ children }: { children: ReactNode }) { const { theme } = useTheme() const [selectedMaterial, setSelectedMaterial] = useState(materials[0]) const [mounted, setMounted] = useState(false) // Set mounted state after hydration useEffect(() => { setMounted(true) }, []) // Apply material to the document useEffect(() => { if (!mounted || !selectedMaterial) return const root = document.documentElement // Set data attributes for CSS to use root.setAttribute("data-material", selectedMaterial.id) if (selectedMaterial.isGlass) { root.setAttribute("data-glass-opacity", selectedMaterial.opacity?.toString() || "0.7") root.setAttribute("data-glass-blur", selectedMaterial.blurAmount || "36px") // Dispatch a custom event when switching to glass material const event = new CustomEvent("materialChanged", { detail: { material: selectedMaterial.id, isGlass: true, }, }) window.dispatchEvent(event) } else { root.removeAttribute("data-glass-opacity") root.removeAttribute("data-glass-blur") // Dispatch a custom event when switching from glass material const event = new CustomEvent("materialChanged", { detail: { material: selectedMaterial.id, isGlass: false, }, }) window.dispatchEvent(event) } }, [selectedMaterial, mounted]) // Function to get the appropriate CSS class based on theme and material const getThemeAwareClass = useCallback( (material: MaterialType): string => { if (!material) return "" return theme === "dark" ? material.darkClass || "" : material.lightClass || "" }, [theme], ) const getThemeAwareCss = useCallback( (material: MaterialType): string => { if (!material) return "" return theme === "dark" ? material.darkClass || "" : material.lightClass || "" }, [theme], ) const getBackgroundPrimaryColor = useCallback(() => { if (!selectedMaterial) return "" return theme === "dark" ? selectedMaterial.backgroundPrimary?.dark || "" : selectedMaterial.backgroundPrimary?.light || "" }, [selectedMaterial, theme]) const contextValue = { materials, selectedMaterial, setSelectedMaterial, getThemeAwareClass, getThemeAwareCss, getBackgroundPrimaryColor, } return {children} } export function useMaterial() { const context = useContext(MaterialContext) if (context === undefined) { throw new Error("useMaterial must be used within a MaterialProvider") } return context }