import {
  Controller,
  Delete,
  Get,
  Param,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports -- NestJS DI requires value imports for emitDecoratorMetadata
import { CommandBus, QueryBus } from '@nestjs/cqrs';
import {
  ApiBearerAuth,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
// eslint-disable-next-line @typescript-eslint/consistent-type-imports -- NestJS DI requires value imports for emitDecoratorMetadata
import { CurrentUser, JwtAuthGuard, type JwtPayload } from '@modules/auth';
import { AddFavoriteCommand } from '../../application/commands/add-favorite/add-favorite.command';
import { type AddFavoriteResult } from '../../application/commands/add-favorite/add-favorite.handler';
import { RemoveFavoriteCommand } from '../../application/commands/remove-favorite/remove-favorite.command';
import { IsFavoritedQuery } from '../../application/queries/is-favorited/is-favorited.query';
import { type IsFavoritedResult } from '../../application/queries/is-favorited/is-favorited.handler';
import { ListFavoritesQuery } from '../../application/queries/list-favorites/list-favorites.query';
import { type ListFavoritesResult } from '../../application/queries/list-favorites/list-favorites.handler';
import { ListFavoritesDto } from '../dto/list-favorites.dto';

@ApiTags('favorites')
@Controller('favorites')
export class FavoritesController {
  constructor(
    private readonly commandBus: CommandBus,
    private readonly queryBus: QueryBus,
  ) {}

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Add a listing to favorites' })
  @ApiParam({ name: 'listingId', description: 'Listing ID to favorite' })
  @ApiResponse({ status: 201, description: 'Listing added to favorites' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 409, description: 'Listing already favorited' })
  @UseGuards(JwtAuthGuard)
  @Post(':listingId')
  async addFavorite(
    @Param('listingId') listingId: string,
    @CurrentUser() user: JwtPayload,
  ): Promise<AddFavoriteResult> {
    return this.commandBus.execute(new AddFavoriteCommand(user.sub, listingId));
  }

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Remove a listing from favorites' })
  @ApiParam({ name: 'listingId', description: 'Listing ID to remove' })
  @ApiResponse({ status: 200, description: 'Listing removed from favorites' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Favorite not found' })
  @UseGuards(JwtAuthGuard)
  @Delete(':listingId')
  async removeFavorite(
    @Param('listingId') listingId: string,
    @CurrentUser() user: JwtPayload,
  ): Promise<{ success: boolean }> {
    await this.commandBus.execute(
      new RemoveFavoriteCommand(user.sub, listingId),
    );
    return { success: true };
  }

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'List authenticated user favorites' })
  @ApiResponse({ status: 200, description: 'Paginated list of favorites' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @UseGuards(JwtAuthGuard)
  @Get()
  async listFavorites(
    @Query() dto: ListFavoritesDto,
    @CurrentUser() user: JwtPayload,
  ): Promise<ListFavoritesResult> {
    return this.queryBus.execute(
      new ListFavoritesQuery(user.sub, dto.page ?? 1, dto.limit ?? 20),
    );
  }

  @ApiBearerAuth('JWT')
  @ApiOperation({ summary: 'Check whether a listing is favorited by the user' })
  @ApiParam({ name: 'listingId', description: 'Listing ID to check' })
  @ApiResponse({ status: 200, description: 'Favorited flag' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @UseGuards(JwtAuthGuard)
  @Get(':listingId/check')
  async isFavorited(
    @Param('listingId') listingId: string,
    @CurrentUser() user: JwtPayload,
  ): Promise<IsFavoritedResult> {
    return this.queryBus.execute(new IsFavoritedQuery(user.sub, listingId));
  }
}
