/**
 * 表单管理控制器
 * 
 * 表单定义管理和设计器 API
 */

import {
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiHeader,
  ApiParam,
} from '@nestjs/swagger';
import { FormManagementService } from '../services/form-management.service';
import { StatisticsService } from '../services/statistics.service';
import { RegionGuard } from '../guards/region.guard';
import { Region, RegionRequired } from '../decorators/region.decorator';
import type { RegionId } from '../decorators/region.decorator';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { PermissionsGuard } from '@modules/organization/auth/guards/permissions.guard';
import {
  CreateFormDefinitionDto,
  UpdateFormDefinitionDto,
} from '../dto/form-definition.dto';
import {
  SaveDesignDto,
  SaveFormDesignDto,
  SaveProcessDesignDto,
} from '../dto/form-design.dto';
import { QueryFormDefinitionsDto } from '../dto/query.dto';
import { StatisticsQueryDto, StatisticsResponseDto } from '../dto/statistics.dto';
import { 
  PreviewProcessDto, 
  PreviewProcessResponse 
} from '../dto/instance.dto';
import { Auditable, Sensitive, Financial } from '@core/observability/audit/decorators/auditable.decorator';

@ApiTags('表单管理')
@ApiBearerAuth()
@ApiHeader({
  name: 'X-Region-Id',
  description: '区域标识（CN / US / ME）',
  required: true,
})
@Controller('form-management')
@UseGuards(RegionGuard, PermissionsGuard)
@RegionRequired(true)
export class FormManagementController {
  private readonly logger = new Logger(FormManagementController.name);

  constructor(
    private readonly formManagementService: FormManagementService,
    private readonly statisticsService: StatisticsService,
  ) {}

  // ============================================
  // 表单定义管理
  // ============================================

  @Get('definitions')
  @ApiOperation({ summary: '获取表单定义列表' })
  @ApiResponse({ status: 200, description: '成功获取列表' })
  @RequirePermissions('form:read')
  async findAll(
    @Query() query: QueryFormDefinitionsDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
    @CurrentUser('permissions') permissions: string[],
  ) {
    this.logger.log(`GET /definitions - region: ${regionId}, user: ${userId}, isAdmin: ${permissions.includes('form:admin')}`);
    return this.formManagementService.findAll(query, regionId, userId, permissions);
  }

  @Post('definitions')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '创建表单定义' })
  @ApiResponse({ status: 201, description: '创建成功' })
  @RequirePermissions('form:design')
  async create(
    @Body() dto: CreateFormDefinitionDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`POST /definitions - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.create(dto, regionId, userId);
  }

  @Get('definitions/:id')
  @ApiOperation({ summary: '获取表单详情' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '成功获取详情' })
  @ApiResponse({ status: 404, description: '表单不存在' })
  @RequirePermissions('form:read')
  async findOne(
    @Param('id') id: string,
    @Region() regionId: RegionId,
  ) {
    this.logger.log(`GET /definitions/${id} - region: ${regionId}`);
    return this.formManagementService.findOne(id, regionId);
  }

  @Patch('definitions/:id')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '更新表单定义' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '更新成功' })
  @RequirePermissions('form:design')
  async update(
    @Param('id') id: string,
    @Body() dto: UpdateFormDefinitionDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`PATCH /definitions/${id} - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.update(id, dto, regionId, userId);
  }

  @Delete('definitions/:id')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '删除表单定义' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '删除成功' })
  @RequirePermissions('form:admin')
  async remove(
    @Param('id') id: string,
    @Region() regionId: RegionId,
  ) {
    this.logger.log(`DELETE /definitions/${id} - region: ${regionId}`);
    return this.formManagementService.remove(id, regionId);
  }

  // ============================================
  // 设计器
  // ============================================

  @Get('definitions/:id/design')
  @ApiOperation({ summary: '获取设计数据（用于设计器或表单提交）' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '成功获取设计数据' })
  // 允许有表单相关权限的用户访问：设计、使用或查看
  // 使用 OR 逻辑：只要有其中一个权限即可
  @RequirePermissions('form:read')  // 最基础的权限，Employee 和 Department Manager 都有
  async getDesignData(
    @Param('id') id: string,
    @Region() regionId: RegionId,
  ) {
    this.logger.log(`GET /definitions/${id}/design - region: ${regionId}`);
    return this.formManagementService.getDesignData(id, regionId);
  }

  @Put('definitions/:id/design')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '保存全部设计（表单 + 流程）' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '保存成功' })
  @RequirePermissions('form:design')
  async saveDesign(
    @Param('id') id: string,
    @Body() dto: SaveDesignDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`PUT /definitions/${id}/design - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.saveDesign(id, dto, regionId, userId);
  }

  @Put('definitions/:id/form-design')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '保存表单设计' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '保存成功' })
  @RequirePermissions('form:design')
  async saveFormDesign(
    @Param('id') id: string,
    @Body() dto: SaveFormDesignDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`PUT /definitions/${id}/form-design - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.saveFormDesign(id, dto, regionId, userId);
  }

  @Put('definitions/:id/process-design')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '保存流程设计' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '保存成功' })
  @RequirePermissions('form:design')
  async saveProcessDesign(
    @Param('id') id: string,
    @Body() dto: SaveProcessDesignDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`PUT /definitions/${id}/process-design - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.saveProcessDesign(id, dto, regionId, userId);
  }

  @Post('definitions/:id/preview-process')
  @ApiOperation({ summary: '预览审批流程（含实际审批人）' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ 
    status: 200, 
    description: '预览成功',
    type: PreviewProcessResponse,
  })
  @ApiResponse({ status: 404, description: '表单或流程不存在' })
  @RequirePermissions('form:read')
  async previewProcess(
    @Param('id') id: string,
    @Body() dto: PreviewProcessDto,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`POST /definitions/${id}/preview-process - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.previewProcessWithApprovers(id, dto, userId);
  }

  // ============================================
  // 表单定义状态管理
  // ============================================

  @Post('definitions/:id/archive')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '归档表单定义' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '归档成功' })
  @ApiResponse({ status: 403, description: '表单已归档或有运行中的实例' })
  @RequirePermissions('form:publish')
  async archive(
    @Param('id') id: string,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`POST /definitions/${id}/archive - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.archive(id, regionId, userId);
  }

  @Post('definitions/:id/disable')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '禁用表单定义' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '禁用成功' })
  @RequirePermissions('form:publish')
  async disable(
    @Param('id') id: string,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`POST /definitions/${id}/disable - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.disable(id, regionId, userId);
  }

  @Post('definitions/:id/enable')
  @Auditable()
  @Sensitive()
  @ApiOperation({ summary: '启用表单定义' })
  @ApiParam({ name: 'id', description: '表单定义 ID' })
  @ApiResponse({ status: 200, description: '启用成功' })
  @RequirePermissions('form:publish')
  async enable(
    @Param('id') id: string,
    @Region() regionId: RegionId,
    @CurrentUser('userId') userId: string,
  ) {
    this.logger.log(`POST /definitions/${id}/enable - region: ${regionId}, user: ${userId}`);
    return this.formManagementService.enable(id, regionId, userId);
  }

  // ============================================
  // 统计分析
  // ============================================

  @Get('statistics')
  @ApiOperation({ 
    summary: '获取表单统计数据',
    description: '获取表单使用统计、热门表单排行、提交趋势等分析数据'
  })
  @ApiResponse({ 
    status: 200, 
    description: '成功获取统计数据',
    type: StatisticsResponseDto
  })
  @RequirePermissions('form:read')
  async getStatistics(
    @Query() query: StatisticsQueryDto,
    @Region() regionId: RegionId,
  ) {
    this.logger.log(`GET /statistics - region: ${regionId}, timeRange: ${query.timeRange}`);
    return this.statisticsService.getStatistics(query, regionId);
  }
}
