import type { Tool, ToolResult } from '../types.js';
import type { SessionManager } from '../../session/manager.js';

interface SessionsListArgs {
  // no args
}

interface SessionsHistoryArgs {
  sessionId: string;
  limit?: number;
  offset?: number;
}

interface SessionsCreateArgs {
  frontend: string;
  userId: string;
}

interface SessionsDeleteArgs {
  frontend: string;
  userId: string;
}

/**
 * Creates session management tools bound to the given SessionManager.
 */
export function createSessionTools(sessionManager: SessionManager): Tool[] {
  const sessionsList: Tool = {
    name: 'sessions.list',
    description:
      'List all active sessions. Returns session IDs and message counts.',
    inputSchema: {
      type: 'object',
      properties: {},
    },
    execute: async (_rawArgs: unknown): Promise<ToolResult> => {
      try {
        const sessionIds = sessionManager.listSessions();
        if (sessionIds.length === 0) {
          return { success: true, output: 'No active sessions.' };
        }

        const sessions = sessionIds.map((id) => {
          const parts = id.split(':');
          const frontend = parts[0];
          const userId = parts.slice(1).join(':');
          const session = sessionManager.getSession(frontend, userId);
          return {
            id,
            frontend,
            userId,
            messageCount: session.getHistory().length,
          };
        });

        const lines = sessions.map(
          (s) => `- **${s.id}** (${s.messageCount} messages)`,
        );
        return { success: true, output: lines.join('\n') };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
        };
      }
    },
  };

  const sessionsHistory: Tool = {
    name: 'sessions.history',
    description:
      'Get the message history for a specific session. Returns the messages with role and content.',
    inputSchema: {
      type: 'object',
      properties: {
        sessionId: {
          type: 'string',
          description: 'Session ID in "frontend:userId" format',
        },
        limit: {
          type: 'number',
          description: 'Maximum number of messages to return (default: all)',
        },
        offset: {
          type: 'number',
          description: 'Number of messages to skip from the start (default: 0)',
        },
      },
      required: ['sessionId'],
    },
    execute: async (rawArgs: unknown): Promise<ToolResult> => {
      const args = rawArgs as SessionsHistoryArgs;

      try {
        const parts = args.sessionId.split(':');
        const frontend = parts[0];
        const userId = parts.slice(1).join(':');
        const session = sessionManager.getSession(frontend, userId);
        const allMessages = session.getHistory();

        const start = args.offset ?? 0;
        const end = args.limit ? start + args.limit : allMessages.length;
        const messages = allMessages.slice(start, end);

        if (messages.length === 0) {
          return {
            success: true,
            output: `Session "${args.sessionId}" has no messages${start > 0 ? ' at this offset' : ''}.`,
          };
        }

        const lines = messages.map((m, i) => {
          const content =
            typeof m.content === 'string'
              ? m.content.slice(0, 200)
              : '[multipart]';
          return `${start + i + 1}. [${m.role}] ${content}`;
        });

        return {
          success: true,
          output: `Session "${args.sessionId}" (${allMessages.length} total messages):\n\n${lines.join('\n')}`,
        };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
        };
      }
    },
  };

  const sessionsCreate: Tool = {
    name: 'sessions.create',
    description:
      'Create a new session (or get an existing one). Returns the session ID.',
    inputSchema: {
      type: 'object',
      properties: {
        frontend: {
          type: 'string',
          description: 'Frontend/channel name (e.g. "telegram", "webchat")',
        },
        userId: {
          type: 'string',
          description: 'User ID for this session',
        },
      },
      required: ['frontend', 'userId'],
    },
    execute: async (rawArgs: unknown): Promise<ToolResult> => {
      const args = rawArgs as SessionsCreateArgs;

      try {
        const session = sessionManager.getSession(args.frontend, args.userId);
        return {
          success: true,
          output: `Session "${session.id}" ready (${session.getHistory().length} existing messages).`,
        };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
        };
      }
    },
  };

  const sessionsDelete: Tool = {
    name: 'sessions.delete',
    description:
      'Clear a session history and close it. The session ID is "frontend:userId".',
    inputSchema: {
      type: 'object',
      properties: {
        frontend: {
          type: 'string',
          description: 'Frontend/channel name',
        },
        userId: {
          type: 'string',
          description: 'User ID',
        },
      },
      required: ['frontend', 'userId'],
    },
    execute: async (rawArgs: unknown): Promise<ToolResult> => {
      const args = rawArgs as SessionsDeleteArgs;

      try {
        const session = sessionManager.getSession(args.frontend, args.userId);
        const messageCount = session.getHistory().length;
        session.clear();
        sessionManager.closeSession(args.frontend, args.userId);
        return {
          success: true,
          output: `Session "${args.frontend}:${args.userId}" cleared (${messageCount} messages removed).`,
        };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
        };
      }
    },
  };

  return [sessionsList, sessionsHistory, sessionsCreate, sessionsDelete];
}
