import {
  BadRequestException, Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Put, Req, Res, UploadedFile, UseGuards, UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import type { Response } from 'express';
import * as multer from 'multer';
import { JwtAuthGuard } from './../auth/guards/jwt-auth.guard';
import { ChecklistTemplatesAccessService } from './services/checklist-templates-access.service';

@Controller()
@UseGuards(JwtAuthGuard)
export class ChecklistTemplatesAccessController {
  constructor(private readonly access: ChecklistTemplatesAccessService) {}

  // ── library ────────────────────────────────────────────────────
  @Get('checklist-templates/mine')
  mine(@Req() req: any) {
    return this.access.listVisible(req.user.id);
  }

  @Patch('checklist-templates/:id/name')
  rename(@Param('id', ParseIntPipe) id: number, @Body() body: { name: string }, @Req() req: any) {
    return this.access.rename(req.user.id, id, body?.name);
  }
    @Patch('checklist-templates/:id/shareable')
  setShareable(@Param('id', ParseIntPipe) id: number, @Body() body: { is_shareable: boolean }, @Req() req: any) {
    return this.access.setShareable(req.user.id, id, !!body?.is_shareable);
  }

  @Patch('checklist-templates/:id/standards')
  setStandards(@Param('id', ParseIntPipe) id: number, @Body() body: { standard_ids: number[] }, @Req() req: any) {
    return this.access.setStandards(req.user.id, id, body?.standard_ids ?? []);
  }

  @Delete('checklist-templates/:id/remove')
  remove(@Param('id', ParseIntPipe) id: number, @Req() req: any) {
    return this.access.remove(req.user.id, id);
  }

  @Post('checklist-templates/:id/items')
  addItem(@Param('id', ParseIntPipe) id: number, @Body() body: { item_text: string; category?: string }, @Req() req: any) {
    return this.access.addItem(req.user.id, id, body?.item_text, body?.category);
  }

  @Patch('checklist-template-items/:itemId')
  updateItem(@Param('itemId', ParseIntPipe) itemId: number, @Body() body: any, @Req() req: any) {
    return this.access.updateItem(req.user.id, itemId, body ?? {});
  }

  @Delete('checklist-template-items/:itemId')
  deleteItem(@Param('itemId', ParseIntPipe) itemId: number, @Req() req: any) {
    return this.access.deleteItem(req.user.id, itemId);
  }

  @Put('checklist-templates/:id/shares')
  setShares(@Param('id', ParseIntPipe) id: number, @Body() body: { user_ids: number[] }, @Req() req: any) {
    return this.access.setShares(req.user.id, id, body?.user_ids ?? []);
  }

  @Post('checklist-templates/:id/files')
  @UseInterceptors(FileInterceptor('file', { storage: multer.memoryStorage(), limits: { fileSize: 30 * 1024 * 1024 } }))
  uploadFile(@Param('id', ParseIntPipe) id: number, @UploadedFile() file: any, @Req() req: any) {
    if (!file) throw new BadRequestException('Choose a file to upload.');
    return this.access.uploadFile(req.user.id, id, file);
  }

  @Get('checklist-template-files/:fileId/download')
  async download(@Param('fileId', ParseIntPipe) fileId: number, @Req() req: any, @Res() res: Response) {
    const f = await this.access.openFile(req.user.id, fileId);
    res.setHeader('Content-Type', f.mimeType || 'application/octet-stream');
    res.setHeader('Content-Length', String(f.size));
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(f.filename)}`);
    f.stream.pipe(res);
  }

  @Delete('checklist-template-files/:fileId')
  deleteFile(@Param('fileId', ParseIntPipe) fileId: number, @Req() req: any) {
    return this.access.deleteFile(req.user.id, fileId);
  }

  // ── building ───────────────────────────────────────────────────
  @Get('audits/:rowId/checklist/picker-templates')
  picker(@Param('rowId', ParseIntPipe) rowId: number, @Req() req: any) {
    return this.access.availableForAudit(rowId, req.user.id);
  }

  @Get('audits/:rowId/checklists/visible')
  visible(@Param('rowId', ParseIntPipe) rowId: number, @Req() req: any) {
    return this.access.visibleChecklists(rowId, req.user.id);
  }

  @Post('audits/:rowId/checklist/build-as-me')
  buildAsMe(@Param('rowId', ParseIntPipe) rowId: number, @Body() body: { standard_id: number; template_item_ids: number[] }, @Req() req: any) {
    return this.access.buildForUser(rowId, req.user.id, body);
  }

  // ── review step ────────────────────────────────────────────────
  @Post('checklists/:checklistId/draft-items')
  addDraftItems(@Param('checklistId', ParseIntPipe) checklistId: number, @Body() body: { template_item_ids: number[] }, @Req() req: any) {
    return this.access.addDraftItems(req.user.id, checklistId, body?.template_item_ids ?? []);
  }

  @Delete('checklists/:checklistId/draft-items/:templateItemId')
  removeDraftItem(
    @Param('checklistId', ParseIntPipe) checklistId: number,
    @Param('templateItemId', ParseIntPipe) templateItemId: number,
    @Req() req: any,
  ) {
    return this.access.removeDraftItem(req.user.id, checklistId, templateItemId);
  }
}