import {
  Controller,
  ForbiddenException,
  Get,
  NotFoundException,
  Param,
  UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard.js';
import { CurrentUser } from '../auth/current-user.decorator.js';
import { TeamsService } from './teams.service.js';

type RequestUser = { id: string; role?: string };

@Controller('api/teams')
@UseGuards(AuthGuard)
export class TeamsController {
  constructor(private readonly teams: TeamsService) {}

  @Get()
  async list(@CurrentUser() user: RequestUser) {
    if (user.role === 'admin') {
      return this.teams.findAll();
    }
    return this.teams.findAllForUser(user.id);
  }

  @Get(':teamId')
  async findOne(@Param('teamId') teamId: string, @CurrentUser() user: RequestUser) {
    return this.getAccessibleTeam(teamId, user);
  }

  @Get(':teamId/members')
  async listMembers(@Param('teamId') teamId: string, @CurrentUser() user: RequestUser) {
    await this.getAccessibleTeam(teamId, user);
    return this.teams.listMembers(teamId);
  }

  @Get(':teamId/members/:userId')
  async checkMembership(
    @Param('teamId') teamId: string,
    @Param('userId') userId: string,
    @CurrentUser() user: RequestUser,
  ) {
    // A user may always ask about their own membership; anything else is
    // team-scoped like the other routes.
    if (userId !== user.id) {
      await this.getAccessibleTeam(teamId, user);
    }
    const isMember = await this.teams.isMember(teamId, userId);
    return { isMember };
  }

  /**
   * Team-scoped access: admins see any team; everyone else only teams they
   * are a member of. NotFoundException when the team does not exist and
   * ForbiddenException when the user lacks access (same convention as the
   * projects controller).
   */
  private async getAccessibleTeam(teamId: string, user: RequestUser) {
    const team = await this.teams.findById(teamId);
    if (!team) throw new NotFoundException('Team not found');
    if (user.role === 'admin') return team;
    const isMember = await this.teams.isMember(teamId, user.id);
    if (!isMember) throw new ForbiddenException('Not a member of this team');
    return team;
  }
}
