import { Inject, Injectable, Logger } from '@nestjs/common';
import { eq, and, type Db, teams, teamMembers, projects } from '@mosaicstack/db';
import { DB } from '../database/database.module.js';

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

  constructor(@Inject(DB) private readonly db: Db) {}

  /**
   * Check if a user is a member of a team.
   */
  async isMember(teamId: string, userId: string): Promise<boolean> {
    const rows = await this.db
      .select({ id: teamMembers.id })
      .from(teamMembers)
      .where(and(eq(teamMembers.teamId, teamId), eq(teamMembers.userId, userId)));
    return rows.length > 0;
  }

  /**
   * Check project access for a user.
   * - ownerType === 'user': project.ownerId must equal userId
   * - ownerType === 'team': userId must be a member of project.teamId
   */
  async canAccessProject(userId: string, projectId: string): Promise<boolean> {
    const rows = await this.db
      .select({
        id: projects.id,
        ownerType: projects.ownerType,
        ownerId: projects.ownerId,
        teamId: projects.teamId,
      })
      .from(projects)
      .where(eq(projects.id, projectId));

    const project = rows[0];
    if (!project) return false;

    if (project.ownerType === 'user') {
      return project.ownerId === userId;
    }

    if (project.ownerType === 'team' && project.teamId) {
      return this.isMember(project.teamId, userId);
    }

    return false;
  }

  /**
   * List all teams (for admin/listing endpoints).
   */
  async findAll() {
    return this.db.select().from(teams);
  }

  /**
   * Find a team by ID.
   */
  async findById(id: string) {
    const rows = await this.db.select().from(teams).where(eq(teams.id, id));
    return rows[0];
  }

  /**
   * List members of a team.
   */
  async listMembers(teamId: string) {
    return this.db.select().from(teamMembers).where(eq(teamMembers.teamId, teamId));
  }
}
