"use strict";

/**
 * Utility Methods Mixin
 * 
 * Provides utility methods including link metadata fetching
 * and Express.js authentication middleware
 */
import { jwtDecode } from 'jwt-decode';
import { CACHE_TIMES } from './mixinHelpers';
export function OxyServicesUtilityMixin(Base) {
  return class extends Base {
    constructor(...args) {
      super(...args);
    }
    /**
     * Fetch link metadata
     */
    async fetchLinkMetadata(url) {
      try {
        return await this.makeRequest('GET', '/api/link-metadata', {
          url
        }, {
          cache: true,
          cacheTTL: CACHE_TIMES.EXTRA_LONG
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Simple Express.js authentication middleware
     * 
     * Built-in authentication middleware that validates JWT tokens and adds user data to requests.
     * 
     * @example
     * ```typescript
     * // Basic usage - just add it to your routes
     * app.use('/api/protected', oxyServices.auth());
     * 
     * // With debug logging
     * app.use('/api/protected', oxyServices.auth({ debug: true }));
     * 
     * // With custom error handling
     * app.use('/api/protected', oxyServices.auth({
     *   onError: (error) => console.error('Auth failed:', error)
     * }));
     * 
     * // Load full user data
     * app.use('/api/protected', oxyServices.auth({ loadUser: true }));
     * ```
     * 
     * @param options Optional configuration
     * @param options.debug Enable debug logging (default: false)
     * @param options.onError Custom error handler
     * @param options.loadUser Load full user data (default: false for performance)
     * @param options.session Use session-based validation (default: false)
     * @returns Express middleware function
     */
    auth(options = {}) {
      const {
        debug = false,
        onError,
        loadUser = false,
        session = false
      } = options;

      // Return a synchronous middleware function
      return (req, res, next) => {
        try {
          // Extract token from Authorization header
          const authHeader = req.headers['authorization'];
          const token = authHeader?.startsWith('Bearer ') ? authHeader.substring(7) : null;
          if (debug) {
            console.log(`🔐 Auth: Processing ${req.method} ${req.path}`);
            console.log(`🔐 Auth: Token present: ${!!token}`);
          }
          if (!token) {
            const error = {
              message: 'Access token required',
              code: 'MISSING_TOKEN',
              status: 401
            };
            if (debug) console.log(`❌ Auth: Missing token`);
            if (onError) return onError(error);
            return res.status(401).json(error);
          }

          // Decode and validate token
          let decoded;
          try {
            decoded = jwtDecode(token);
            if (debug) {
              console.log(`🔐 Auth: Token decoded, User ID: ${decoded.userId || decoded.id}`);
            }
          } catch (decodeError) {
            const error = {
              message: 'Invalid token format',
              code: 'INVALID_TOKEN_FORMAT',
              status: 403
            };
            if (debug) console.log(`❌ Auth: Token decode failed`);
            if (onError) return onError(error);
            return res.status(403).json(error);
          }
          const userId = decoded.userId || decoded.id;
          if (!userId) {
            const error = {
              message: 'Token missing user ID',
              code: 'INVALID_TOKEN_PAYLOAD',
              status: 403
            };
            if (debug) console.log(`❌ Auth: Token missing user ID`);
            if (onError) return onError(error);
            return res.status(403).json(error);
          }

          // Check token expiration
          if (decoded.exp && decoded.exp < Math.floor(Date.now() / 1000)) {
            const error = {
              message: 'Token expired',
              code: 'TOKEN_EXPIRED',
              status: 403
            };
            if (debug) console.log(`❌ Auth: Token expired`);
            if (onError) return onError(error);
            return res.status(403).json(error);
          }

          // For now, skip session validation to keep it simple
          // Session validation can be added later if needed

          // Set request properties immediately
          req.userId = userId;
          req.accessToken = token;
          req.user = {
            id: userId
          };

          // Automatically authenticate the OxyServices instance so all subsequent API calls are authenticated
          this.setTokens(token);
          if (debug) {
            console.log(`✅ Auth: Authentication successful for user ${userId}`);
          }
          next();
        } catch (error) {
          const apiError = this.handleError(error);
          if (debug) {
            // Debug logging - using console.log is acceptable here for development
            console.log(`❌ Auth: Unexpected error:`, apiError);
          }
          if (onError) return onError(apiError);
          return res.status(apiError && apiError.status || 500).json(apiError);
        }
      };
    }
  };
}
//# sourceMappingURL=OxyServices.utility.js.map