import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  ParseUUIDPipe,
  HttpCode,
} from '@nestjs/common';
import { CycleService } from '../services/cycle.service';
import { ResultService } from '../services/result.service';
import {
  CreateCycleDto,
  UpdateCycleDto,
  QueryCycleDto,
} from '../dto/cycle.dto';
import { PublishResultsDto } from '../dto/result.dto';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { PERFORMANCE_PERMISSIONS } from '../constants/permissions';
import { BusinessException } from '@common/exceptions/business.exception';
import { PERFORMANCE_ERROR_CODES } from '../constants/error-codes';
import { toPaginatedResponse } from '@common/utils/pagination';

/**
 * 周期管理控制器
 * 路由前缀: /api/v1/performance/cycles
 */
@Controller('performance/cycles')
export class CycleController {
  constructor(
    private readonly cycleService: CycleService,
    private readonly resultService: ResultService,
  ) {}

  /**
   * 获取周期列表
   */
  @Get()
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async findAll(@Query() query: QueryCycleDto) {
    const result = await this.cycleService.findAll(query);
    return toPaginatedResponse(result);
  }

  /**
   * 获取周期选择列表（用于下拉）
   */
  @Get('select')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async findForSelect(@Query('organizationId') organizationId?: string) {
    const cycles = await this.cycleService.findForSelect(false, organizationId);
    return cycles.map((cycle) => ({ id: cycle.id, name: cycle.name }));
  }

  /**
   * 获取当前活跃周期
   */
  @Get('active')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async findActiveCycle(@Query('organizationId') organizationId?: string) {
    return this.cycleService.findActiveCycle(organizationId);
  }

  /**
   * 获取周期统计数据
   */
  @Get(':id/statistics')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async getStatistics(@Param('id', ParseUUIDPipe) id: string) {
    const stats = await this.cycleService.getStatistics(id);
    return {
      totalEmployees: stats.kpi.total,
      kpiStats: {
        total: stats.kpi.total,
        selfEvaluated: stats.kpi.selfEvaluated,
        managerEvaluated: stats.kpi.managerEvaluated,
        confirmed: stats.kpi.confirmed,
      },
      evaluation360Stats: {
        total: stats.e360.total,
        completed: stats.e360.completed,
        pending: stats.e360.total - stats.e360.completed,
      },
    };
  }

  /**
   * 获取目标设定进度
   */
  @Get(':id/goal-setting-progress')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async getGoalSettingProgress(@Param('id', ParseUUIDPipe) id: string) {
    return this.cycleService.getGoalSettingProgress(id);
  }

  /**
   * 获取评估进度
   */
  @Get(':id/evaluation-progress')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async getEvaluationProgress(@Param('id', ParseUUIDPipe) id: string) {
    return this.cycleService.getEvaluationProgress(id);
  }

  /**
   * 获取校准进度
   */
  @Get(':id/calibration-progress')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async getCalibrationProgress(@Param('id', ParseUUIDPipe) id: string) {
    return this.cycleService.getCalibrationProgress(id);
  }

  /**
   * 获取周期结果汇总
   */
  @Get(':id/cycle-results-summary')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async getCycleResultsSummary(@Param('id', ParseUUIDPipe) id: string) {
    return this.cycleService.getCycleResultsSummary(id);
  }

  /**
   * 获取周期详情
   */
  @Get(':id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_VIEW)
  async findById(@Param('id', ParseUUIDPipe) id: string) {
    return this.cycleService.findById(id);
  }

  /**
   * 创建周期
   */
  @Post()
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_CREATE)
  async create(
    @Body() dto: CreateCycleDto,
    @CurrentUser('userId') userId: string,
  ) {
    const cycle = await this.cycleService.create({
      name: dto.name,
      type: dto.type,
      startDate: new Date(dto.startDate),
      endDate: new Date(dto.endDate),
      gradeConfigId: dto.gradeConfigId,
      parentCycleId: dto.parentCycleId,
      organizationId: dto.organizationId,
      createdBy: userId,
    });
    return this.cycleService.findById(cycle.id);
  }

  /**
   * 更新周期
   */
  @Put(':id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  async update(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateCycleDto,
  ) {
    await this.cycleService.update(id, {
      name: dto.name,
      startDate: dto.startDate ? new Date(dto.startDate) : undefined,
      endDate: dto.endDate ? new Date(dto.endDate) : undefined,
      gradeConfigId: dto.gradeConfigId,
    });
    return this.cycleService.findById(id);
  }

  /**
   * 删除周期
   */
  @Delete(':id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_DELETE)
  async delete(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.delete(id);
    return { id };
  }

  /**
   * 发布周期 DRAFT → GOAL_SETTING
   */
  @Post(':id/publish')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_PUBLISH)
  @HttpCode(200)
  async publish(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.publish(id);
    return this.cycleService.findById(id);
  }

  /**
   * 开始执行 GOAL_SETTING → IN_PROGRESS
   */
  @Post(':id/start-execution')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async startExecution(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.startExecution(id);
    return this.cycleService.findById(id);
  }

  /**
   * 开始评估 IN_PROGRESS → EVALUATING
   */
  @Post(':id/start-evaluation')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async startEvaluation(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.startEvaluation(id);
    return this.cycleService.findById(id);
  }

  /**
   * 开始校准 EVALUATING → CALIBRATING
   */
  @Post(':id/start-calibration')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async startCalibration(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.startCalibration(id);
    return this.cycleService.findById(id);
  }

  /**
   * 开始确认 CALIBRATING → CONFIRMING
   */
  @Post(':id/start-confirming')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async startConfirming(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.startConfirming(id);
    return this.cycleService.findById(id);
  }

  /**
   * 完成周期 CONFIRMING → COMPLETED
   */
  @Post(':id/complete')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async complete(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.complete(id);
    return this.cycleService.findById(id);
  }

  /**
   * 发布绩效结果给员工
   */
  @Post(':id/publish-results')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.RESULT_PUBLISH)
  @HttpCode(200)
  async publishResults(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: PublishResultsDto,
    @CurrentUser('userId') publishedBy: string,
  ) {
    const result = await this.resultService.publishResults(id, publishedBy, {
      employeeIds: dto.employeeIds,
      notifyEmployees: dto.notifyEmployees,
    });
    return {
      cycleId: id,
      published: result.published,
      alreadyPublished: result.alreadyPublished,
      notified: result.notified,
    };
  }

  /**
   * 归档周期 COMPLETED → ARCHIVED
   */
  @Post(':id/archive')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.CYCLE_UPDATE)
  @HttpCode(200)
  async archive(@Param('id', ParseUUIDPipe) id: string) {
    await this.cycleService.archive(id);
    return this.cycleService.findById(id);
  }
}
