/**
 * 表单实例控制器
 * 完全符合 API 文档规范 - 12个端点
 */

import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  HttpCode,
  HttpStatus,
  Res,
} from '@nestjs/common';
import type { Response } from 'express';
// import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';  // TODO: Install @nestjs/swagger
import { PermissionsGuard } from '@modules/organization/auth/guards/permissions.guard';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { Auditable, Sensitive } from '@core/observability/audit/decorators/auditable.decorator';
import { FormInstanceService } from '../services';
import { FormApprovalIntegrationService } from '../services/form-approval-integration.service';
import {
  CreateFormInstanceDto,
  UpdateFormInstanceDto,
  SubmitFormInstanceDto,
  QueryMyFormInstancesDto,
  QueryAllFormInstancesDto,
  BatchUpdateStatusDto,
  ExportFormInstancesDto,
  GetFormInstanceStatsDto,
  CancelFormInstanceDto,
} from '../dto';

// @ApiTags('Form Instances - 表单实例')
@Controller('form-instances')
// @ApiBearerAuth()
export class FormInstancesController {
  constructor(
    private readonly formInstanceService: FormInstanceService,
    private readonly approvalIntegration: FormApprovalIntegrationService,
  ) {}

  // ============================================
  // 管理员接口 - 需要放在动态路由之前
  // ============================================

  // 3.9 获取所有表单实例 🔒 Admin Only
  @Get()
  @RequirePermissions('form:instance:read:all')
  // @ApiOperation({
  //   summary: '获取所有表单实例（管理员）',
  //   description: '🔐 Admin Only - 此接口仅管理员可访问',
  // })
  async findAll(@Query() query: QueryAllFormInstancesDto) {
    return this.formInstanceService.findAll(query);
  }

  // 3.11 导出表单实例数据 🔒 Admin Only
  @Get('export')
  @RequirePermissions('form:instance:export')
  // @ApiOperation({
  //   summary: '导出表单实例数据（管理员）',
  //   description: '🔐 Admin Only - 此接口仅管理员可访问',
  // })
  async exportInstances(
    @Query() dto: ExportFormInstancesDto,
    @Res() res: Response
  ) {
    const result = await this.formInstanceService.exportInstances(dto);

    const contentType =
      result.format === 'csv'
        ? 'text/csv; charset=utf-8'
        : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';

    res.setHeader('Content-Type', contentType);
    res.setHeader(
      'Content-Disposition',
      `attachment; filename="${encodeURIComponent(result.filename)}"`,
    );
    res.setHeader('X-Export-Row-Count', String(result.rowCount));
    res.end(result.buffer);
  }

  // 3.12 获取表单实例统计 🔒 Admin Only
  @Get('stats')
  @RequirePermissions('form:instance:read:all')
  // @ApiOperation({
  //   summary: '获取表单实例统计（管理员）',
  //   description: '🔐 Admin Only - 此接口仅管理员可访问',
  // })
  async getStats(@Query() dto: GetFormInstanceStatsDto) {
    return this.formInstanceService.getStats(dto);
  }

  // ============================================
  // 用户接口 - 我的实例
  // ============================================

  // 3.1 创建表单实例（草稿）
  @Post()
  @Auditable()
  @Sensitive()
  @RequirePermissions('form:instance:create')
  // @ApiOperation({ summary: '创建表单实例（草稿）' })
  async create(
    @Body() dto: CreateFormInstanceDto,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.create(dto, userId);
  }

  // 3.2 获取我的表单实例列表
  @Get('my')
  @RequirePermissions('form:instance:read')
  // @ApiOperation({ summary: '获取我的表单实例列表' })
  async findMy(
    @Query() query: QueryMyFormInstancesDto,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.findMy(query, userId);
  }

  // 3.3 获取单个实例详情
  @Get(':instanceIdentifier')
  @RequirePermissions('form:instance:read')
  // @ApiOperation({ summary: '获取单个实例详情' })
  async findOne(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.findOne(instanceIdentifier, userId);
  }

  // 3.4 更新表单实例（草稿）
  @Patch(':instanceIdentifier')
  @Auditable()
  @Sensitive()
  @RequirePermissions('form:instance:update')
  // @ApiOperation({ summary: '更新表单实例（草稿）' })
  async update(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @Body() dto: UpdateFormInstanceDto,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.update(instanceIdentifier, dto, userId);
  }

  // 3.5 提交表单实例
  @Post(':instanceIdentifier/submit')
  @Auditable()
  @Sensitive()
  @HttpCode(HttpStatus.OK)
  @RequirePermissions('form:instance:create')
  // @ApiOperation({ summary: '提交表单实例' })
  async submit(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @Body() dto: SubmitFormInstanceDto,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.submit(instanceIdentifier, dto, userId);
  }

  // 3.6 删除表单实例（软删除）
  @Delete(':instanceIdentifier')
  @Auditable()
  @Sensitive()
  @RequirePermissions('form:instance:delete')
  // @ApiOperation({ summary: '删除表单实例' })
  async remove(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.remove(instanceIdentifier, userId);
  }

  // 3.7 取消表单实例
  @Post(':instanceIdentifier/cancel')
  @Auditable()
  @Sensitive()
  @HttpCode(HttpStatus.OK)
  @RequirePermissions('form:instance:create')
  // @ApiOperation({ summary: '取消表单实例' })
  async cancel(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @Body() dto: CancelFormInstanceDto,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.cancel(instanceIdentifier, dto, userId);
  }

  // 3.8 恢复已删除的实例 🆕
  @Post(':instanceIdentifier/restore')
  @Auditable()
  @Sensitive()
  @HttpCode(HttpStatus.OK)
  @RequirePermissions('form:instance:delete:all')
  // @ApiOperation({
  //   summary: '恢复已删除的实例',
  //   description: '🔐 Admin Only - 恢复软删除的实例',
  // })
  async restore(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @CurrentUser('userId') userId: string
  ) {
    return this.formInstanceService.restore(instanceIdentifier, userId);
  }

  // ============================================
  // 管理员接口 - 批量操作
  // ============================================

  // 3.10 批量更新实例状态 🔒 Admin Only
  @Post('batch-update-status')
  @Auditable()
  @Sensitive()
  @HttpCode(HttpStatus.OK)
  @RequirePermissions('form:instance:update:all')
  // @ApiOperation({
  //   summary: '批量更新实例状态（管理员）',
  //   description: '🔐 Admin Only - 此接口仅管理员可访问',
  // })
  async batchUpdateStatus(@Body() dto: BatchUpdateStatusDto) {
    return this.formInstanceService.batchUpdateStatus(dto);
  }

  // 3.13 批量删除实例（软删除）🔒 Admin Only
  @Delete('_batch/delete')
  @Auditable()
  @Sensitive()
  @RequirePermissions('form:instance:delete:all')
  // @ApiOperation({
  //   summary: '批量删除实例（管理员）',
  //   description: '🔐 Admin Only - 此接口仅管理员可访问',
  // })
  async batchDelete(
    @Body('ids') ids: string[],
    @CurrentUser('userId') userId: string
  ) {
    const results = {
      deleted: 0,
      failed: 0,
      errors: [] as Array<{ id: string; error: string }>,
    };

    for (const id of ids) {
      try {
        await this.formInstanceService.remove(id, userId);
        results.deleted++;
      } catch (error) {
        results.failed++;
        results.errors.push({ id, error: error.message });
      }
    }

    return results;
  }

  // ============================================
  // 审批流集成接口
  // ============================================

  /**
   * 3.13 查询表单实例的审批状态
   */
  @Get(':instanceIdentifier/approval-status')
  @RequirePermissions('form:instance:read')
  // @ApiOperation({ summary: '查询表单实例的审批状态' })
  async getApprovalStatus(
    @Param('instanceIdentifier') instanceIdentifier: string,
  ) {
    return this.approvalIntegration.getApprovalStatus(instanceIdentifier);
  }

  /**
   * 3.14 撤回表单实例（撤回审批）
   */
  @Post(':instanceIdentifier/withdraw')
  @Auditable()
  @Sensitive()
  @HttpCode(HttpStatus.OK)
  @RequirePermissions('form:instance:update')
  // @ApiOperation({ summary: '撤回表单实例（撤回审批）' })
  async withdrawForm(
    @Param('instanceIdentifier') instanceIdentifier: string,
    @CurrentUser('userId') userId: string,
  ) {
    const updated = await this.approvalIntegration.withdrawFormWithApproval(
      instanceIdentifier,
      userId,
    );
    return {
      instanceId: updated.id,
      status: updated.status,
      withdrawn: true,
    };
  }
}

