/**
 * Subscription hook for checking plan features and limits
 */

import { useState, useEffect, useCallback, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { subscriptionService } from '../services/subscription';
import {
  SUBSCRIPTION_TIERS,
  SubscriptionTier
} from '../types/subscription';
import { useCurrentTenant } from '../../stores';
import { useAuthUser, useJWTSubscription } from '../../stores/auth.store';
import { useSubscriptionEvents } from '../../contexts/SubscriptionEventsContext';

export interface SubscriptionFeature {
  hasFeature: boolean;
  featureLevel?: string;
  reason?: string;
}

export interface SubscriptionLimits {
  canAddUser: boolean;
  canAddLocation: boolean;
  canAddProduct: boolean;
  usageData?: any;
}

export interface SubscriptionInfo {
  plan: string;
  status: 'active' | 'inactive' | 'past_due' | 'cancelled' | 'trialing';
  features: Record<string, any>;
  loading: boolean;
  error?: string;
}

export const useSubscription = () => {
  const currentTenant = useCurrentTenant();
  const user = useAuthUser();
  const tenantId = currentTenant?.id || user?.tenant_id;
  const { subscriptionVersion } = useSubscriptionEvents();

  // Initialize with tenant's subscription_plan if available, otherwise default to starter
  const initialPlan = currentTenant?.subscription_plan || currentTenant?.subscription_tier || 'starter';

  // Use React Query to fetch subscription data (automatically deduplicates & caches)
  const { data: usageSummary, isLoading, error, refetch } = useQuery({
    queryKey: ['subscription-usage', tenantId, subscriptionVersion],
    queryFn: () => subscriptionService.getUsageSummary(tenantId!),
    enabled: !!tenantId,
    staleTime: 30 * 1000, // Cache for 30 seconds (matches backend cache)
    gcTime: 5 * 60 * 1000, // Keep in cache for 5 minutes
    retry: 1,
  });

  // Get JWT subscription data for instant rendering
  const jwtSubscription = useJWTSubscription();
  
  // Derive subscription info from query data or tenant fallback
  // IMPORTANT: Memoize to prevent infinite re-renders in dependent hooks
  const subscriptionInfo: SubscriptionInfo = useMemo(() => {
    // If we have fresh API data (from loadSubscriptionData), use it
    // This handles the case where token refresh failed but API call succeeded
    const apiPlan = usageSummary?.plan;
    const jwtPlan = jwtSubscription?.tier;

    // Prefer API data if available and more recent
    // Ensure status is compatible with SubscriptionInfo interface
    const rawStatus = usageSummary?.status || jwtSubscription?.status || 'active';
    const status = (() => {
      switch (rawStatus) {
        case 'active':
        case 'inactive':
        case 'past_due':
        case 'cancelled':
        case 'trialing':
          return rawStatus;
        default:
          return 'active';
      }
    })();
    
    return {
      plan: apiPlan || jwtPlan || initialPlan,
      status: status,
      features: usageSummary?.usage || {},
      loading: isLoading && !apiPlan && !jwtPlan,
      error: error ? 'Failed to load subscription data' : undefined,
      fromJWT: !apiPlan && !!jwtPlan,
    };
  }, [jwtSubscription, usageSummary?.plan, usageSummary?.status, usageSummary?.usage, initialPlan, isLoading, error]);

  // Check if user has a specific feature
  const hasFeature = useCallback(async (featureName: string): Promise<SubscriptionFeature> => {
    if (!tenantId) {
      return { hasFeature: false, reason: 'No tenant ID available' };
    }

    try {
      const result = await subscriptionService.hasFeature(tenantId, featureName);
      return {
        hasFeature: result.has_feature,
        featureLevel: result.feature_value,
        reason: result.reason
      };
    } catch (error) {
      console.error('Error checking feature:', error);
      return { hasFeature: false, reason: 'Error checking feature access' };
    }
  }, [tenantId]);

  // Check analytics access level
  const getAnalyticsAccess = useCallback((): { hasAccess: boolean; level: string; reason?: string } => {
    const plan = subscriptionInfo.plan;

    // Convert plan string to typed SubscriptionTier
    let tierKey: SubscriptionTier | undefined;
    if (plan === SUBSCRIPTION_TIERS.STARTER) tierKey = SUBSCRIPTION_TIERS.STARTER;
    else if (plan === SUBSCRIPTION_TIERS.PROFESSIONAL) tierKey = SUBSCRIPTION_TIERS.PROFESSIONAL;
    else if (plan === SUBSCRIPTION_TIERS.ENTERPRISE) tierKey = SUBSCRIPTION_TIERS.ENTERPRISE;

    if (tierKey) {
      const analyticsLevel = subscriptionService.getAnalyticsLevelForTier(tierKey);
      return { hasAccess: true, level: analyticsLevel };
    }

    // Default fallback when plan is not recognized
    return { hasAccess: false, level: 'none', reason: 'Unknown plan' };
  }, [subscriptionInfo.plan]);

  // Check if user can access specific analytics features
  const canAccessAnalytics = useCallback((requiredLevel: 'basic' | 'advanced' | 'predictive' = 'basic'): boolean => {
    const { hasAccess, level } = getAnalyticsAccess();

    if (!hasAccess) return false;

    return subscriptionService.doesAnalyticsLevelMeetMinimum(level as any, requiredLevel);
  }, [getAnalyticsAccess]);

  // Check if user can access forecasting features
  const canAccessForecasting = useCallback((): boolean => {
    return canAccessAnalytics('advanced'); // Forecasting requires advanced or higher
  }, [canAccessAnalytics]);

  // Check if user can access AI insights
  const canAccessAIInsights = useCallback((): boolean => {
    return canAccessAnalytics('predictive'); // AI Insights requires enterprise plan
  }, [canAccessAnalytics]);

  // Check usage limits
  const checkLimits = useCallback(async (): Promise<SubscriptionLimits> => {
    if (!tenantId) {
      return {
        canAddUser: false,
        canAddLocation: false,
        canAddProduct: false
      };
    }

    try {
      const [userCheck, locationCheck, productCheck] = await Promise.all([
        subscriptionService.canAddUser(tenantId),
        subscriptionService.canAddLocation(tenantId),
        subscriptionService.canAddProduct(tenantId)
      ]);

      return {
        canAddUser: userCheck.can_add,
        canAddLocation: locationCheck.can_add,
        canAddProduct: productCheck.can_add,
      };
    } catch (error) {
      console.error('Error checking limits:', error);
      return {
        canAddUser: false,
        canAddLocation: false,
        canAddProduct: false
      };
    }
  }, [tenantId]);

  return {
    subscriptionInfo,
    hasFeature,
    getAnalyticsAccess,
    canAccessAnalytics,
    canAccessForecasting,
    canAccessAIInsights,
    checkLimits,
    refreshSubscription: refetch,
  };
};

export default useSubscription;
