import {
  Controller,
  Get,
  Patch,
  Post,
  Delete,
  Param,
  Body,
  Res,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import type { Response } from 'express';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { ExpertProfileService } from './expert-profile.service';
import { ProfileExportService } from './profile-export.service';
import { UpdateSkillsDto } from './dto/update-skills.dto';
import { CreateExperienceDto } from './dto/create-experience.dto';
import { CreateLanguageDto } from './dto/create-language.dto';
import { CreateProjectDto } from './dto/create-project.dto';
import { UpdateProjectDto } from './dto/update-project.dto';
import { CreateCertificationDto } from './dto/create-certification.dto';
import { UpdateCertificationDto } from './dto/update-certification.dto';
import { UploadAttachmentDto } from './dto/upload-attachment.dto';

@ApiTags('Experten-Profil')
@ApiBearerAuth('access-token')
@Controller('expert-profile')
export class ExpertProfileController {
  constructor(
    private readonly expertProfileService: ExpertProfileService,
    private readonly profileExportService: ProfileExportService,
  ) {}

  // ============================================================
  // Profil
  // ============================================================
  @Get('me')
  @ApiOperation({ summary: 'Eigenes Experten-Profil abrufen' })
  async getProfile(@CurrentUser('sub') userId: string) {
    return this.expertProfileService.getOrCreateProfile(userId);
  }

  // ============================================================
  // Skills
  // ============================================================
  @Patch('me/skills')
  @ApiOperation({ summary: 'Skills aktualisieren' })
  async updateSkills(
    @CurrentUser('sub') userId: string,
    @Body() dto: UpdateSkillsDto,
  ) {
    return this.expertProfileService.updateSkills(userId, dto);
  }

  // ============================================================
  // Erfahrung
  // ============================================================
  @Post('me/experiences')
  @ApiOperation({ summary: 'Erfahrung hinzufügen' })
  async addExperience(
    @CurrentUser('sub') userId: string,
    @Body() dto: CreateExperienceDto,
  ) {
    return this.expertProfileService.addExperience(userId, dto);
  }

  @Delete('me/experiences/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Erfahrung löschen' })
  async deleteExperience(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    await this.expertProfileService.deleteExperience(userId, id);
  }

  // ============================================================
  // Sprachen
  // ============================================================
  @Post('me/languages')
  @ApiOperation({ summary: 'Sprache hinzufügen' })
  async addLanguage(
    @CurrentUser('sub') userId: string,
    @Body() dto: CreateLanguageDto,
  ) {
    return this.expertProfileService.addLanguage(userId, dto);
  }

  @Delete('me/languages/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Sprache löschen' })
  async deleteLanguage(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    await this.expertProfileService.deleteLanguage(userId, id);
  }

  // ============================================================
  // Projekte
  // ============================================================
  @Post('me/projects')
  @ApiOperation({ summary: 'Projekt hinzufügen' })
  async addProject(
    @CurrentUser('sub') userId: string,
    @Body() dto: CreateProjectDto,
  ) {
    return this.expertProfileService.addProject(userId, dto);
  }

  @Patch('me/projects/:id')
  @ApiOperation({ summary: 'Projekt bearbeiten' })
  async updateProject(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateProjectDto,
  ) {
    return this.expertProfileService.updateProject(userId, id, dto);
  }

  @Delete('me/projects/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Projekt löschen' })
  async deleteProject(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    await this.expertProfileService.deleteProject(userId, id);
  }

  // ============================================================
  // Zertifizierungen
  // ============================================================
  @Post('me/certifications')
  @ApiOperation({ summary: 'Zertifizierung hinzufügen' })
  async addCertification(
    @CurrentUser('sub') userId: string,
    @Body() dto: CreateCertificationDto,
  ) {
    return this.expertProfileService.addCertification(userId, dto);
  }

  @Patch('me/certifications/:id')
  @ApiOperation({ summary: 'Zertifizierung bearbeiten' })
  async updateCertification(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateCertificationDto,
  ) {
    return this.expertProfileService.updateCertification(userId, id, dto);
  }

  @Delete('me/certifications/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Zertifizierung löschen' })
  async deleteCertification(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    await this.expertProfileService.deleteCertification(userId, id);
  }

  // ============================================================
  // Export (PDF / DOCX)
  // ============================================================
  @Get('me/export/pdf')
  @ApiOperation({ summary: 'Profil als PDF exportieren' })
  async exportPdf(
    @CurrentUser('sub') userId: string,
    @Res() res: Response,
  ) {
    const { buffer, firstName, lastName } = await this.profileExportService.generatePdf(userId);
    const baseName = `${firstName}_${lastName}_CV`.replace(/\s+/g, '_');
    const encodedName = encodeURIComponent(`${baseName}.pdf`);
    res.set({
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${baseName}.pdf"; filename*=UTF-8''${encodedName}`,
      'Content-Length': String(buffer.length),
    });
    res.end(buffer);
  }

  @Get('me/export/docx')
  @ApiOperation({ summary: 'Profil als Word-Dokument exportieren' })
  async exportDocx(
    @CurrentUser('sub') userId: string,
    @Res() res: Response,
  ) {
    const { buffer, firstName, lastName } = await this.profileExportService.generateDocx(userId);
    const baseName = `${firstName}_${lastName}_CV`.replace(/\s+/g, '_');
    const encodedName = encodeURIComponent(`${baseName}.docx`);
    res.set({
      'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'Content-Disposition': `attachment; filename="${baseName}.docx"; filename*=UTF-8''${encodedName}`,
      'Content-Length': String(buffer.length),
    });
    res.end(buffer);
  }

  // ============================================================
  // Profilanlagen
  // ============================================================
  @Post('me/attachments')
  @ApiOperation({ summary: 'Datei hochladen' })
  async uploadAttachment(
    @CurrentUser('sub') userId: string,
    @Body() dto: UploadAttachmentDto,
  ) {
    return this.expertProfileService.uploadAttachment(userId, dto);
  }

  @Get('me/attachments/:id')
  @ApiOperation({ summary: 'Datei herunterladen' })
  async downloadAttachment(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.expertProfileService.downloadAttachment(userId, id);
  }

  @Delete('me/attachments/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Datei löschen' })
  async deleteAttachment(
    @CurrentUser('sub') userId: string,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    await this.expertProfileService.deleteAttachment(userId, id);
  }
}
