import { Controller, Get, Param, Res, NotFoundException, Logger } from '@nestjs/common';
import { Response } from 'express';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { GoogleDriveService } from './google-drive.service';
import { App } from '../../entities/app.entity';
import { User } from '../../entities/user.entity';

@Controller('api/drive')
export class DriveController {
  private readonly logger = new Logger(DriveController.name);

  constructor(
    private driveService: GoogleDriveService,
    @InjectRepository(App)
    private appRepo: Repository<App>,
    @InjectRepository(User)
    private userRepo: Repository<User>,
  ) { }

  /**
   * Serve app icon by app ID (primary) or legacy Drive file ID (fallback).
   * Icons are stored as base64 in the DB for reliability; Drive is only used
   * as a fallback for apps that were uploaded before the DB-storage migration.
   */
  @Get('icon/:identifier')
  async getIcon(@Param('identifier') identifier: string, @Res() res: Response) {
    try {
      // Try by app ID first, then fall back to iconFileId for backward compatibility
      let app = await this.appRepo.findOne({
        where: { id: identifier },
        relations: ['user'],
      });
      if (!app) {
        app = await this.appRepo.findOne({
          where: { iconFileId: identifier },
          relations: ['user'],
        });
      }
      if (!app) {
        this.logger.warn(`No app found for icon identifier: ${identifier}`);
        throw new NotFoundException('Icon not found');
      }

      // Serve from DB if icon data is available
      if (app.iconData) {
        const buffer = Buffer.from(app.iconData, 'base64');
        res.setHeader('Content-Type', 'image/png');
        res.setHeader('Cache-Control', 'public, max-age=86400');
        res.send(buffer);
        return;
      }

      // Fallback: fetch from Google Drive (for legacy apps without DB icon data)
      if (app.iconFileId && app.user) {
        const buffer = await this.driveService.getIconBuffer(app.user, app.iconFileId);
        res.setHeader('Content-Type', 'image/png');
        res.setHeader('Cache-Control', 'public, max-age=86400');
        res.send(buffer);

        // Backfill DB so future requests don't need Drive
        try {
          app.iconData = buffer.toString('base64');
          await this.appRepo.save(app);
        } catch (err: any) {
          this.logger.warn(`Failed to backfill icon data for app ${app.id}: ${err.message}`);
        }
        return;
      }

      throw new NotFoundException('Icon not found');
    } catch (error: any) {
      if (error instanceof NotFoundException) throw error;
      this.logger.error(`Failed to serve icon ${identifier}: ${error.message}`);
      throw new NotFoundException('Icon not found');
    }
  }
}
