import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  Res,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiExcludeEndpoint, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { Throttle } from '../../common/decorators/throttle.decorator';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { JwtPayload } from '../../common/interfaces/jwt-payload.interface';
import { HlsPlaylistService } from '../../common/media/hls-playlist.service';
import { AiMusicArchiveQueryDto } from './dto/ai-music-archive-query.dto';
import { ShareAiMusicArchiveToFeedDto } from './dto/share-ai-music-archive.dto';
import { TextToMusicDto } from './dto/text-to-music.dto';
import { UpdateAiMusicArchiveDto } from './dto/update-ai-music-archive.dto';
import { MediaService } from './media.service';

@ApiTags('Media')
@Controller('media')
export class MediaController {
  constructor(
    private readonly mediaService: MediaService,
    private readonly hlsPlaylistService: HlsPlaylistService,
  ) {}

  @Get('hls/*')
  @ApiExcludeEndpoint()
  async hlsPlaylist(
    @Param() params: Record<string, string>,
    @Query('expires') expires: string | undefined,
    @Query('signature') signature: string | undefined,
    @Res({ passthrough: true }) response: Response,
  ): Promise<string> {
    response.type('application/vnd.apple.mpegurl');
    response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
    response.setHeader('X-Content-Type-Options', 'nosniff');
    return this.hlsPlaylistService.rewritePlaylist(params['0'] ?? '', { expires, signature });
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Get('health')
  async mediaHealth() {
    return this.mediaService.getMediaHealth();
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Post('ai/text-to-music')
  @Throttle(6, 60_000)
  async generateMusicFromText(@CurrentUser() user: JwtPayload, @Body() dto: TextToMusicDto) {
    return this.mediaService.generateMusicFromText(user.sub, dto);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Get('ai/music/archive')
  async getMyAiMusicArchive(
    @CurrentUser() user: JwtPayload,
    @Query() query: AiMusicArchiveQueryDto,
  ) {
    return this.mediaService.getMyAiMusicArchive(user.sub, query);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Get('ai/music/archive/:id')
  async getAiMusicArchiveItem(@CurrentUser() user: JwtPayload, @Param('id') itemId: string) {
    return this.mediaService.getAiMusicArchiveItem(user.sub, itemId);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Patch('ai/music/archive/:id')
  async renameAiMusicArchiveItem(
    @CurrentUser() user: JwtPayload,
    @Param('id') itemId: string,
    @Body() dto: UpdateAiMusicArchiveDto,
  ) {
    return this.mediaService.renameAiMusicArchiveItem(user.sub, itemId, dto);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Delete('ai/music/archive/:id')
  async deleteAiMusicArchiveItem(@CurrentUser() user: JwtPayload, @Param('id') itemId: string) {
    return this.mediaService.deleteAiMusicArchiveItem(user.sub, itemId);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Post('ai/music/archive/:id/share')
  async shareAiMusicArchiveItem(@CurrentUser() user: JwtPayload, @Param('id') itemId: string) {
    return this.mediaService.shareAiMusicArchiveItem(user.sub, itemId);
  }

  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  @Post('ai/music/archive/:id/share-to-feed')
  async shareAiMusicArchiveItemToFeed(
    @CurrentUser() user: JwtPayload,
    @Param('id') itemId: string,
    @Body() dto: ShareAiMusicArchiveToFeedDto,
  ) {
    return this.mediaService.shareAiMusicArchiveItemToFeed(user.sub, itemId, dto);
  }
}
