import { serialize, parse } from 'cookie';
import { randomBytes } from 'crypto';
import type { SessionData } from '~/utils/types';

// In-memory session store (in production, you'd use Redis or a database)
const sessionStore = new Map<string, {
  data: SessionData;
  expiresAt: number;
  rememberMe: boolean;
}>();

// Cleanup expired sessions every 5 minutes
setInterval(() => {
  const now = Date.now();
  let cleanedCount = 0;
  for (const [sessionId, session] of sessionStore.entries()) {
    if (now > session.expiresAt) {
      sessionStore.delete(sessionId);
      cleanedCount++;
    }
  }
  if (cleanedCount > 0) {
    console.log(`🧹 Cleaned up ${cleanedCount} expired sessions`);
  }
}, 5 * 60 * 1000);

export class SessionManager {
  private cookieName = 'monacousa-session';

  constructor() {
    // No encryption key needed since we're only storing session IDs
  }

  private generateSessionId(): string {
    return randomBytes(32).toString('hex');
  }

  createSession(sessionData: SessionData, rememberMe: boolean = false): string {
    const sessionId = this.generateSessionId();
    const maxAge = rememberMe ? 60 * 60 * 24 * 30 : 60 * 60 * 24 * 7; // 30 days vs 7 days
    const expiresAt = Date.now() + (maxAge * 1000);
    
    // Store session data server-side
    sessionStore.set(sessionId, {
      data: sessionData,
      expiresAt,
      rememberMe
    });
    
    return serialize(this.cookieName, sessionId, {
      httpOnly: true,
      secure: true,
      sameSite: 'none',
      maxAge,
      path: '/',
    });
  }

  getSession(cookieHeader?: string): SessionData | null {
    if (!cookieHeader) {
      return null;
    }

    const cookies = parse(cookieHeader);
    const sessionId = cookies[this.cookieName];

    if (!sessionId) {
      return null;
    }

    const sessionEntry = sessionStore.get(sessionId);
    if (!sessionEntry) {
      return null;
    }

    // Check if session is expired
    if (Date.now() > sessionEntry.expiresAt) {
      sessionStore.delete(sessionId);
      return null;
    }

    // Update last activity
    sessionEntry.data.lastActivity = Date.now();
    
    return sessionEntry.data;
  }

  destroySession(cookieHeader?: string): string {
    if (cookieHeader) {
      const cookies = parse(cookieHeader);
      const sessionId = cookies[this.cookieName];
      
      if (sessionId && sessionStore.has(sessionId)) {
        sessionStore.delete(sessionId);
        console.log(`🗑️ Destroyed session: ${sessionId.substring(0, 8)}...`);
      }
    }

    return serialize(this.cookieName, '', {
      httpOnly: true,
      secure: true,
      sameSite: 'none',
      maxAge: 0,
      path: '/',
    });
  }

  // Helper method to get session stats
  getSessionStats() {
    return {
      totalSessions: sessionStore.size,
      activeSessions: Array.from(sessionStore.values()).filter(s => Date.now() < s.expiresAt).length
    };
  }
}

export function createSessionManager(): SessionManager {
  return new SessionManager();
}
