import { Request, Response, NextFunction } from 'express';
import crypto from 'crypto';
import { ApiKey } from '../models/api-key.model';
import { ApiError } from './error.middleware';
import { config } from '../config/env';

// Test API key for JSON store mode
const TEST_API_KEY = 'test-api-key-for-development';

export async function apiKeyAuth(
  req: Request,
  _res: Response,
  next: NextFunction
): Promise<void> {
  try {
    const apiKey = req.headers['x-api-key'] as string;

    if (!apiKey) {
      throw new ApiError(401, 'API key required', 'API_KEY_REQUIRED');
    }

    // In JSON store mode, accept the test API key
    if (config.useJsonStore) {
      if (apiKey === TEST_API_KEY) {
        next();
        return;
      }
      throw new ApiError(401, 'Invalid API key', 'INVALID_API_KEY');
    }

    // MongoDB mode - validate against database
    const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex');
    const keyRecord = await ApiKey.findOne({
      keyHash,
      isActive: true,
      $or: [{ expiresAt: null }, { expiresAt: { $gt: new Date() } }],
    });

    if (!keyRecord) {
      throw new ApiError(401, 'Invalid API key', 'INVALID_API_KEY');
    }

    // Update last used timestamp
    await ApiKey.updateOne({ _id: keyRecord._id }, { lastUsedAt: new Date() });

    next();
  } catch (error) {
    next(error);
  }
}
