import { logger } from '@goodgo/logger';
import { Request } from 'express';

import { cookieService } from '../../modules/token/cookie.service';

/**
 * EN: Validation result interface
 * VI: Interface kết quả xác thực
 */
export interface ValidationResult {
  allowed: boolean;
  requireMFA?: boolean;
  riskScore?: number;
  reasons?: string[];
}

/**
 * EN: Zero-Trust Validator for request validation
 * VI: Zero-Trust Validator cho xác thực request
 */
export class ZeroTrustValidator {
  /**
   * EN: Validate request with zero-trust principles
   * VI: Xác thực request với nguyên tắc zero-trust
   */
  async validateRequest(req: Request): Promise<ValidationResult> {
    const checks = await Promise.all([
      this.validateDevice(req),
      this.validateLocation(req),
      this.validateBehavior(req),
      this.validateCSRF(req),
    ]);

    const riskScore = this.calculateRiskScore(checks);
    const reasons: string[] = [];

    checks.forEach((check, index) => {
      if (!check.passed) {
        reasons.push(check.reason || `Check ${index} failed`);
      }
    });

    if (riskScore > 0.8) {
      // High risk - require MFA
      return {
        allowed: false,
        requireMFA: true,
        riskScore,
        reasons,
      };
    } else if (riskScore > 0.5) {
      // Medium risk - allow but log
      logger.warn('Medium risk request detected', {
        ip: req.ip,
        userAgent: req.headers['user-agent'],
        riskScore,
        reasons,
      });
      return {
        allowed: true,
        riskScore,
        reasons,
      };
    }

    return {
      allowed: true,
      riskScore,
    };
  }

  /**
   * EN: Validate device fingerprint
   * VI: Xác thực device fingerprint
   */
  private async validateDevice(req: Request): Promise<{ passed: boolean; reason?: string }> {
    const fingerprint = cookieService.getDeviceFingerprint(req);
    
    // In production, check against known devices for user
    // For now, basic validation
    if (!fingerprint) {
      return { passed: false, reason: 'No device fingerprint' };
    }

    return { passed: true };
  }

  /**
   * EN: Validate location (geo-location check)
   * VI: Xác thực vị trí (kiểm tra địa lý)
   */
  private async validateLocation(req: Request): Promise<{ passed: boolean; reason?: string }> {
    // In production, use geo-location service
    // For now, basic IP validation
    const ip = req.ip || req.socket.remoteAddress;
    
    if (!ip || ip === '::1' || ip === '127.0.0.1') {
      // Localhost is always allowed
      return { passed: true };
    }

    // In production, check against known locations
    return { passed: true };
  }

  /**
   * EN: Validate behavior (ML-based behavior analysis)
   * VI: Xác thực hành vi (phân tích hành vi dựa trên ML)
   */
  private async validateBehavior(_req: Request): Promise<{ passed: boolean; reason?: string }> {
    // In production, use ML model for behavior analysis
    // Check request patterns, timing, etc.
    
    // Basic rate limiting check (would be done by middleware)
    return { passed: true };
  }

  /**
   * EN: Validate CSRF token
   * VI: Xác thực CSRF token
   */
  private async validateCSRF(req: Request): Promise<{ passed: boolean; reason?: string }> {
    // Skip CSRF for GET requests
    if (req.method === 'GET') {
      return { passed: true };
    }

    const isValid = cookieService.validateCSRFToken(req);
    if (!isValid) {
      return { passed: false, reason: 'Invalid CSRF token' };
    }

    return { passed: true };
  }

  /**
   * EN: Calculate risk score from checks
   * VI: Tính điểm rủi ro từ các kiểm tra
   */
  private calculateRiskScore(checks: Array<{ passed: boolean }>): number {
    const failedChecks = checks.filter(c => !c.passed).length;
    return failedChecks / checks.length;
  }
}

export const zeroTrustValidator = new ZeroTrustValidator();
