/**
 * Login Flow Controller
 * 
 * Deterministic state machine for authentication flow.
 * Compliant with docs/architecture/website/LOGIN_FLOW_STATE_MACHINE.md
 */

import type { SessionViewModel } from '@/lib/view-models/SessionViewModel';

export enum LoginState {
  UNAUTHENTICATED = "UNAUTHENTICATED",
  AUTHENTICATED_WITH_PERMISSIONS = "AUTHENTICATED_WITH_PERMISSIONS", 
  AUTHENTICATED_WITHOUT_PERMISSIONS = "AUTHENTICATED_WITHOUT_PERMISSIONS",
  POST_AUTH_REDIRECT = "POST_AUTH_REDIRECT"
}

export type LoginAction = 
  | { type: 'SHOW_LOGIN_FORM' }
  | { type: 'REDIRECT'; path: string }
  | { type: 'SHOW_PERMISSION_ERROR' };

/**
 * LoginFlowController - Immutable, deterministic state machine
 * 
 * Rules:
 * - Constructed from explicit inputs only
 * - No side effects
 * - Pure functions for state transitions
 * - Side effects (routing) executed outside
 */
export class LoginFlowController {
  // Immutable state
  private readonly session: SessionViewModel | null;
  private readonly returnTo: string;
  
  // State machine
  private state: LoginState;

  constructor(session: SessionViewModel | null, returnTo: string) {
    this.session = session;
    this.returnTo = returnTo;
    this.state = this.determineInitialState();
  }

  private determineInitialState(): LoginState {
    if (!this.session) return LoginState.UNAUTHENTICATED;
    if (this.returnTo === '/dashboard') return LoginState.AUTHENTICATED_WITH_PERMISSIONS;
    return LoginState.AUTHENTICATED_WITHOUT_PERMISSIONS;
  }

  // Pure function - no side effects
  getState(): LoginState {
    return this.state;
  }

  // Pure function - returns action, does not execute
  getNextAction(): LoginAction {
    switch (this.state) {
      case LoginState.UNAUTHENTICATED:
        return { type: 'SHOW_LOGIN_FORM' };
      case LoginState.AUTHENTICATED_WITH_PERMISSIONS:
        return { type: 'REDIRECT', path: '/dashboard' };
      case LoginState.AUTHENTICATED_WITHOUT_PERMISSIONS:
        return { type: 'SHOW_PERMISSION_ERROR' };
      case LoginState.POST_AUTH_REDIRECT:
        return { type: 'REDIRECT', path: this.returnTo };
    }
  }

  // Transition called after authentication
  transitionToPostAuth(): void {
    if (this.session) {
      this.state = LoginState.POST_AUTH_REDIRECT;
    }
  }
}