/**
 * Plan capability and feature gating module.
 * Reference: ConverseCart app/lib/billing-plans.ts
 *
 * Implements strict plan entitlement checks, assert helpers, and feature matrices
 * for Meta AI FB (Meta Commerce, Pixel & Conversions API).
 */

export type FeatureKey =
  // 17 Specification Matrix Features:
  | 'meta.pixel_count'
  | 'meta.pixel_multi'
  | 'meta.capi_tracking'
  | 'meta.order_quota'
  | 'meta.advanced_tracking_rules'
  | 'meta.specific_market_routing'
  | 'meta.catalog_feeds'
  | 'meta.catalog_unlimited'
  | 'meta.sku_limit'
  | 'meta.sync_frequency'
  | 'meta.order_reconciliation'
  | 'meta.pixel_analytics'
  | 'meta.live_event_stream'
  | 'meta.realtime_ads_report'
  | 'meta.bot_protection'
  | 'meta.restricted_mode'
  | 'meta.audience_report'
  | 'meta.meta_audiences_sync'
  | 'meta.support_level'
  // Backwards compatibility legacy keys:
  | 'meta.custom_titles'
  | 'meta.supplementary_feeds'
  | 'meta.ad_campaigns_unlimited'
  | 'meta.website_audit'
  | 'meta.dedicated_manager'
  | 'meta.priority_support';

export type PlanId = 'basic' | 'growth' | 'scale' | 'accelerate';

export interface PlanFeatureConfig {
  id: PlanId;
  name: string;
  price: number;
  yearly_price: number;
  sku_limit: number | null;
  campaigns_limit: number | null; // Catalog Feeds Limit
  pixel_limit: number | null;
  order_quota: number | null; // Monthly orders
  trial_days: number;
  features: string[];
  featureFlags: Record<FeatureKey, boolean>;
  featureLimits?: Partial<Record<FeatureKey, number | null>>;
}

/**
 * Normalizes any plan tier string to one of the canonical tiers: 'basic', 'growth', or 'scale'.
 */
export function normalizePlanId(planId: string | null | undefined): 'basic' | 'growth' | 'scale' {
  if (!planId) return 'basic';
  const clean = planId.trim().toLowerCase();
  if (clean === 'scale' || clean === 'accelerate' || clean === 'enterprise' || clean.includes('scale') || clean.includes('accelerate')) {
    return 'scale';
  }
  if (clean === 'growth' || clean === 'pro' || clean.includes('growth')) {
    return 'growth';
  }
  return 'basic';
}

export const PLAN_FEATURE_CONFIGS: Record<PlanId, PlanFeatureConfig> = {
  basic: {
    id: 'basic',
    name: 'Free Plan',
    price: 0,
    yearly_price: 0,
    sku_limit: 100,
    campaigns_limit: 1, // 1 feed
    pixel_limit: 1, // 1 pixel
    order_quota: 5, // 5 orders/month
    trial_days: 0,
    features: [
      '1 Meta Pixel, 1 Conversion API',
      '5 orders per month quota',
      '1 catalog feed, weekly sync',
      'Up to 100 SKUs feed upload',
      'Order reconciliation & report',
      'Advanced tracking rules (COD / Subs)',
      'Pixel Analytics & Health (Basic)',
      'Layer 1 Bot Protection',
      'Audience report: who buys, who returns',
      '24/7 Support',
    ],
    featureFlags: {
      'meta.pixel_count': true,
      'meta.pixel_multi': false,
      'meta.capi_tracking': true,
      'meta.order_quota': true,
      'meta.advanced_tracking_rules': true,
      'meta.specific_market_routing': false,
      'meta.catalog_feeds': true,
      'meta.catalog_unlimited': false,
      'meta.sku_limit': true,
      'meta.sync_frequency': true,
      'meta.order_reconciliation': true,
      'meta.pixel_analytics': true,
      'meta.live_event_stream': false,
      'meta.realtime_ads_report': false,
      'meta.bot_protection': true,
      'meta.restricted_mode': false,
      'meta.audience_report': true,
      'meta.meta_audiences_sync': false,
      'meta.support_level': true,
      'meta.custom_titles': false,
      'meta.supplementary_feeds': false,
      'meta.ad_campaigns_unlimited': false,
      'meta.website_audit': false,
      'meta.dedicated_manager': false,
      'meta.priority_support': false,
    },
    featureLimits: {
      'meta.pixel_count': 1,
      'meta.catalog_feeds': 1,
      'meta.sku_limit': 100,
      'meta.order_quota': 5,
    },
  },

  growth: {
    id: 'growth',
    name: 'Growth Plan',
    price: 13,
    yearly_price: 124.80,
    sku_limit: 5000,
    campaigns_limit: 3, // 3 feeds
    pixel_limit: null, // Unlimited
    order_quota: null, // Unlimited orders
    trial_days: 14,
    features: [
      'Everything in Free Plan',
      'Unlimited Meta Pixels',
      'Conversions API (1 Dataset included, +$5.99/mo per extra)',
      'Unlimited Order Tracking Quota',
      '3 Catalog Feeds (XML / CSV)',
      '100 – 5,000 SKUs feed upload',
      'Standard (Daily) feed sync frequency',
      'Advanced Pixel Analytics & Health',
      'Live Event Stream & Activities',
      'Real-Time Ads Report & UTM Attribution',
      'Layer 1 + Layer 2 Bot Protection Blocking',
      '24/7 Priority Chat & Email Support',
    ],
    featureFlags: {
      'meta.pixel_count': true,
      'meta.pixel_multi': true,
      'meta.capi_tracking': true,
      'meta.order_quota': true,
      'meta.advanced_tracking_rules': true,
      'meta.specific_market_routing': false,
      'meta.catalog_feeds': true,
      'meta.catalog_unlimited': false,
      'meta.sku_limit': true,
      'meta.sync_frequency': true,
      'meta.order_reconciliation': true,
      'meta.pixel_analytics': true,
      'meta.live_event_stream': true,
      'meta.realtime_ads_report': true,
      'meta.bot_protection': true,
      'meta.restricted_mode': false,
      'meta.audience_report': true,
      'meta.meta_audiences_sync': false,
      'meta.support_level': true,
      'meta.custom_titles': true,
      'meta.supplementary_feeds': true,
      'meta.ad_campaigns_unlimited': false,
      'meta.website_audit': false,
      'meta.dedicated_manager': false,
      'meta.priority_support': true,
    },
    featureLimits: {
      'meta.pixel_count': null, // Unlimited
      'meta.catalog_feeds': 3,
      'meta.sku_limit': 5000,
      'meta.order_quota': null, // Unlimited
    },
  },

  scale: {
    id: 'scale',
    name: 'Scale Plan',
    price: 99,
    yearly_price: 950.40,
    sku_limit: null, // Unlimited
    campaigns_limit: null, // Unlimited feeds
    pixel_limit: null, // Unlimited pixels
    order_quota: null, // Unlimited
    trial_days: 14,
    features: [
      'Everything in Growth Plan',
      'Unlimited Meta Pixels & Unlimited CAPI Datasets',
      'Unlimited Orders & Unlimited Catalog Feeds',
      'Unlimited SKUs upload to Meta',
      'Specific-Market Pixel Routing',
      'Advanced (Daily + Real-time) Feed Sync',
      'Full Bot Protection + Manual Resend Queue',
      'Restricted Mode (Consent Policy / GDPR / CCPA)',
      'Meta Audiences Sync (Lookalikes & Retargeting)',
      'Highest Priority 24/7 + VIP Community Support',
    ],
    featureFlags: {
      'meta.pixel_count': true,
      'meta.pixel_multi': true,
      'meta.capi_tracking': true,
      'meta.order_quota': true,
      'meta.advanced_tracking_rules': true,
      'meta.specific_market_routing': true,
      'meta.catalog_feeds': true,
      'meta.catalog_unlimited': true,
      'meta.sku_limit': true,
      'meta.sync_frequency': true,
      'meta.order_reconciliation': true,
      'meta.pixel_analytics': true,
      'meta.live_event_stream': true,
      'meta.realtime_ads_report': true,
      'meta.bot_protection': true,
      'meta.restricted_mode': true,
      'meta.audience_report': true,
      'meta.meta_audiences_sync': true,
      'meta.support_level': true,
      'meta.custom_titles': true,
      'meta.supplementary_feeds': true,
      'meta.ad_campaigns_unlimited': true,
      'meta.website_audit': true,
      'meta.dedicated_manager': true,
      'meta.priority_support': true,
    },
    featureLimits: {
      'meta.pixel_count': null,
      'meta.catalog_feeds': null,
      'meta.sku_limit': null,
      'meta.order_quota': null,
    },
  },

  // Accelerate alias for backwards compatibility
  accelerate: {
    id: 'accelerate',
    name: 'Scale Plan',
    price: 99,
    yearly_price: 950.40,
    sku_limit: null,
    campaigns_limit: null,
    pixel_limit: null,
    order_quota: null,
    trial_days: 14,
    features: [
      'Everything in Growth Plan',
      'Unlimited Meta Pixels & Unlimited CAPI Datasets',
      'Unlimited Orders & Unlimited Catalog Feeds',
      'Unlimited SKUs upload to Meta',
      'Specific-Market Pixel Routing',
      'Advanced (Daily + Real-time) Feed Sync',
      'Full Bot Protection + Manual Resend Queue',
      'Restricted Mode (Consent Policy / GDPR / CCPA)',
      'Meta Audiences Sync (Lookalikes & Retargeting)',
      'Highest Priority 24/7 + VIP Community Support',
    ],
    featureFlags: {
      'meta.pixel_count': true,
      'meta.pixel_multi': true,
      'meta.capi_tracking': true,
      'meta.order_quota': true,
      'meta.advanced_tracking_rules': true,
      'meta.specific_market_routing': true,
      'meta.catalog_feeds': true,
      'meta.catalog_unlimited': true,
      'meta.sku_limit': true,
      'meta.sync_frequency': true,
      'meta.order_reconciliation': true,
      'meta.pixel_analytics': true,
      'meta.live_event_stream': true,
      'meta.realtime_ads_report': true,
      'meta.bot_protection': true,
      'meta.restricted_mode': true,
      'meta.audience_report': true,
      'meta.meta_audiences_sync': true,
      'meta.support_level': true,
      'meta.custom_titles': true,
      'meta.supplementary_feeds': true,
      'meta.ad_campaigns_unlimited': true,
      'meta.website_audit': true,
      'meta.dedicated_manager': true,
      'meta.priority_support': true,
    },
    featureLimits: {
      'meta.pixel_count': null,
      'meta.catalog_feeds': null,
      'meta.sku_limit': null,
      'meta.order_quota': null,
    },
  },
};

/**
 * Custom error thrown when a store attempts an action not entitled by their plan.
 */
export class FeatureAccessError extends Error {
  statusCode = 403;
  code = 'FEATURE_NOT_AVAILABLE';
  plan: string;
  feature: FeatureKey;
  pricingUrl?: string;

  constructor(plan: string, feature: FeatureKey, customMessage?: string, pricingUrl?: string) {
    const featureLabels: Record<string, string> = {
      'meta.specific_market_routing': 'Specific-Market Pixel Routing (Scale Plan only)',
      'meta.restricted_mode': 'Restricted Mode Consent Policy & GDPR (Scale Plan only)',
      'meta.meta_audiences_sync': 'Meta Audiences Sync (Scale Plan only)',
      'meta.live_event_stream': 'Live Event Stream (Growth & Scale Plans)',
      'meta.realtime_ads_report': 'Real-Time Ads Report & UTM Attribution (Growth & Scale Plans)',
      'meta.pixel_multi': 'Multiple Meta Pixels (Growth & Scale Plans)',
      'meta.catalog_unlimited': 'Unlimited Catalog Feeds (Scale Plan only)',
    };

    const friendlyLabel = featureLabels[feature] || feature;
    const message =
      customMessage ||
      `Feature '${friendlyLabel}' is not included in the ${(plan || 'basic').toUpperCase()} plan. Please upgrade your subscription to access this feature.`;
    super(message);
    this.name = 'FeatureAccessError';
    this.plan = plan;
    this.feature = feature;
    this.pricingUrl = pricingUrl || '/meta-connector/pricing';
  }
}

/**
 * Check whether a specific plan tier has permission to use a feature flag.
 */
export function canUseFeature(
  planId: string | null | undefined,
  feature: FeatureKey,
  customFeatureFlags?: Record<string, boolean> | null
): boolean {
  if (customFeatureFlags && typeof customFeatureFlags === 'object' && customFeatureFlags[feature] !== undefined) {
    return Boolean(customFeatureFlags[feature]);
  }

  const normalized = normalizePlanId(planId);
  const config = PLAN_FEATURE_CONFIGS[normalized];
  if (!config) return false;

  return Boolean(config.featureFlags[feature]);
}

/**
 * Returns the numeric limit for a feature on a given plan, or null if unlimited.
 */
export function getFeatureLimit(
  planId: string | null | undefined,
  feature: FeatureKey,
  customLimits?: Record<string, number | null> | null
): number | null {
  if (customLimits && typeof customLimits === 'object' && customLimits[feature] !== undefined) {
    return customLimits[feature];
  }

  const normalized = normalizePlanId(planId);
  const config = PLAN_FEATURE_CONFIGS[normalized];
  if (!config || !config.featureLimits) return null;

  return config.featureLimits[feature] ?? null;
}

/**
 * Asserts that a plan has access to a feature, throwing FeatureAccessError if denied.
 */
export function assertCanUseFeature(
  planId: string | null | undefined,
  feature: FeatureKey,
  customMessage?: string,
  pricingUrl?: string
): void {
  if (!canUseFeature(planId, feature)) {
    throw new FeatureAccessError(String(planId || 'basic'), feature, customMessage, pricingUrl);
  }
}

/**
 * Asserts that current usage does not exceed the allowed feature quota.
 */
export function assertWithinQuota(
  planId: string | null | undefined,
  feature: FeatureKey,
  currentUsage: number,
  customMessage?: string
): void {
  const limit = getFeatureLimit(planId, feature);
  if (limit !== null && currentUsage >= limit) {
    const normalized = normalizePlanId(planId);
    const msg =
      customMessage ||
      `You have reached the maximum limit of ${limit} for this feature on the ${normalized.toUpperCase()} plan. Please upgrade to Growth or Scale plan to increase your quota.`;
    throw new FeatureAccessError(String(planId || 'basic'), feature, msg);
  }
}
