import { useState, useEffect, useCallback } from 'react';
import { supabase } from '@/lib/supabase';
import { useTranslation } from 'react-i18next';
import type {
  StoreSubscription,
  SubscriptionPlan,
  SubscriptionPlanTranslation,
  PackagePurchase,
  SubscriptionWithPlan,
  calculateMinutesRemaining,
  isSubscriptionExpired,
  getUsagePercentage
} from '@/types/subscription.types';

interface UseSubscriptionReturn {
  subscription: SubscriptionWithPlan | null;
  isLoading: boolean;
  error: string | null;
  minutesRemaining: number;
  packageMinutesRemaining: number;
  totalMinutesRemaining: number;
  usagePercentage: number;
  isExpired: boolean;
  daysRemaining: number;
  refetch: () => Promise<void>;
}

export function useSubscription(storeId: string | undefined): UseSubscriptionReturn {
  const { i18n } = useTranslation();
  const [subscription, setSubscription] = useState<SubscriptionWithPlan | null>(null);
  const [activePackages, setActivePackages] = useState<PackagePurchase[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const currentLanguage = i18n.language?.split('-')[0] || 'en';

  // Fetch subscription data
  const fetchSubscription = useCallback(async () => {
    if (!storeId) {
      setSubscription(null);
      setActivePackages([]);
      setIsLoading(false);
      return;
    }

    try {
      setIsLoading(true);
      setError(null);

      // Fetch subscription with plan data
      const { data: subData, error: subError } = await supabase
        .from('store_subscriptions')
        .select(`
          *,
          plan:subscription_plans(*)
        `)
        .eq('store_id', storeId)
        .single();

      if (subError) {
        if (subError.code === 'PGRST116') {
          // No subscription found
          setSubscription(null);
          setActivePackages([]);
          return;
        }
        throw subError;
      }

      // Fetch plan translation
      let planTranslation: SubscriptionPlanTranslation | undefined;
      if (subData?.plan?.id) {
        const { data: transData } = await supabase
          .from('subscription_plan_translations')
          .select('*')
          .eq('plan_id', subData.plan.id)
          .eq('language_code', currentLanguage)
          .single();

        if (transData) {
          planTranslation = transData;
        }
      }

      // Fetch active packages
      const { data: packagesData } = await supabase
        .from('package_purchases')
        .select('*')
        .eq('store_id', storeId)
        .eq('is_active', true)
        .gt('expires_at', new Date().toISOString());

      setSubscription({
        ...subData,
        plan_translation: planTranslation
      } as SubscriptionWithPlan);

      setActivePackages(packagesData || []);
    } catch (err) {
      console.error('Error fetching subscription:', err);
      setError(err instanceof Error ? err.message : 'Failed to fetch subscription');
    } finally {
      setIsLoading(false);
    }
  }, [storeId, currentLanguage]);

  // Initial fetch
  useEffect(() => {
    fetchSubscription();
  }, [fetchSubscription]);

  // Realtime subscription for live updates
  useEffect(() => {
    if (!storeId) return;

    // Subscribe to store_subscriptions changes
    const channel = supabase
      .channel(`subscription:${storeId}`)
      .on(
        'postgres_changes',
        {
          event: 'UPDATE',
          schema: 'public',
          table: 'store_subscriptions',
          filter: `store_id=eq.${storeId}`
        },
        (payload) => {
          console.log('Subscription UPDATE received:', payload);
          // Refetch to get full data with joins
          fetchSubscription();
        }
      )
      .on(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'store_subscriptions',
          filter: `store_id=eq.${storeId}`
        },
        (payload) => {
          console.log('Subscription INSERT received:', payload);
          fetchSubscription();
        }
      )
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'package_purchases',
          filter: `store_id=eq.${storeId}`
        },
        (payload) => {
          console.log('Package purchase update received:', payload);
          // Refetch packages
          fetchSubscription();
        }
      )
      .subscribe((status) => {
        console.log('Subscription channel status:', status);
      });

    return () => {
      supabase.removeChannel(channel);
    };
  }, [storeId, fetchSubscription]);

  // Calculate derived values
  const minutesRemaining = subscription
    ? Math.max(subscription.minutes_included - subscription.minutes_used, 0)
    : 0;

  const packageMinutesRemaining = activePackages.reduce(
    (sum, pkg) => sum + pkg.minutes_remaining,
    0
  );

  const totalMinutesRemaining = minutesRemaining + packageMinutesRemaining;

  const usagePercentage = subscription
    ? Math.min((subscription.minutes_used / subscription.minutes_included) * 100, 100)
    : 0;

  const isExpired = subscription ? (() => {
    const now = new Date();
    const periodEnd = new Date(subscription.period_end);

    // Time expired
    if (now > periodEnd) return true;

    // For trial, also check minutes
    if (subscription.status === 'trial' && minutesRemaining <= 0) {
      return true;
    }

    return false;
  })() : false;

  const daysRemaining = subscription
    ? Math.max(
        Math.ceil(
          (new Date(subscription.period_end).getTime() - Date.now()) / (1000 * 60 * 60 * 24)
        ),
        0
      )
    : 0;

  return {
    subscription,
    isLoading,
    error,
    minutesRemaining,
    packageMinutesRemaining,
    totalMinutesRemaining,
    usagePercentage,
    isExpired,
    daysRemaining,
    refetch: fetchSubscription
  };
}

// Hook for updating subscription (changing plans)
export function useUpdateSubscription() {
  const [isUpdating, setIsUpdating] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const changePlan = async (
    storeId: string,
    newPlanId: string,
    newPlan: SubscriptionPlan
  ): Promise<boolean> => {
    try {
      setIsUpdating(true);
      setError(null);

      // Get current subscription
      const { data: currentSub } = await supabase
        .from('store_subscriptions')
        .select('*')
        .eq('store_id', storeId)
        .single();

      const now = new Date();
      const periodEnd = new Date(now);
      periodEnd.setMonth(periodEnd.getMonth() + 1);

      // Update subscription
      const { error: updateError } = await supabase
        .from('store_subscriptions')
        .update({
          plan_id: newPlanId,
          status: newPlan.is_trial ? 'trial' : 'active',
          billing_period: newPlan.is_trial ? 'trial' : 'monthly',
          period_start: now.toISOString(),
          period_end: newPlan.is_trial
            ? new Date(now.getTime() + (newPlan.trial_days || 14) * 24 * 60 * 60 * 1000).toISOString()
            : periodEnd.toISOString(),
          minutes_included: newPlan.minutes_included,
          minutes_used: 0 // Reset usage for new period
        })
        .eq('store_id', storeId);

      if (updateError) throw updateError;

      // Log billing history
      await supabase.from('billing_history').insert({
        store_id: storeId,
        subscription_id: currentSub?.id,
        event_type: 'plan_changed',
        currency: currentSub?.currency || 'HUF',
        amount: 0, // UI only, no payment
        plan_id: newPlanId,
        description: `Changed plan to ${newPlan.plan_code}`
      });

      return true;
    } catch (err) {
      console.error('Error changing plan:', err);
      setError(err instanceof Error ? err.message : 'Failed to change plan');
      return false;
    } finally {
      setIsUpdating(false);
    }
  };

  const updateAutoPurchase = async (
    storeId: string,
    enabled: boolean,
    packageId?: string,
    threshold?: number
  ): Promise<boolean> => {
    try {
      setIsUpdating(true);
      setError(null);

      const { error: updateError } = await supabase
        .from('store_subscriptions')
        .update({
          auto_purchase_enabled: enabled,
          auto_purchase_package_id: packageId || null,
          auto_purchase_threshold: threshold || 5
        })
        .eq('store_id', storeId);

      if (updateError) throw updateError;

      return true;
    } catch (err) {
      console.error('Error updating auto-purchase:', err);
      setError(err instanceof Error ? err.message : 'Failed to update auto-purchase');
      return false;
    } finally {
      setIsUpdating(false);
    }
  };

  return {
    changePlan,
    updateAutoPurchase,
    isUpdating,
    error
  };
}
