
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { useAuth } from '@/contexts/AuthContext';
import { useToast } from '@/hooks/use-toast';

const CustomVariablesContext = createContext(null);

export const useCustomVariables = () => {
  const context = useContext(CustomVariablesContext);
  if (!context) {
    return { variables: [], fetchVariables: () => {}, loading: false, error: null, updateVariable: () => {}, deleteVariable: () => {}, createVariable: () => {} };
  }
  return context;
};

export const CustomVariablesProvider = ({ children }) => {
  const { user } = useAuth();
  const { toast } = useToast();
  const [variables, setVariables] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  
  // Cache to prevent redundant fetches
  const [currentClientId, setCurrentClientId] = useState(null);

  const fetchVariables = useCallback(async (clientId, force = false) => {
    if (!clientId) {
        setVariables([]);
        return;
    }
    
    // If we already have data for this client and not forcing, return
    if (clientId === currentClientId && variables.length > 0 && !force) {
        return;
    }

    setLoading(true);
    setError(null);
    setCurrentClientId(clientId);

    try {
      const { data, error } = await supabase
        .from('custom_variables')
        .select('*')
        .eq('client_id', clientId)
        .order('variable_name');

      if (error) throw error;
      setVariables(data || []);
    } catch (err) {
      console.error('Error fetching custom variables:', err);
      setError(err.message);
      toast({
        variant: "destructive",
        title: "Error fetching variables",
        description: err.message
      });
    } finally {
      setLoading(false);
    }
  }, [currentClientId, variables.length, toast]);

  const refreshVariables = useCallback(() => {
    if (currentClientId) {
      fetchVariables(currentClientId, true);
    }
  }, [currentClientId, fetchVariables]);

  // Real-time updates
  useEffect(() => {
    if (!currentClientId) return;

    const channel = supabase
      .channel('custom_variables_changes')
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'custom_variables',
          filter: `client_id=eq.${currentClientId}`
        },
        () => {
          refreshVariables();
        }
      )
      .subscribe();

    return () => {
      supabase.removeChannel(channel);
    };
  }, [currentClientId, refreshVariables]);

  const createVariable = async (clientId, variableData) => {
      try {
        const { data, error } = await supabase
            .from('custom_variables')
            .insert([{ ...variableData, client_id: clientId }])
            .select()
            .single();
            
        if (error) throw error;
        
        setVariables(prev => [...prev, data].sort((a, b) => a.variable_name.localeCompare(b.variable_name)));
        toast({ title: "Success", description: "Variable created." });
        return data;
      } catch (err) {
        console.error("Create var error", err);
        toast({ variant: "destructive", title: "Error", description: err.message });
        throw err;
      }
  };

  const updateVariable = async (id, updates) => {
      try {
        const { data, error } = await supabase
            .from('custom_variables')
            .update(updates)
            .eq('id', id)
            .select()
            .single();
            
        if (error) throw error;
        
        setVariables(prev => prev.map(v => v.id === id ? data : v));
        toast({ title: "Success", description: "Variable updated." });
        return data;
      } catch (err) {
         console.error("Update var error", err);
         toast({ variant: "destructive", title: "Error", description: err.message });
         throw err;
      }
  };

  const deleteVariable = async (id) => {
      try {
        const { error } = await supabase
            .from('custom_variables')
            .delete()
            .eq('id', id);
            
        if (error) throw error;
        
        setVariables(prev => prev.filter(v => v.id !== id));
        toast({ title: "Success", description: "Variable deleted." });
      } catch (err) {
         console.error("Delete var error", err);
         toast({ variant: "destructive", title: "Error", description: err.message });
         throw err;
      }
  };

  const getVariableByName = useCallback((name) => {
     const cleanName = name.replace(/[{}]/g, '');
     return variables.find(v => v.variable_name.replace(/[{}]/g, '') === cleanName);
  }, [variables]);

  const searchVariables = useCallback((term) => {
      const lowerTerm = term.toLowerCase();
      return variables.filter(v => 
          v.variable_name.toLowerCase().includes(lowerTerm) || 
          v.display_label.toLowerCase().includes(lowerTerm)
      );
  }, [variables]);

  return (
    <CustomVariablesContext.Provider value={{
      variables,
      loading,
      error,
      fetchVariables,
      refreshVariables,
      createVariable,
      updateVariable,
      deleteVariable,
      getVariableByName,
      searchVariables
    }}>
      {children}
    </CustomVariablesContext.Provider>
  );
};
