import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery, ApiConsumes } from '@nestjs/swagger';
import { PluginsService } from './plugins.service';
import { InstallPluginDto } from './dto/install-plugin.dto';
import { UpdatePluginConfigDto } from './dto/update-plugin-config.dto';
import { CurrentTenant } from '../../common/decorators/current-tenant.decorator';
import { RequirePermission } from '../../common/decorators/require-permission.decorator';
import { JwtAuthGuard } from '../../common/guards/jwt-auth.guard';
import { PermissionsGuard } from '../../common/guards/permissions.guard';

@ApiTags('plugins')
@ApiBearerAuth()
@Controller('plugins')
@UseGuards(JwtAuthGuard, PermissionsGuard)
export class PluginsController {
  constructor(private readonly pluginsService: PluginsService) {}

  @Get()
  @RequirePermission('plugin.view')
  @ApiOperation({ summary: 'Get all installed plugins for tenant' })
  getPlugins(@CurrentTenant() licenseId: string) {
    return this.pluginsService.getPlugins(licenseId);
  }

  @Post('install')
  @RequirePermission('plugin.manage')
  @ApiOperation({ summary: 'Install new plugin' })
  installPlugin(@CurrentTenant() licenseId: string, @Body() dto: InstallPluginDto) {
    return this.pluginsService.installPlugin(licenseId, dto);
  }

  @Delete(':id')
  @RequirePermission('plugin.manage')
  @ApiOperation({ summary: 'Uninstall plugin' })
  async uninstallPlugin(@CurrentTenant() licenseId: string, @Param('id') pluginId: string) {
    await this.pluginsService.uninstallPlugin(licenseId, pluginId);
    return { deleted: true };
  }

  @Post(':id/reload')
  @RequirePermission('plugin.manage')
  @ApiOperation({ summary: 'Reload plugin on game server' })
  reloadPlugin(@CurrentTenant() licenseId: string, @Param('id') pluginId: string) {
    return this.pluginsService.reloadPlugin(licenseId, pluginId);
  }

  @Put(':id/config')
  @RequirePermission('plugin.manage')
  @ApiOperation({ summary: 'Update plugin configuration' })
  updateConfig(
    @CurrentTenant() licenseId: string,
    @Param('id') pluginId: string,
    @Body() dto: UpdatePluginConfigDto,
  ) {
    return this.pluginsService.updateConfig(licenseId, pluginId, dto);
  }

  @Get('search')
  @RequirePermission('plugin.view')
  @ApiOperation({ summary: 'Search uMod plugin directory (legacy stub)' })
  @ApiQuery({ name: 'q', required: true, example: 'kits' })
  searchUmod(@Query('q') query: string) {
    return this.pluginsService.searchUmod(query);
  }

  @Get('browse')
  @RequirePermission('plugin.view')
  @ApiOperation({ summary: 'Browse uMod plugin directory (proxied)' })
  @ApiQuery({ name: 'query', required: false, example: 'vanish' })
  @ApiQuery({ name: 'page', required: false, example: 1 })
  @ApiQuery({ name: 'sort', required: false, example: 'downloads' })
  browseUmod(
    @Query('query') query: string,
    @Query('page') page: string,
    @Query('sort') sort: string,
  ) {
    return this.pluginsService.browseUmod(query, page ? parseInt(page, 10) : 1, sort);
  }

  @Post('upload')
  @RequirePermission('plugin.manage')
  @ApiOperation({ summary: 'Upload a custom .cs plugin file' })
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(FileInterceptor('file'))
  uploadPlugin(
    @CurrentTenant() licenseId: string,
    @UploadedFile() file: Express.Multer.File,
  ) {
    if (!file) {
      throw new BadRequestException('No file provided');
    }
    return this.pluginsService.uploadPlugin(licenseId, file);
  }
}
