/**
 * @ai-summary React hook for tier-based feature access checking
 * @ai-context Used to gate premium features based on user subscription tier
 */

import { useQuery } from '@tanstack/react-query';
import { useAuth0 } from '@auth0/auth0-react';
import { apiClient } from '../api/client';
import type { SubscriptionTier } from '../../features/settings/types/profile.types';

// Feature tier configuration (mirrors backend)
export interface FeatureConfig {
  minTier: SubscriptionTier;
  name: string;
  upgradePrompt: string;
}

interface FeatureTiersResponse {
  tiers: Record<SubscriptionTier, number>;
  features: Record<string, FeatureConfig>;
}

interface AccessCheckResult {
  allowed: boolean;
  requiredTier: SubscriptionTier | null;
  config: FeatureConfig | null;
}

// Tier hierarchy for comparison
const TIER_LEVELS: Record<SubscriptionTier, number> = {
  free: 0,
  pro: 1,
  enterprise: 2,
};

// Resource limits per tier (mirrors backend VEHICLE_LIMITS)
const RESOURCE_LIMITS = {
  vehicles: {
    free: 2,
    pro: 5,
    enterprise: null, // unlimited
  } as Record<SubscriptionTier, number | null>,
};

/**
 * Hook to check if user can access tier-gated features
 * Fetches user profile for tier and feature config from backend
 */
export const useTierAccess = () => {
  const { isAuthenticated, isLoading: authLoading } = useAuth0();

  // Fetch user profile for current tier
  const profileQuery = useQuery({
    queryKey: ['user-profile'],
    queryFn: async () => {
      const response = await apiClient.get('/user/profile');
      return response.data;
    },
    enabled: isAuthenticated && !authLoading,
    staleTime: 5 * 60 * 1000, // 5 minutes
    gcTime: 10 * 60 * 1000,
  });

  // Fetch feature tier config from backend (single source of truth)
  const featureConfigQuery = useQuery({
    queryKey: ['feature-tiers'],
    queryFn: async () => {
      const response = await apiClient.get<FeatureTiersResponse>('/config/feature-tiers');
      return response.data;
    },
    enabled: isAuthenticated && !authLoading,
    staleTime: 30 * 60 * 1000, // 30 minutes - config rarely changes
    gcTime: 60 * 60 * 1000, // 1 hour cache
    refetchOnWindowFocus: false,
    refetchOnMount: false,
  });

  const tier: SubscriptionTier = profileQuery.data?.subscriptionTier || 'free';
  const features = featureConfigQuery.data?.features || {};

  /**
   * Check if user can access a feature by key
   */
  const hasAccess = (featureKey: string): boolean => {
    const config = features[featureKey];
    if (!config) {
      // Unknown features are allowed (fail open for safety)
      return true;
    }
    return TIER_LEVELS[tier] >= TIER_LEVELS[config.minTier];
  };

  /**
   * Get detailed access information for a feature
   */
  const checkAccess = (featureKey: string): AccessCheckResult => {
    const config = features[featureKey] || null;
    if (!config) {
      return {
        allowed: true,
        requiredTier: null,
        config: null,
      };
    }
    return {
      allowed: TIER_LEVELS[tier] >= TIER_LEVELS[config.minTier],
      requiredTier: config.minTier,
      config,
    };
  };

  /**
   * Get resource limit for current user's tier
   * Resource-agnostic method for count-based limits (vehicles, documents, etc.)
   *
   * @param resourceType - Type of resource (e.g., 'vehicles')
   * @returns Maximum allowed count, or null for unlimited
   */
  const getResourceLimit = (resourceType: keyof typeof RESOURCE_LIMITS): number | null => {
    const limits = RESOURCE_LIMITS[resourceType];
    if (!limits) {
      return null; // Unknown resource type = unlimited
    }
    return limits[tier] ?? null;
  };

  /**
   * Check if user is at or over their resource limit
   * Resource-agnostic method for count-based limits (vehicles, documents, etc.)
   *
   * @param resourceType - Type of resource (e.g., 'vehicles')
   * @param currentCount - Current number of resources user has
   * @returns true if user is at or over limit, false if under limit or unlimited
   */
  const isAtResourceLimit = (
    resourceType: keyof typeof RESOURCE_LIMITS,
    currentCount: number
  ): boolean => {
    const limit = getResourceLimit(resourceType);
    if (limit === null) {
      return false; // Unlimited
    }
    return currentCount >= limit;
  };

  return {
    tier,
    loading: profileQuery.isLoading || featureConfigQuery.isLoading,
    hasAccess,
    checkAccess,
    getResourceLimit,
    isAtResourceLimit,
  };
};

export default useTierAccess;
