import { useState, useCallback, useEffect, useRef } from 'react';
import { supabase } from '@/integrations/supabase/client';
import { useToast } from '@/hooks/use-toast';
import { addDays } from 'date-fns';
import { useAuth } from '@/contexts/AuthContext';

export function useWorkflowTemplates(initialClientId = null) {
  const [templates, setTemplates] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [lastUpdated, setLastUpdated] = useState(null);
  const { toast } = useToast();
  const { user } = useAuth();
  
  const subscriptionRef = useRef(null);

  useEffect(() => {
    try {
      const cached = localStorage.getItem('workflow_templates_cache');
      if (cached) {
        const parsed = JSON.parse(cached);
        if (Date.now() - parsed.timestamp < 3600000) {
           setTemplates(parsed.data);
           setLastUpdated(new Date(parsed.timestamp));
        }
      }
    } catch (e) {
      console.warn('Failed to load templates cache', e);
    }
  }, []);

  const getTemplates = useCallback(async (clientId = initialClientId) => {
    try {
      setLoading(true);
      setError(null);

      let query = supabase
        .from('workflow_templates')
        .select(`
          *,
          workflow_template_tasks (
            id, 
            task_name, 
            task_description, 
            days_until_due, 
            task_sequence, 
            priority, 
            assigned_to
          )
        `)
        .order('created_at', { ascending: false });

      if (clientId) {
        query = query.eq('client_id', clientId);
      }

      const { data, error: fetchError } = await query;
      
      if (fetchError) throw fetchError;
      
      setTemplates(data || []);
      setLastUpdated(new Date());
      
      localStorage.setItem('workflow_templates_cache', JSON.stringify({
        timestamp: Date.now(),
        data: data || []
      }));

      return data || [];
    } catch (err) {
      console.error('Error fetching templates:', err);
      setError(err.message);
      toast({ 
        variant: "destructive", 
        title: "Error fetching templates", 
        description: err.message 
      });
      return [];
    } finally {
      setLoading(false);
    }
  }, [initialClientId, toast]);

  useEffect(() => {
    if (!user) return;

    const channel = supabase
      .channel('workflow_templates_changes')
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'workflow_templates'
        },
        () => {
          getTemplates(initialClientId); 
        }
      )
      .subscribe();

    subscriptionRef.current = channel;

    return () => {
      supabase.removeChannel(channel);
    };
  }, [user, initialClientId, getTemplates]);

  const createTemplate = async (templateData, tasks) => {
    try {
      setLoading(true);

      if (!templateData.name) throw new Error("Template name is required");
      if (!user?.id) throw new Error("User must be authenticated to create templates");

      const templateToInsert = {
        ...templateData,
        created_by: user.id,
        created_at: new Date().toISOString(),
        updated_at: new Date().toISOString()
      };

      const { data: template, error: templateError } = await supabase
        .from('workflow_templates')
        .insert([templateToInsert])
        .select()
        .single();

      if (templateError) throw templateError;

      if (tasks && tasks.length > 0) {
        const tasksWithId = tasks.map((task, index) => ({
          template_id: template.id,
          task_name: task.task_name,
          task_description: task.task_description || '',
          days_until_due: parseInt(task.days_until_due) || 0,
          task_sequence: index + 1,
          priority: task.priority || 'medium',
          assigned_to: task.assigned_to,
          created_at: new Date().toISOString()
        }));

        const { error: tasksError } = await supabase
          .from('workflow_template_tasks')
          .insert(tasksWithId);

        if (tasksError) {
          await supabase.from('workflow_templates').delete().eq('id', template.id);
          throw new Error(`Failed to create template tasks: ${tasksError.message}`);
        }
      }
      
      return true;
    } catch (error) {
      console.error('Error creating template:', error);
      toast({ variant: "destructive", title: "Error", description: error.message });
      return false;
    } finally {
      setLoading(false);
    }
  };

  const deleteTemplate = async (templateId) => {
    try {
      setLoading(true);
      
      const { error: tasksError } = await supabase
        .from('workflow_template_tasks')
        .delete()
        .eq('template_id', templateId);

      if (tasksError) console.warn('Task deletion warning:', tasksError);

      const { error } = await supabase
        .from('workflow_templates')
        .delete()
        .eq('id', templateId);

      if (error) throw error;
      
      toast({ title: "Success", description: "Template deleted successfully." });
      return true;
    } catch (error) {
      console.error('Error deleting template:', error);
      toast({ variant: "destructive", title: "Error", description: error.message });
      return false;
    } finally {
      setLoading(false);
    }
  };

  const applyTemplate = async (templateId, parentTaskData, propertyId = null) => {
    try {
      setLoading(true);
      
      const { data: templateTasks, error: fetchError } = await supabase
        .from('workflow_template_tasks')
        .select('*')
        .eq('template_id', templateId)
        .order('task_sequence');

      if (fetchError) throw fetchError;
      
      let finalDescription = parentTaskData.description || '';
      let unitLabel = '';
      if (propertyId) {
          const { data: unitData } = await supabase
             .from('units')
             .select('unit_number, address')
             .eq('id', propertyId)
             .single();
          
          if (unitData) {
              unitLabel = `Unit ${unitData.unit_number || ''}${unitData.address ? ' - ' + unitData.address : ''}`;
              finalDescription += `\n\nProperty: ${unitLabel}`;
          }
      }

      if (!parentTaskData.association_id && !parentTaskData.client_id) {
        throw new Error("An association must be selected to apply a workflow.");
      }

      const resolvedAssociationId = parentTaskData.association_id || parentTaskData.client_id;

      const { data: parentTask, error: parentError } = await supabase
        .from('tasks')
        .insert([{
          ...parentTaskData,
          association_id: resolvedAssociationId,
          description: finalDescription,
          status: 'pending',
          template_id: templateId,
          property_id: propertyId,
          client_specific: !!propertyId
        }])
        .select()
        .single();

      if (parentError) throw parentError;

      if (templateTasks?.length > 0) {
        const subtasks = templateTasks.map(t => ({
              title: t.task_name,
              description: (t.task_description || '') + (unitLabel ? `\n\nProperty: ${unitLabel}` : ''),
              priority: t.priority,
              assigned_to: t.assigned_to || parentTaskData.assigned_to, 
              days_until_due: t.days_until_due,
              task_sequence: t.task_sequence,
              parent_task_id: parentTask.id,
              association_id: resolvedAssociationId,
              client_id: parentTaskData.client_id,
              created_by: parentTaskData.created_by,
              status: 'pending',
              due_date: addDays(new Date(), t.days_until_due || 0).toISOString(),
              property_id: propertyId
        }));

        const { error: subtasksError } = await supabase.from('tasks').insert(subtasks);
        if (subtasksError) throw subtasksError;
      }

      toast({ title: "Success", description: "Workflow started successfully!" });
      return true;
    } catch (error) {
      console.error('Error applying template:', error);
      toast({ variant: "destructive", title: "Error", description: error.message });
      return false;
    } finally {
      setLoading(false);
    }
  };

  return {
    templates,
    loading,
    error,
    lastUpdated,
    getTemplates,
    createTemplate,
    deleteTemplate,
    applyTemplate
  };
}
