/**
 * @ai-summary Fastify tier authorization plugin
 * @ai-context Enforces subscription tier requirements for protected routes
 */

import { FastifyPluginAsync, FastifyRequest, FastifyReply, FastifyInstance } from 'fastify';
import fp from 'fastify-plugin';
import { logger } from '../logging/logger';
import { SubscriptionTier } from '../../features/user-profile/domain/user-profile.types';
import { canAccessFeature, getFeatureConfig, getTierLevel } from '../config/feature-tiers';

// Tier check options
export interface TierCheckOptions {
  minTier?: SubscriptionTier;
  featureKey?: string;
}

declare module 'fastify' {
  interface FastifyInstance {
    requireTier: (options: TierCheckOptions) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
  }
}

const tierGuardPlugin: FastifyPluginAsync = async (fastify) => {
  /**
   * Creates a preHandler that enforces tier requirements
   *
   * Usage:
   *   fastify.get('/premium-route', {
   *     preHandler: [fastify.requireTier({ minTier: 'pro' })],
   *     handler: controller.method
   *   });
   *
   * Or with feature key:
   *   fastify.post('/documents', {
   *     preHandler: [fastify.requireTier({ featureKey: 'document.scanMaintenanceSchedule' })],
   *     handler: controller.method
   *   });
   */
  fastify.decorate('requireTier', function(this: FastifyInstance, options: TierCheckOptions) {
    const { minTier, featureKey } = options;

    return async (request: FastifyRequest, reply: FastifyReply): Promise<void> => {
      try {
        // Ensure user is authenticated first
        if (typeof this.authenticate !== 'function') {
          logger.error('Tier guard: authenticate handler missing');
          return reply.code(500).send({
            error: 'Internal server error',
            message: 'Authentication handler missing',
          });
        }

        await this.authenticate(request, reply);
        if (reply.sent) {
          return;
        }

        // Get user's subscription tier from context
        const userTier = request.userContext?.subscriptionTier || 'free';

        // Determine required tier and check access
        let hasAccess = false;
        let requiredTier: SubscriptionTier = 'free';
        let upgradePrompt: string | undefined;
        let featureName: string | undefined;

        if (featureKey) {
          // Feature-based tier check
          hasAccess = canAccessFeature(userTier, featureKey);
          const config = getFeatureConfig(featureKey);
          requiredTier = config?.minTier || 'pro';
          upgradePrompt = config?.upgradePrompt;
          featureName = config?.name;
        } else if (minTier) {
          // Direct tier comparison
          hasAccess = getTierLevel(userTier) >= getTierLevel(minTier);
          requiredTier = minTier;
        } else {
          // No tier requirement specified - allow access
          hasAccess = true;
        }

        if (!hasAccess) {
          logger.warn('Tier guard: user tier insufficient', {
            userId: request.userContext?.userId?.substring(0, 8) + '...',
            userTier,
            requiredTier,
            featureKey,
          });

          return reply.code(403).send({
            error: 'TIER_REQUIRED',
            requiredTier,
            currentTier: userTier,
            feature: featureKey || null,
            featureName: featureName || null,
            upgradePrompt: upgradePrompt || `Upgrade to ${requiredTier} to access this feature.`,
          });
        }

        logger.debug('Tier guard: access granted', {
          userId: request.userContext?.userId?.substring(0, 8) + '...',
          userTier,
          featureKey,
        });
      } catch (error) {
        logger.error('Tier guard: authorization check failed', {
          error: error instanceof Error ? error.message : 'Unknown error',
          userId: request.userContext?.userId?.substring(0, 8) + '...',
        });

        return reply.code(500).send({
          error: 'Internal server error',
          message: 'Tier check failed',
        });
      }
    };
  });
};

export default fp(tierGuardPlugin, {
  name: 'tier-guard-plugin',
  // Note: Requires auth-plugin to be registered first for authenticate decorator
  // Dependency check removed to allow testing with mock authenticate
});
