import { Controller, Get, Delete, Param, Query, NotFoundException } from '@nestjs/common';
import { TenantId } from '@it0/common';
import { SessionRepository } from '../../../infrastructure/repositories/session.repository';
import { TaskRepository } from '../../../infrastructure/repositories/task.repository';
import { MessageRepository } from '../../../infrastructure/repositories/message.repository';

@Controller('api/v1/agent/sessions')
export class SessionController {
  constructor(
    private readonly sessionRepository: SessionRepository,
    private readonly taskRepository: TaskRepository,
    private readonly messageRepository: MessageRepository,
  ) {}

  @Get()
  async listSessions(@TenantId() tenantId: string) {
    const sessions = await this.sessionRepository.findByTenant(tenantId);
    // Return a safe DTO: systemPrompt is an internal engine instruction and must
    // NOT be sent to the client (it would be displayed as the conversation title).
    // The client derives the display title from metadata.title / metadata.voiceMode.
    return sessions.map((s) => ({
      id: s.id,
      status: s.status,
      engineType: s.engineType,
      metadata: s.metadata,   // contains { title, voiceMode, titleSet, sdkSessionId? }
      createdAt: s.createdAt,
      updatedAt: s.updatedAt,
    }));
  }

  @Get(':sessionId')
  async getSession(@Param('sessionId') sessionId: string) {
    const session = await this.sessionRepository.findById(sessionId);
    if (!session) {
      throw new NotFoundException(`Session ${sessionId} not found`);
    }
    return session;
  }

  @Get(':sessionId/history')
  async getSessionHistory(@Param('sessionId') sessionId: string) {
    return this.taskRepository.findBySessionId(sessionId);
  }

  @Get(':sessionId/messages')
  async getSessionMessages(
    @Param('sessionId') sessionId: string,
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    const session = await this.sessionRepository.findById(sessionId);
    if (!session) {
      throw new NotFoundException(`Session ${sessionId} not found`);
    }

    const messages = await this.messageRepository.findBySessionId(
      sessionId,
      limit ? parseInt(limit, 10) : 50,
      offset ? parseInt(offset, 10) : 0,
    );
    const total = await this.messageRepository.countBySessionId(sessionId);

    return {
      messages,
      total,
      sessionId,
    };
  }

  @Delete(':sessionId/messages')
  async clearSessionMessages(@Param('sessionId') sessionId: string) {
    const session = await this.sessionRepository.findById(sessionId);
    if (!session) {
      throw new NotFoundException(`Session ${sessionId} not found`);
    }

    await this.messageRepository.deleteBySessionId(sessionId);
    return { message: 'Conversation history cleared', sessionId };
  }

  @Delete(':sessionId')
  async deleteSession(@Param('sessionId') sessionId: string) {
    const session = await this.sessionRepository.findById(sessionId);
    if (!session) {
      throw new NotFoundException(`Session ${sessionId} not found`);
    }

    // Delete messages first (cascade should handle this, but be explicit)
    await this.messageRepository.deleteBySessionId(sessionId);

    // Delete tasks
    const tasks = await this.taskRepository.findBySessionId(sessionId);
    for (const task of tasks) {
      await this.taskRepository.remove(task);
    }

    // Delete session
    await this.sessionRepository.remove(session);
    return { message: 'Session deleted', sessionId };
  }
}
