import { createContext, ReactNode, useContext } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient";

interface Settings {
  siteTitle: string;
  siteTitleAr: string;
  logoText: string;
  logoTextAr: string;
  homeBannerTitle: string;
  homeBannerTitleAr: string;
  homeBannerDescription: string;
  homeBannerDescriptionAr: string;
  authWelcomeTitle: string;
  authWelcomeTitleAr: string;
  authDescription: string;
  authDescriptionAr: string;
  statsCard1Title: string;
  statsCard1TitleAr: string;
  statsCard1Description: string;
  statsCard1DescriptionAr: string;
  statsCard2Title: string;
  statsCard2TitleAr: string;
  statsCard2Description: string;
  statsCard2DescriptionAr: string;
  enableRegistration: boolean;
  openaiApiKey: string;
  firebaseApiKey: string;
  firebaseProjectId: string;
  firebaseAppId: string;
  firebaseMessagingSenderId: string;
  firebaseVapidKey: string;
  pusherAppId: string;
  pusherKey: string;
  pusherSecret: string;
  pusherCluster: string;
  deepgramApiKey: string;
  sendgridApiKey: string;
  sendgridFromEmail: string;
}

interface SettingsContextType {
  settings: Settings | null;
  isLoading: boolean;
  error: Error | null;
  updateSettings: (newSettings: Partial<Settings>) => Promise<void>;
}

const SettingsContext = createContext<SettingsContextType | null>(null);

export function SettingsProvider({ children }: { children: ReactNode }) {
  const { toast } = useToast();

  const { data: settings, error, isLoading } = useQuery<Settings>({
    queryKey: ["/api/settings"],
    queryFn: async () => {
      try {
        const response = await apiRequest("GET", "/api/settings");
        if (!response.ok) {
          throw new Error("Failed to fetch settings");
        }
        return response.json();
      } catch (error) {
        console.error("Error fetching settings:", error);
        throw error;
      }
    },
    retry: 3,
    retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
  });

  const updateSettingsMutation = useMutation({
    mutationFn: async (newSettings: Partial<Settings>) => {
      const response = await apiRequest("POST", "/api/settings", newSettings);
      if (!response.ok) {
        throw new Error("Failed to update settings");
      }
      return response.json();
    },
    onSuccess: (newSettings: Settings) => {
      queryClient.setQueryData(["/api/settings"], newSettings);
      toast({
        title: "Settings updated",
        description: "Your settings have been saved successfully.",
      });
    },
    onError: (error: Error) => {
      console.error("Error updating settings:", error);
      toast({
        title: "Error",
        description: error.message || "Failed to update settings. Please try again.",
        variant: "destructive",
      });
    },
  });

  const updateSettings = async (newSettings: Partial<Settings>) => {
    try {
      await updateSettingsMutation.mutateAsync(newSettings);
    } catch (error) {
      console.error("Error in updateSettings:", error);
      throw error;
    }
  };

  return (
    <SettingsContext.Provider
      value={{
        settings: settings ?? null,
        isLoading,
        error: error instanceof Error ? error : null,
        updateSettings,
      }}
    >
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettings() {
  const context = useContext(SettingsContext);
  if (!context) {
    throw new Error("useSettings must be used within a SettingsProvider");
  }
  return context;
}