import { Controller, Post, Body, Get, Param, Query, UseGuards, Request, BadRequestException } from '@nestjs/common';
import { NodesService } from './nodes.service.js';
import { AuthGuard } from '@nestjs/passport';

@UseGuards(AuthGuard('jwt'))
@Controller('nodes')
export class NodesController {
  constructor(private readonly nodesService: NodesService) {}

  @Post('folder')
  createFolder(@Body() body: { name: string; parentId?: string }, @Request() req: any) {
    return this.nodesService.createFolder(body.name, body.parentId || null, req.user.userId);
  }

  @Post('upload-request')
  requestUpload(@Body() body: { name: string; sizeBytes: number; parentId?: string; mimeType: string }, @Request() req: any) {
    return this.nodesService.requestFileUpload(
      body.name,
      body.sizeBytes,
      body.parentId || null,
      body.mimeType,
      req.user.userId
    );
  }

  @Get('download/:id')
  getDownloadUrl(@Param('id') id: string, @Request() req: any) {
    return this.nodesService.getFileDownloadUrl(id, req.user.userId);
  }

  @Get()
  listNodes(
    @Query('parentId') parentId: string, 
    @Query('tab') tab: string, 
    @Query('search') search: string, 
    @Request() req: any
  ) {
    return this.nodesService.listNodes(parentId || null, req.user.userId, tab, search);
  }

  @Post(':id/rename')
  renameNode(@Param('id') id: string, @Body() body: { name: string }, @Request() req: any) {
    return this.nodesService.renameNode(id, body.name, req.user.userId);
  }

  @Post(':id/delete')
  deleteNode(@Param('id') id: string, @Request() req: any) {
    return this.nodesService.deleteNode(id, req.user.userId);
  }

  @Post(':id/restore')
  restoreNode(@Param('id') id: string, @Request() req: any) {
    return this.nodesService.restoreNode(id, req.user.userId);
  }

  @Post(':id/share')
  async shareNode(@Param('id') id: string, @Body('email') email: string, @Request() req: any) {
    try {
      return await this.nodesService.shareNode(id, email, req.user.userId);
    } catch (e: any) {
      throw new BadRequestException(e.message);
    }
  }

  @Post(':id/move')
  async moveNode(@Param('id') id: string, @Body('parentId') parentId: string | null, @Request() req: any) {
    return this.nodesService.moveNode(id, parentId, req.user.userId);
  }

  @Get(':id/permissions')
  async getPermissions(@Param('id') id: string, @Request() req: any) {
    try {
      return await this.nodesService.getPermissions(id, req.user.userId);
    } catch (e: any) {
      throw new BadRequestException(e.message);
    }
  }

  @Post(':id/permissions/:permId')
  async updatePermission(@Param('id') id: string, @Param('permId') permId: string, @Body('role') role: string, @Request() req: any) {
    try {
      return await this.nodesService.updatePermission(id, permId, role, req.user.userId);
    } catch (e: any) {
      throw new BadRequestException(e.message);
    }
  }

  @Post(':id/permissions/:permId/remove')
  async removePermission(@Param('id') id: string, @Param('permId') permId: string, @Request() req: any) {
    try {
      return await this.nodesService.removePermission(id, permId, req.user.userId);
    } catch (e: any) {
      throw new BadRequestException(e.message);
    }
  }

  @Get('starred-ids')
  getStarredIds(@Request() req: any) {
    return this.nodesService.getStarredIds(req.user.userId);
  }

  @Post(':id/star')
  async toggleStar(@Param('id') id: string, @Body('isStarred') isStarred: boolean, @Request() req: any) {
    return this.nodesService.toggleStar(id, isStarred, req.user.userId);
  }

  @Post(':id/color')
  async updateFolderColor(@Param('id') id: string, @Body('color') color: string, @Request() req: any) {
    try {
      return await this.nodesService.updateFolderColor(id, color, req.user.userId);
    } catch (e: any) {
      throw new BadRequestException(e.message);
    }
  }

  @Get('notifications')
  async getNotifications(@Request() req: any) {
    return await this.nodesService.getNotifications(req.user.userId);
  }

  @Post('notifications/read')
  async markNotificationsRead(@Request() req: any) {
    return await this.nodesService.markNotificationsRead(req.user.userId);
  }
}
