import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  ParseUUIDPipe,
  BadRequestException,
  ForbiddenException,
  HttpCode,
} from '@nestjs/common';
import { Evaluation360Service } from '../services/evaluation360.service';
import {
  CreateEvaluation360Dto,
  UpdateEvaluation360Dto,
  QueryEvaluation360Dto,
  AddEvaluatorDto,
  AddEvaluatorsDto,
  QueryTaskDto,
  SubmitFeedbackDto,
} from '../dto/evaluation360.dto';
import { RelationType } from '@prisma/client';
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';

/**
 * 360 评估控制器
 * 路由前缀: /api/v1/performance/360
 */
@Controller('performance/360')
export class Evaluation360Controller {
  constructor(private readonly evaluation360Service: Evaluation360Service) {}

  // ==================== 评估管理 ====================

  // v4.0: summary/by-employee 需要在 :id 路由之前定义
  // 允许：本人 / Administrator 角色 / 有 E360_VIEW_RESULTS 权限
  @Get('evaluations/summary')
  async getEmployee360Summary(
    @Query('cycleId', ParseUUIDPipe) cycleId: string,
    @Query('employeeId', ParseUUIDPipe) employeeId: string,
    @CurrentUser('userId') userId: string,
    @CurrentUser('roles') roles: string[],
    @CurrentUser('permissions') permissions: string[],
  ) {
    if (!this.canView360(employeeId, userId, roles, permissions)) {
      throw new ForbiddenException('无权查看他人的 360 评估汇总');
    }
    return this.evaluation360Service.getEmployee360Summary(cycleId, employeeId);
  }

  @Get('evaluations/by-employee')
  async getEmployee360Evaluation(
    @Query('cycleId', ParseUUIDPipe) cycleId: string,
    @Query('employeeId', ParseUUIDPipe) employeeId: string,
    @CurrentUser('userId') userId: string,
    @CurrentUser('roles') roles: string[],
    @CurrentUser('permissions') permissions: string[],
  ) {
    if (!this.canView360(employeeId, userId, roles, permissions)) {
      throw new ForbiddenException('无权查看他人的 360 评估');
    }
    return this.evaluation360Service.getEmployee360Evaluation(cycleId, employeeId);
  }

  /** 本人 / Admin 角色 / 有 view:results 权限 → 允许查看 */
  private canView360(employeeId: string, userId: string, roles: string[], permissions: string[]): boolean {
    return this.evaluation360Service.canView360(employeeId, userId, roles, permissions);
  }

  @Get('evaluations')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_VIEW)
  async findAll(@Query() query: QueryEvaluation360Dto) {
    const result = await this.evaluation360Service.findAll(query);
    return toPaginatedResponse(result);
  }

  @Get('evaluations/:id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_VIEW)
  async findById(@Param('id', ParseUUIDPipe) id: string) {
    return this.evaluation360Service.findById(id);
  }

  @Post('evaluations')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_CREATE)
  async create(
    @Body() dto: CreateEvaluation360Dto,
    @CurrentUser('userId') userId: string,
  ) {
    // 前端发送 evaluateeId，后端内部使用 targetId
    const targetId = dto.targetId || dto.evaluateeId;
    if (!targetId) {
      throw new BadRequestException('targetId 或 evaluateeId 必须提供');
    }

    // deadline 默认用周期结束日期
    let deadline: Date;
    if (dto.deadline) {
      deadline = new Date(dto.deadline);
    } else {
      const cycleEndDate = await this.evaluation360Service.getCycleEndDate(dto.cycleId);
      deadline = cycleEndDate || new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
    }

    const evaluation = await this.evaluation360Service.create({
      cycleId: dto.cycleId,
      targetId,
      deadline,
      templateId: dto.templateId,
      minEvaluators: dto.minEvaluators,
      createdBy: userId,
      evaluators: dto.evaluators?.map(e => ({
        evaluatorId: e.evaluatorId,
        relationType: (e.relationType || e.relationship) as RelationType,
        isAnonymous: e.isAnonymous,
      })),
    });
    return evaluation;
  }

  @Patch('evaluations/:id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_UPDATE)
  async update(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateEvaluation360Dto,
  ) {
    await this.evaluation360Service.update(id, {
      templateId: dto.templateId,
      deadline: dto.deadline ? new Date(dto.deadline) : undefined,
      minEvaluators: dto.minEvaluators,
    });
    return this.evaluation360Service.findById(id);
  }

  @Delete('evaluations/:id')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_DELETE)
  async delete(@Param('id', ParseUUIDPipe) id: string) {
    await this.evaluation360Service.delete(id);
    return { id };
  }

  // ==================== 状态流转 ====================

  @Post('evaluations/:id/start')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_UPDATE)
  @HttpCode(200)
  async start(@Param('id', ParseUUIDPipe) id: string) {
    await this.evaluation360Service.start(id);
    return this.evaluation360Service.findById(id);
  }

  @Post('evaluations/:id/complete')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_UPDATE)
  @HttpCode(200)
  async complete(@Param('id', ParseUUIDPipe) id: string) {
    await this.evaluation360Service.complete(id);
    return this.evaluation360Service.findById(id);
  }

  // ==================== 评估人管理 ====================

  @Post('evaluations/:id/evaluators')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_UPDATE)
  @HttpCode(200)
  async addEvaluators(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: AddEvaluatorsDto | AddEvaluatorDto,
  ) {
    // 前端发送 { evaluators: [{evaluatorId, relationship}] }
    // 后端服务层期望 [{evaluatorId, relationType}]
    let evaluators: { evaluatorId: string; relationType: RelationType; isAnonymous?: boolean }[];

    if ('evaluators' in dto && Array.isArray(dto.evaluators)) {
      // 数组格式：映射 relationship -> relationType
      evaluators = dto.evaluators.map((e) => ({
        evaluatorId: e.evaluatorId,
        relationType: (e.relationType || e.relationship) as RelationType,
        isAnonymous: e.isAnonymous,
      }));
    } else {
      // 单个格式（向后兼容）
      const single = dto as AddEvaluatorDto;
      evaluators = [{
        evaluatorId: single.evaluatorId,
        relationType: single.relationType as RelationType,
        isAnonymous: single.isAnonymous,
      }];
    }

    await this.evaluation360Service.addEvaluators(id, evaluators);
    return { evaluationId: id, added: evaluators.length };
  }

  @Delete('evaluations/:evaluationId/evaluators/:evaluatorId')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_UPDATE)
  async removeEvaluator(
    @Param('evaluationId', ParseUUIDPipe) evaluationId: string,
    @Param('evaluatorId', ParseUUIDPipe) evaluatorId: string,
  ) {
    await this.evaluation360Service.removeEvaluator(evaluationId, evaluatorId);
    return { evaluationId, evaluatorId };
  }

  // ==================== 任务 ====================

  @Get('tasks')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_VIEW)
  async findTasks(@Query() query: QueryTaskDto) {
    const items = await this.evaluation360Service.findTasks(query);
    return {
      items: items.map((item) => ({
        id: item.id,
        evaluationId: item.evaluationId,
        evaluatorId: item.evaluatorId,
        relationType: item.relationType,
        status: item.status,
        isAnonymous: item.isAnonymous,
        submittedAt: item.submittedAt,
        createdAt: item.createdAt,
        deletedAt: item.deletedAt,
      })),
    };
  }

  @Get('tasks/my')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_VIEW)
  async findMyTasks(@CurrentUser('userId') userId: string) {
    const items = await this.evaluation360Service.findMyTasks(userId);
    return {
      items: items.map((item) => ({
        id: item.id,
        evaluationId: item.evaluationId,
        evaluation360Id: item.evaluationId, // 前端兼容字段名
        evaluatorId: item.evaluatorId,
        relationType: item.relationType,
        relationship: item.relationType, // 前端兼容字段名
        status: item.status,
        isAnonymous: item.isAnonymous,
        submittedAt: item.submittedAt,
        createdAt: item.createdAt,
        updatedAt: (item as Record<string, unknown>).updatedAt || item.createdAt,
        evaluation: (item as Record<string, unknown>).evaluation,
      })),
    };
  }

  @Post('tasks/:id/submit')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_SUBMIT)
  @HttpCode(200)
  async submitFeedback(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: SubmitFeedbackDto,
    @CurrentUser('userId') currentUserId: string,
  ) {
    await this.evaluation360Service.submitFeedback(id, dto.responses, currentUserId);
    return { id, status: 'SUBMITTED' };
  }

  // ==================== 结果 ====================

  @Get('evaluations/:id/results')
  @RequirePermissions(PERFORMANCE_PERMISSIONS.E360_VIEW_RESULTS)
  async getResults(@Param('id', ParseUUIDPipe) id: string) {
    return this.evaluation360Service.getResults(id);
  }

  @Get('my-evaluation')
  async getMyEvaluation(
    @CurrentUser('userId') userId: string,
    @Query('cycleId') cycleId?: string,
  ) {
    if (!cycleId) return null;
    return this.evaluation360Service.getEmployee360Evaluation(cycleId, userId);
  }

  @Get('my-tasks')
  async getMyFeedbackTasks(
    @CurrentUser('userId') userId: string,
  ) {
    return this.evaluation360Service.findMyTasks(userId);
  }

}
