import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  ParseUUIDPipe,
  HttpCode,
} from '@nestjs/common';
import { KpiService } from '../services/kpi.service';
import {
  CreateAssignmentDto,
  UpdateAssignmentDto,
  BatchAssignDto,
  QueryAssignmentDto,
  SelfEvaluateDto,
  ManagerEvaluateDto,
  SubmitAllKpiDto,
  RejectAssignmentDto,
  RejectDependencyDto,
} from '../dto/kpi.dto';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { PERFORMANCE_PERMISSIONS } from '../constants/permissions';
import { toPaginatedResponse } from '@common/utils/pagination';

/**
 * KPI 考核管理控制器
 * 路由前缀: /api/v1/performance/kpi
 */
@Controller('performance/kpi')
export class KpiController {
  constructor(private readonly kpiService: KpiService) {}

  // ==================== KPI 分配 ====================

  @Get('assignments')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_VIEW)
  async findAssignments(@Query() query: QueryAssignmentDto) {
    const result = await this.kpiService.findAssignments(query);
    return toPaginatedResponse(result);
  }

  @Get('assignments/my')
  async getMyAssignments(
    @CurrentUser('userId') userId: string,
    @Query('cycleId') cycleId?: string,
  ) {
    const result = await this.kpiService.getMyAssessments(userId, { cycleId });
    return toPaginatedResponse(result);
  }

  @Get('assignments/team')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_VIEW_TEAM)
  async getTeamAssignments(
    @CurrentUser('userId') managerId: string,
    @Query('cycleId') cycleId?: string,
    @Query('organizationId') organizationId?: string,
  ) {
    return this.kpiService.getTeamAssessments(managerId, {
      cycleId,
      organizationId,
    });
  }

  @Post('assignments/submit-all')
  @HttpCode(200)
  async submitAllKpi(
    @Body() dto: SubmitAllKpiDto,
    @CurrentUser('userId') userId: string,
  ) {
    return this.kpiService.submitAllKpi(dto.cycleId, userId);
  }

  @Get('dependencies/pending')
  async getPendingDependencyConfirmations(
    @CurrentUser('userId') userId: string,
  ) {
    const items = await this.kpiService.getPendingDependencyConfirmations(userId);
    return { items };
  }

  @Get('assignments/:id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_VIEW)
  async findAssignmentById(@Param('id', ParseUUIDPipe) id: string) {
    return this.kpiService.findAssignmentById(id);
  }

  @Post('assignments')
  async assignKpi(
    @Body() dto: CreateAssignmentDto,
    @CurrentUser('userId') userId: string,
  ) {
    // 员工只能给自己创建 KPI，强制使用当前用户 ID
    dto.employeeId = userId;
    // 兼容前端扁平字段：将 dependentUserId/dependencyDescription 转为 dependencies 数组
    if (dto.dependentUserId && !dto.dependencies?.length) {
      dto.dependencies = [{ targetUserId: dto.dependentUserId, description: dto.dependencyDescription }];
    }
    return this.kpiService.assignKpi(dto as CreateAssignmentDto & { employeeId: string });
  }

  @Post('assignments/batch')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_ASSIGN)
  async batchAssignKpi(@Body() dto: BatchAssignDto) {
    return this.kpiService.batchAssignKpi(
      dto.cycleId,
      dto.employeeIds,
      dto.assignments,
    );
  }

  @Put('assignments/:id')
  async updateAssignment(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateAssignmentDto,
    @CurrentUser('userId') userId: string,
  ) {
    // 员工可编辑自己的 DRAFT/SUBMITTED KPI，无需 KPI_ASSIGN 权限
    const assignment = await this.kpiService.updateAssignment(id, dto, userId);
    return assignment;
  }

  @Delete('assignments/:id')
  async deleteAssignment(
    @Param('id', ParseUUIDPipe) id: string,
    @CurrentUser('userId') userId: string,
  ) {
    await this.kpiService.deleteAssignment(id, userId);
    return { id };
  }

  // ==================== KPI 审批与依赖 ====================

  @Post('assignments/:id/approve')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_MANAGER_EVALUATE)
  @HttpCode(200)
  async approveAssignment(@Param('id', ParseUUIDPipe) id: string) {
    return this.kpiService.approveAssignment(id);
  }

  @Post('assignments/:id/reject')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_MANAGER_EVALUATE)
  @HttpCode(200)
  async rejectAssignment(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: RejectAssignmentDto,
  ) {
    return this.kpiService.rejectAssignment(id, dto.reason);
  }

  @Post('dependencies/:id/confirm')
  @HttpCode(200)
  async confirmDependency(
    @Param('id', ParseUUIDPipe) id: string,
    @CurrentUser('userId') userId: string,
  ) {
    return this.kpiService.confirmDependency(id, userId);
  }

  @Post('dependencies/:id/reject')
  @HttpCode(200)
  async rejectDependency(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: RejectDependencyDto,
    @CurrentUser('userId') userId: string,
  ) {
    return this.kpiService.rejectDependency(id, userId, dto.reason);
  }

  // ==================== 考核评分 ====================

  @Get('assessments/:id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_VIEW)
  async findAssessmentById(@Param('id', ParseUUIDPipe) id: string) {
    const { assignment, adjustmentLogs, ...rest } = await this.kpiService.findAssessmentById(id) as
      Record<string, unknown>;
    return rest;
  }

  @Post('assessments/:id/self-evaluate')
  @HttpCode(200)
  async selfEvaluate(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: SelfEvaluateDto,
    @CurrentUser('userId') userId: string,
  ) {
    const assessment = await this.kpiService.selfEvaluate(id, userId, dto);
    return assessment;
  }

  @Post('assessments/:id/manager-evaluate')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_MANAGER_EVALUATE)
  @HttpCode(200)
  async managerEvaluate(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: ManagerEvaluateDto,
    @CurrentUser('userId') managerId: string,
  ) {
    const assessment = await this.kpiService.managerEvaluate(id, managerId, dto);
    return assessment;
  }

  @Post('assessments/:id/confirm')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_CONFIRM)
  @HttpCode(200)
  async confirmAssessment(@Param('id', ParseUUIDPipe) id: string) {
    const assessment = await this.kpiService.confirmAssessment(id);
    return assessment;
  }

  @Get('weight-validation')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.KPI_VIEW)
  async validateWeightSum(
    @Query('cycleId', ParseUUIDPipe) cycleId: string,
    @Query('employeeId', ParseUUIDPipe) employeeId: string,
  ) {
    return this.kpiService.validateWeightSum(cycleId, employeeId);
  }
}
