import {
  Controller,
  Post,
  Get,
  Patch,
  Delete,
  Param,
  Query,
  Body,
  Req,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
  UseGuards,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { PhotosService } from './photos.service';
import { PhotoType } from '../../database/entities/photo.entity';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';

@Controller('api/v1/photos')
@UseGuards(JwtAuthGuard)
export class PhotosController {
  constructor(private readonly photosService: PhotosService) {}

  @Post('upload')
  @UseInterceptors(
    FileInterceptor('photo', {
      limits: {
        fileSize: 10 * 1024 * 1024, // 10MB limit
      },
      fileFilter: (req, file, cb) => {
        if (!file.mimetype.startsWith('image/')) {
          return cb(
            new BadRequestException('Only image files are allowed'),
            false,
          );
        }
        cb(null, true);
      },
    }),
  )
  async uploadPhoto(
    @Req() req: any,
    @UploadedFile() file: Express.Multer.File,
    @Body('childId') childId?: string,
    @Body('activityId') activityId?: string,
    @Body('type') type?: string,
    @Body('caption') caption?: string,
    @Body('description') description?: string,
    @Body('takenAt') takenAt?: string,
    @Body('metadata') metadata?: string,
  ) {
    if (!file) {
      throw new BadRequestException('No file uploaded');
    }

    const photo = await this.photosService.uploadPhoto(file, {
      userId: req.user.userId,
      childId,
      activityId,
      type: (type as PhotoType) || PhotoType.GENERAL,
      caption,
      description,
      takenAt: takenAt ? new Date(takenAt) : undefined,
      metadata: metadata ? JSON.parse(metadata) : undefined,
    });

    return {
      success: true,
      data: { photo },
    };
  }

  @Get('child/:childId')
  async getChildPhotos(
    @Req() req: any,
    @Param('childId') childId: string,
    @Query('type') type?: PhotoType,
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    const result = await this.photosService.getChildPhotos(childId, {
      type,
      limit: limit ? parseInt(limit, 10) : undefined,
      offset: offset ? parseInt(offset, 10) : undefined,
    });

    return {
      success: true,
      data: result,
    };
  }

  @Get('child/:childId/gallery')
  async getGallery(
    @Req() req: any,
    @Param('childId') childId: string,
    @Query('type') type?: PhotoType,
    @Query('limit') limit?: string,
    @Query('offset') offset?: string,
  ) {
    const result = await this.photosService.getGallery(
      childId,
      req.user.userId,
      {
        type,
        limit: limit ? parseInt(limit, 10) : 50,
        offset: offset ? parseInt(offset, 10) : undefined,
      },
    );

    return {
      success: true,
      data: result,
    };
  }

  @Get('child/:childId/milestones')
  async getMilestones(@Req() req: any, @Param('childId') childId: string) {
    const photos = await this.photosService.getMilestonePhotos(childId);

    return {
      success: true,
      data: { photos },
    };
  }

  @Get('child/:childId/stats')
  async getPhotoStats(@Req() req: any, @Param('childId') childId: string) {
    const stats = await this.photosService.getPhotoStats(childId);

    return {
      success: true,
      data: stats,
    };
  }

  @Get('activity/:activityId')
  async getActivityPhotos(
    @Req() req: any,
    @Param('activityId') activityId: string,
  ) {
    const photos = await this.photosService.getActivityPhotos(activityId);

    return {
      success: true,
      data: { photos },
    };
  }

  @Get('recent')
  async getRecentPhotos(@Req() req: any, @Query('limit') limit?: string) {
    const photos = await this.photosService.getRecentPhotos(
      req.user.userId,
      limit ? parseInt(limit, 10) : 10,
    );

    return {
      success: true,
      data: { photos },
    };
  }

  @Get(':photoId')
  async getPhoto(@Req() req: any, @Param('photoId') photoId: string) {
    const photo = await this.photosService.getPhotoWithUrl(
      photoId,
      req.user.userId,
    );

    return {
      success: true,
      data: { photo },
    };
  }

  @Patch(':photoId')
  async updatePhoto(
    @Req() req: any,
    @Param('photoId') photoId: string,
    @Body()
    updates: {
      caption?: string;
      description?: string;
      type?: PhotoType;
      metadata?: Record<string, any>;
    },
  ) {
    const photo = await this.photosService.updatePhoto(
      photoId,
      req.user.userId,
      updates,
    );

    return {
      success: true,
      data: { photo },
    };
  }

  @Delete(':photoId')
  async deletePhoto(@Req() req: any, @Param('photoId') photoId: string) {
    await this.photosService.deletePhoto(photoId, req.user.userId);

    return {
      success: true,
      message: 'Photo deleted successfully',
    };
  }
}
