import type { License, ChannelType } from '../../types/user.js';
import type { BaseMessage } from '@langchain/core/messages';

/**
 * Channel capabilities (what the channel supports)
 */
export interface ChannelCapabilities {
  supportsMarkdown: boolean;
  supportsImages: boolean;
  supportsButtons: boolean;
  supportsVoice: boolean;
  supportsFiles: boolean;
  maxMessageLength: number;
}

/**
 * Active channel information for multi-channel routing
 */
export interface ActiveChannel {
  type: ChannelType;
  channelUserId: string; // Platform-specific ID (telegram_id, discord_id, etc)
  capabilities: ChannelCapabilities;
  metadata?: Record<string, unknown>;
}

/**
 * Workspace state (current user context)
 */
export interface WorkspaceContext {
  activeIndicators: string[];
  activeStrategies: string[];
  watchlist: string[];
  recentQueries: string[];
  preferences: Record<string, unknown>;
}

/**
 * Enhanced user context for agent harness
 *
 * Contains all necessary context for an agent session:
 * - User identity and license
 * - Active channel info (for multi-channel support)
 * - Conversation state and history
 * - Workspace state
 *
 * This object is passed to all agent nodes and tools.
 */
export interface UserContext {
  // Identity
  userId: string;
  sessionId: string;
  license: License;

  // Channel context (for multi-channel routing)
  activeChannel: ActiveChannel;

  // Conversation state
  conversationHistory: BaseMessage[];
  currentMessage?: string;

  // Workspace state
  workspaceState: WorkspaceContext;

  // Metadata
  createdAt: Date;
  lastActivity: Date;
}

/**
 * Get default channel capabilities based on type
 */
export function getDefaultCapabilities(channelType: ChannelType): ChannelCapabilities {
  switch (channelType) {
    case 'websocket':
      return {
        supportsMarkdown: true,
        supportsImages: true,
        supportsButtons: true,
        supportsVoice: false,
        supportsFiles: true,
        maxMessageLength: 100000,
      };

    case 'telegram':
      return {
        supportsMarkdown: true,
        supportsImages: true,
        supportsButtons: true,
        supportsVoice: true,
        supportsFiles: true,
        maxMessageLength: 4096,
      };

    case 'slack':
      return {
        supportsMarkdown: true,
        supportsImages: true,
        supportsButtons: true,
        supportsVoice: false,
        supportsFiles: true,
        maxMessageLength: 40000,
      };

    case 'discord':
      return {
        supportsMarkdown: true,
        supportsImages: true,
        supportsButtons: true,
        supportsVoice: true,
        supportsFiles: true,
        maxMessageLength: 2000,
      };

    default:
      // Default fallback
      return {
        supportsMarkdown: false,
        supportsImages: false,
        supportsButtons: false,
        supportsVoice: false,
        supportsFiles: false,
        maxMessageLength: 1000,
      };
  }
}

/**
 * Create a new user context
 */
export function createUserContext(params: {
  userId: string;
  sessionId: string;
  license: License;
  channelType: ChannelType;
  channelUserId: string;
  channelCapabilities?: Partial<ChannelCapabilities>;
}): UserContext {
  const defaultCapabilities = getDefaultCapabilities(params.channelType);
  const capabilities: ChannelCapabilities = {
    ...defaultCapabilities,
    ...params.channelCapabilities,
  };

  return {
    userId: params.userId,
    sessionId: params.sessionId,
    license: params.license,
    activeChannel: {
      type: params.channelType,
      channelUserId: params.channelUserId,
      capabilities,
    },
    conversationHistory: [],
    workspaceState: {
      activeIndicators: [],
      activeStrategies: [],
      watchlist: [],
      recentQueries: [],
      preferences: {},
    },
    createdAt: new Date(),
    lastActivity: new Date(),
  };
}

/**
 * Update last activity timestamp
 */
export function touchContext(context: UserContext): UserContext {
  return {
    ...context,
    lastActivity: new Date(),
  };
}

/**
 * Check if context has expired (for TTL management)
 */
export function isContextExpired(context: UserContext, ttlSeconds: number): boolean {
  const now = Date.now();
  const lastActivity = context.lastActivity.getTime();
  return (now - lastActivity) / 1000 > ttlSeconds;
}

/**
 * Serialize context for Redis storage
 */
export function serializeContext(context: UserContext): string {
  return JSON.stringify({
    ...context,
    createdAt: context.createdAt.toISOString(),
    lastActivity: context.lastActivity.toISOString(),
    // Don't serialize conversation history (too large, use checkpoint instead)
    conversationHistory: undefined,
  });
}

/**
 * Deserialize context from Redis storage
 */
export function deserializeContext(data: string): Partial<UserContext> {
  const parsed = JSON.parse(data);
  return {
    ...parsed,
    createdAt: new Date(parsed.createdAt),
    lastActivity: new Date(parsed.lastActivity),
    conversationHistory: [], // Will be loaded from checkpoint
  };
}
