/**
 * TerminalSessionService
 *
 * Manages database persistence for terminal sessions.
 * Provides CRUD operations on the TerminalSession model,
 * enabling session tracking, recovery, and workspace-level listing.
 *
 * Session lifecycle:
 * - create: record a new terminal session with ACTIVE status
 * - findByWorkspace: return all ACTIVE sessions for a workspace
 * - close: mark a session as CLOSED, set closedAt timestamp
 * - findById: retrieve a single session by ID
 */

import { Injectable, NotFoundException, Logger } from "@nestjs/common";
import { TerminalSessionStatus } from "@prisma/client";
import type { TerminalSession } from "@prisma/client";
import { PrismaService } from "../prisma/prisma.service";

@Injectable()
export class TerminalSessionService {
  private readonly logger = new Logger(TerminalSessionService.name);

  constructor(private readonly prisma: PrismaService) {}

  /**
   * Create a new terminal session record in the database.
   *
   * @param workspaceId - The workspace this session belongs to
   * @param name - Optional display name for the session (defaults to "Terminal")
   * @returns The created TerminalSession record
   */
  async create(workspaceId: string, name?: string): Promise<TerminalSession> {
    this.logger.log(
      `Creating terminal session for workspace ${workspaceId}${name !== undefined ? ` (name: ${name})` : ""}`
    );

    const data: { workspaceId: string; name?: string } = { workspaceId };
    if (name !== undefined) {
      data.name = name;
    }

    return this.prisma.terminalSession.create({ data });
  }

  /**
   * Find all ACTIVE terminal sessions for a workspace.
   *
   * @param workspaceId - The workspace to query
   * @returns Array of active TerminalSession records, ordered by creation time (newest first)
   */
  async findByWorkspace(workspaceId: string): Promise<TerminalSession[]> {
    return this.prisma.terminalSession.findMany({
      where: {
        workspaceId,
        status: TerminalSessionStatus.ACTIVE,
      },
      orderBy: { createdAt: "desc" },
    });
  }

  /**
   * Close a terminal session by setting its status to CLOSED and recording closedAt.
   *
   * @param id - The session ID to close
   * @returns The updated TerminalSession record
   * @throws NotFoundException if the session does not exist
   */
  async close(id: string): Promise<TerminalSession> {
    const existing = await this.prisma.terminalSession.findUnique({ where: { id } });

    if (!existing) {
      throw new NotFoundException(`Terminal session ${id} not found`);
    }

    this.logger.log(`Closing terminal session ${id} (workspace: ${existing.workspaceId})`);

    return this.prisma.terminalSession.update({
      where: { id },
      data: {
        status: TerminalSessionStatus.CLOSED,
        closedAt: new Date(),
      },
    });
  }

  /**
   * Find a terminal session by ID.
   *
   * @param id - The session ID to retrieve
   * @returns The TerminalSession record, or null if not found
   */
  async findById(id: string): Promise<TerminalSession | null> {
    return this.prisma.terminalSession.findUnique({ where: { id } });
  }
}
