import crypto from 'crypto';

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

// EN: Device fingerprinting library will be loaded dynamically to avoid browser-only code
// VI: Thư viện device fingerprinting sẽ được load động để tránh code chỉ chạy trên browser

/**
 * EN: Cookie service for secure cookie management
 * VI: Service cookie cho quản lý cookie bảo mật
 */
export class CookieService {
  private readonly isProduction = process.env.NODE_ENV === 'production';

  /**
   * EN: Set secure HTTP-only cookies
   * VI: Thiết lập cookie bảo mật HTTP-only
   */
  setAuthCookies(res: Response, tokens: { accessToken: string; refreshToken: string; idToken?: string }): void {
    // Access Token Cookie (15 minutes)
    res.cookie('access_token', tokens.accessToken, {
      httpOnly: true,
      secure: this.isProduction,
      sameSite: 'strict',
      maxAge: 15 * 60 * 1000, // 15 minutes
      path: '/',
    });

    // Refresh Token Cookie (7 days, more restrictive)
    res.cookie('refresh_token', tokens.refreshToken, {
      httpOnly: true,
      secure: this.isProduction,
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
      path: '/auth/refresh', // Only sent to refresh endpoint
    });

    // ID Token Cookie (1 hour, readable by JS for OIDC)
    if (tokens.idToken) {
      res.cookie('id_token', tokens.idToken, {
        httpOnly: false, // JS can read for OIDC
        secure: this.isProduction,
        sameSite: 'strict',
        maxAge: 60 * 60 * 1000, // 1 hour
        path: '/',
      });
    }

    // CSRF Token (readable by JS)
    const csrfToken = this.generateCSRFToken();
    res.cookie('csrf_token', csrfToken, {
      httpOnly: false, // JS can read
      secure: this.isProduction,
      sameSite: 'strict',
      maxAge: 15 * 60 * 1000, // 15 minutes
      path: '/',
    });

    logger.debug('Auth cookies set', { hasAccessToken: !!tokens.accessToken });
  }

  /**
   * EN: Get token from cookies
   * VI: Lấy token từ cookies
   */
  getTokenFromCookie(req: Request, tokenType: 'access' | 'refresh' | 'id' = 'access'): string | null {
    const cookieName = `${tokenType}_token`;
    return req.cookies?.[cookieName] || null;
  }

  /**
   * EN: Clear all auth cookies on logout
   * VI: Xóa tất cả cookie xác thực khi đăng xuất
   */
  clearAuthCookies(res: Response): void {
    const cookiesToClear = ['access_token', 'refresh_token', 'id_token', 'csrf_token'];

    cookiesToClear.forEach(name => {
      res.clearCookie(name, {
        httpOnly: true,
        secure: this.isProduction,
        sameSite: 'strict',
        path: '/',
      });
    });

    logger.debug('Auth cookies cleared');
  }

  /**
   * EN: Generate CSRF token
   * VI: Tạo CSRF token
   */
  private generateCSRFToken(): string {
    // Simple CSRF token generation
    // In production, use crypto.randomBytes
    return crypto.randomBytes(32).toString('hex');
  }

  /**
   * EN: Validate CSRF token
   * VI: Xác thực CSRF token
   */
  validateCSRFToken(req: Request): boolean {
    const cookieToken = req.cookies?.csrf_token;
    const headerToken = req.headers['x-csrf-token'];

    if (!cookieToken || !headerToken) {
      return false;
    }

    return cookieToken === headerToken;
  }

  /**
   * EN: Get device fingerprint from request using comprehensive fingerprinting
   * VI: Lấy device fingerprint từ request sử dụng fingerprinting toàn diện
   */
  getDeviceFingerprint(req: Request): string {
    try {
      // EN: Comprehensive server-side device fingerprinting
      // VI: Device fingerprinting toàn diện phía server
      const fingerprintData = {
        ip: req.ip || req.socket.remoteAddress || '',
        forwardedFor: req.headers['x-forwarded-for'] || '',
        realIp: req.headers['x-real-ip'] || '',
        userAgent: req.headers['user-agent'] || '',
        acceptLanguage: req.headers['accept-language'] || '',
        acceptEncoding: req.headers['accept-encoding'] || '',
        connection: req.headers['connection'] || '',
        cacheControl: req.headers['cache-control'] || '',
        dnt: req.headers['dnt'] || '', // Do Not Track
        secChUa: req.headers['sec-ch-ua'] || '', // User-Agent Client Hints
        secChUaMobile: req.headers['sec-ch-ua-mobile'] || '',
        secChUaPlatform: req.headers['sec-ch-ua-platform'] || '',
        host: req.headers['host'] || '',
        referer: req.headers['referer'] || '',
      };

      // EN: Create fingerprint string and hash for security
      // VI: Tạo chuỗi fingerprint và hash để bảo mật
      const fingerprintString = JSON.stringify(fingerprintData);
      return crypto.createHash('sha256').update(fingerprintString).digest('hex');
    } catch (error) {
      logger.warn('Device fingerprinting failed, using basic fallback', { error });

      // Fallback to basic fingerprinting
      const userAgent = req.headers['user-agent'] || '';
      const acceptLanguage = req.headers['accept-language'] || '';
      const acceptEncoding = req.headers['accept-encoding'] || '';
      const ip = req.ip || req.socket.remoteAddress || '';

      const fingerprint = `${userAgent}:${acceptLanguage}:${acceptEncoding}:${ip}`;
      return crypto.createHash('sha256').update(fingerprint).digest('hex');
    }
  }
}

export const cookieService = new CookieService();
