import {
  Body,
  Controller,
  Get,
  Param,
  ParseIntPipe,
  ParseUUIDPipe,
  Post,
  Query,
  Req,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import {
  ListInboxQueryDto,
  MarkCaseReadDto,
  MarkTabReadDto,
} from './dto/notifications.dto';
import { LabCaseActivityService } from './lab-case-activity.service';
import { UserNotificationService } from './user-notification.service';

@ApiTags('notifications')
@ApiBearerAuth('JWT-auth')
@UseGuards(JwtAuthGuard)
@Controller('notifications')
export class NotificationsController {
  constructor(
    private readonly labCaseActivityService: LabCaseActivityService,
    private readonly userNotifications: UserNotificationService,
  ) {}

  @Get('tab-counts')
  @ApiOperation({ summary: 'Unread activity counts for sidebar tab badges' })
  getTabCounts(@Req() req: { user: { id: string; organizationId?: string } }) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true, data: {} };
    }
    return this.labCaseActivityService.getTabCounts(req.user.id, organizationId);
  }

  @Post('mark-tab-read')
  @ApiOperation({ summary: 'Clear sidebar badge for a tab after the user visits it' })
  markTabRead(
    @Body() dto: MarkTabReadDto,
    @Req() req: { user: { id: string; organizationId?: string } },
  ) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true };
    }
    return this.labCaseActivityService.markTabRead(req.user.id, organizationId, dto.tab);
  }

  @Get('lab-cases/:labCaseId/activities')
  @ApiOperation({ summary: 'Activity feed for a lab case' })
  listLabCaseActivities(
    @Param('labCaseId', ParseUUIDPipe) labCaseId: string,
    @Query('limit', new ParseIntPipe({ optional: true })) limit = 50,
    @Req() req: { user: { id: string; organizationId?: string } },
  ) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true, data: [] };
    }
    return this.labCaseActivityService.listForLabCase(
      req.user.id,
      organizationId,
      labCaseId,
      limit,
    );
  }

  @Post('mark-case-read')
  @ApiOperation({ summary: 'Mark a lab case as read for the current user' })
  markCaseRead(
    @Body() dto: MarkCaseReadDto,
    @Req() req: { user: { id: string; organizationId?: string } },
  ) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true };
    }
    return this.labCaseActivityService.markCaseRead(
      req.user.id,
      organizationId,
      dto.labCaseId,
    );
  }

  @Get('inbox')
  @ApiOperation({ summary: 'Paginated notification inbox for the current user and org' })
  listInbox(
    @Query() query: ListInboxQueryDto,
    @Req() req: { user: { id: string; organizationId?: string } },
  ) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true, data: { items: [], nextCursor: null } };
    }
    return this.userNotifications.listInbox(req.user.id, organizationId, {
      limit: query.limit,
      cursor: query.cursor,
    });
  }

  @Get('inbox/unread-count')
  @ApiOperation({ summary: 'Unread inbox count for the header bell' })
  inboxUnreadCount(@Req() req: { user: { id: string; organizationId?: string } }) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true, data: { count: 0 } };
    }
    return this.userNotifications.unreadCount(req.user.id, organizationId);
  }

  @Post('inbox/read-all')
  @ApiOperation({ summary: 'Mark all inbox notifications as read for the current org' })
  markInboxReadAll(@Req() req: { user: { id: string; organizationId?: string } }) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true };
    }
    return this.userNotifications.markAllRead(req.user.id, organizationId);
  }

  @Post('inbox/:id/read')
  @ApiOperation({ summary: 'Mark a single inbox notification as read' })
  markInboxRead(
    @Param('id', ParseUUIDPipe) id: string,
    @Req() req: { user: { id: string; organizationId?: string } },
  ) {
    const organizationId = req.user.organizationId;
    if (!organizationId) {
      return { success: true, data: null };
    }
    return this.userNotifications.markRead(req.user.id, organizationId, id);
  }
}
