import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards, UseInterceptors, UploadedFile } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CmsService } from '../services/cms.service';
import { UploadService } from '../services/upload.service';

@ApiTags('CMS Management')
@ApiBearerAuth()
@Controller('admin/cms')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
export class CmsController {
  constructor(
    private readonly cmsService: CmsService,
    private readonly uploadService: UploadService,
  ) {}

  @Get('content')
  @ApiOperation({ summary: 'Get all CMS content' })
  @ApiResponse({ status: 200, description: 'Returns all CMS content' })
  async getAllContent() {
    return this.cmsService.getAllContent();
  }

  @Get('content/section/:section')
  @ApiOperation({ summary: 'Get content by section' })
  @ApiResponse({ status: 200, description: 'Returns content for the specified section' })
  async getContentBySection(@Param('section') section: string) {
    return this.cmsService.getContentBySection(section);
  }

  @Get('content/key/:key')
  @ApiOperation({ summary: 'Get content by key' })
  @ApiResponse({ status: 200, description: 'Returns content for the specified key' })
  async getContentByKey(@Param('key') key: string) {
    return this.cmsService.getContentByKey(key);
  }

  @Get('content/type/:type')
  @ApiOperation({ summary: 'Get content by type' })
  @ApiResponse({ status: 200, description: 'Returns content for the specified type' })
  async getContentByType(@Param('type') type: string) {
    return this.cmsService.getContentByType(type);
  }

  @Post('content')
  @ApiOperation({ summary: 'Create new content' })
  @ApiResponse({ status: 201, description: 'Content created successfully' })
  async createContent(@Body() contentData: any) {
    return this.cmsService.createContent(contentData);
  }

  @Put('content/:id')
  @ApiOperation({ summary: 'Update content by ID' })
  @ApiResponse({ status: 200, description: 'Content updated successfully' })
  async updateContent(@Param('id') id: string, @Body() contentData: any) {
    return this.cmsService.updateContent(id, contentData);
  }

  @Put('content/key/:key')
  @ApiOperation({ summary: 'Update content by key' })
  @ApiResponse({ status: 200, description: 'Content updated successfully' })
  async updateContentByKey(@Param('key') key: string, @Body() contentData: any) {
    return this.cmsService.updateContentByKey(key, contentData);
  }

  @Post('content/bulk-update')
  @ApiOperation({ summary: 'Bulk update content' })
  @ApiResponse({ status: 200, description: 'Content updated successfully' })
  async bulkUpdateContent(@Body() updates: Array<{ key: string; value: string; image?: string }>) {
    return this.cmsService.bulkUpdateContent(updates);
  }

  @Delete('content/:id')
  @ApiOperation({ summary: 'Delete content by ID' })
  @ApiResponse({ status: 200, description: 'Content deleted successfully' })
  async deleteContent(@Param('id') id: string) {
    return this.cmsService.deleteContent(id);
  }

  @Post('upload/image')
  @UseInterceptors(FileInterceptor('file'))
  @ApiOperation({ summary: 'Upload image for CMS' })
  @ApiResponse({ status: 201, description: 'Image uploaded successfully' })
  async uploadImage(
    @UploadedFile() file: Express.Multer.File,
    @Body() data: { section: string; key: string }
  ) {
    // Use Multer's file info and UploadService.getFileUrl
    const fileUrl = this.uploadService.getFileUrl(file.filename, 'cms');
    await this.cmsService.updateContentByKey(data.key, {
      image: fileUrl,
      value: file.filename
    });

    return {
      success: true,
      file: {
        filename: file.filename,
        url: fileUrl,
        mimetype: file.mimetype,
        size: file.size
      },
      contentKey: data.key
    };
  }

  @Get('sections')
  @ApiOperation({ summary: 'Get all available sections' })
  @ApiResponse({ status: 200, description: 'Returns all sections' })
  async getSections() {
    const content = await this.cmsService.getAllContent();
    const sections = [...new Set(content.map(item => item.section).filter(Boolean))];
    return sections.sort();
  }

  @Get('sections/:section/overview')
  @ApiOperation({ summary: 'Get section overview with content count' })
  @ApiResponse({ status: 200, description: 'Returns section overview' })
  async getSectionOverview(@Param('section') section: string) {
    const content = await this.cmsService.getContentBySection(section);
    const textContent = content.filter(item => item.type === 'text');
    const imageContent = content.filter(item => item.type === 'image');
    
    return {
      section,
      totalItems: content.length,
      textItems: textContent.length,
      imageItems: imageContent.length,
      content: content.sort((a, b) => a.sortOrder - b.sortOrder)
    };
  }

  @Get('theme')
  @ApiOperation({ summary: 'Get current theme' })
  @ApiResponse({ status: 200, description: 'Returns current theme' })
  async getTheme() {
    return this.cmsService.getTheme();
  }

  @Put('theme')
  @ApiOperation({ summary: 'Update theme' })
  @ApiResponse({ status: 200, description: 'Theme updated successfully' })
  async updateTheme(@Body() themeData: any) {
    return this.cmsService.updateTheme(themeData);
  }

  @Post('backup')
  @ApiOperation({ summary: 'Create content backup' })
  @ApiResponse({ status: 201, description: 'Backup created successfully' })
  async createBackup() {
    await this.cmsService.backupContent();
    return { success: true, message: 'Backup created successfully' };
  }

  @Post('restore/:filename')
  @ApiOperation({ summary: 'Restore content from backup' })
  @ApiResponse({ status: 200, description: 'Content restored successfully' })
  async restoreBackup(@Param('filename') filename: string) {
    await this.cmsService.restoreBackup(filename);
    return { success: true, message: 'Content restored successfully' };
  }
} 