import { Controller, Get, Put, Post, Delete, Param, Body, Req, Query, BadRequestException } from '@nestjs/common';
import { UserAiService } from './user-ai.service';
import { QuizExecutionRouter } from './quiz-execution-router';
import { LearningAnalysisExecutionRouter } from './learning-analysis-execution-router';
import { QuotaGuardService } from '../membership/quota-guard.service';
import { SaveLearningProfileDto, UpdateAiSettingsDto, CreateCredentialDto, UpdateCredentialDto, CreateAnalysisJobDto } from './user-ai.dto';

@Controller('ai')
export class UserAiController {
  // M-MEMBER-01-CLOSE-01: jobType → quotaType
  private static readonly JOB_QUOTA: Record<string, string> = {
    active_recall: 'active_recall',
    feynman_evaluation: 'feynman_evaluation',
    quiz_generation: 'quiz_generation',
    learning_state_analysis: 'learning_analysis_manual',
    flashcard_generation: 'flashcard_generation',
  };

  constructor(
    private readonly service: UserAiService,
    private readonly quizRouter: QuizExecutionRouter,
    private readonly learningAnalysisRouter: LearningAnalysisExecutionRouter,
    private readonly quotaGuard: QuotaGuardService,
  ) {}

  // ── Profile ──

  @Get('profile')
  async getProfile(@Req() req: any) {
    return (await this.service.getProfile(req.user.id)) ?? {};
  }

  @Put('profile')
  async saveProfile(@Req() req: any, @Body() dto: SaveLearningProfileDto) {
    return this.service.saveProfile(req.user.id, dto);
  }

  // ── Settings ──

  @Get('settings')
  async getSettings(@Req() req: any) {
    return this.service.getSettings(req.user.id);
  }

  @Put('settings')
  async updateSettings(@Req() req: any, @Body() dto: UpdateAiSettingsDto) {
    return this.service.updateSettings(req.user.id, dto);
  }

  // ── Model Credentials ──

  @Get('model-credentials')
  async listCredentials(@Req() req: any) {
    return this.service.listCredentials(req.user.id);
  }

  @Post('model-credentials')
  async createCredential(@Req() req: any, @Body() dto: CreateCredentialDto) {
    return this.service.createCredential(req.user.id, dto);
  }

  @Put('model-credentials/:id')
  async updateCredential(@Req() req: any, @Param('id') id: string, @Body() dto: UpdateCredentialDto) {
    return this.service.updateCredential(req.user.id, id, dto);
  }

  @Delete('model-credentials/:id')
  async deleteCredential(@Req() req: any, @Param('id') id: string) {
    await this.service.deleteCredential(req.user.id, id);
    return { ok: true };
  }

  @Post('model-credentials/:id/test')
  async testCredential(@Req() req: any, @Param('id') id: string) {
    return this.service.testCredential(req.user.id, id);
  }

  // ── Analysis Jobs ──

  @Post('jobs')
  async createAnalysisJob(@Req() req: any, @Body() dto: CreateAnalysisJobDto) {
    const userId = req.user.id;
    const quotaType = UserAiController.JOB_QUOTA[dto.jobType];
    const opId = dto.idempotencyKey ?? `${dto.jobType}:${dto.targetType}:${dto.targetId}`;

    // 统一额度预占（Child Job 和定时任务不在此路径）
    if (quotaType) {
      const check = await this.quotaGuard.check(userId, quotaType, opId);
      if (!check.allowed) throw new BadRequestException(this.quotaGuard.buildError(check));
    }

    try {
      let result: any;
      if (dto.jobType === 'quiz_generation') {
        result = await this.quizRouter.generateQuiz(userId, dto);
      } else if (['learning_state_analysis', 'weak_point_analysis', 'next_action_planning'].includes(dto.jobType)) {
        result = await this.learningAnalysisRouter.analyze(userId, dto);
      } else {
        result = await this.service.createAnalysisJob(userId, dto);
      }
      if (quotaType) this.quotaGuard.confirm(opId).catch(() => {});
      return result;
    } catch (err) {
      if (quotaType) this.quotaGuard.cancel(opId).catch(() => {});
      throw err;
    }
  }

  @Post('jobs/:jobId/cancel')
  async cancelJob(@Req() req: any, @Param('jobId') jobId: string) {
    return this.service.cancelJob(req.user.id, jobId);
  }

  @Get('jobs/:jobId')
  async getJob(@Req() req: any, @Param('jobId') jobId: string) {
    return this.service.getJob(req.user.id, jobId);
  }

  @Get('jobs')
  async listJobs(@Req() req: any, @Query('status') status?: string, @Query('take') take?: string) {
    return this.service.listJobs(req.user.id, status, take ? parseInt(take) : undefined);
  }

  // ── Quiz Publish ──

  @Post('quizzes/:quizId/publish')
  async publishQuiz(@Req() req: any, @Param('quizId') quizId: string) {
    return this.service.publishQuiz(req.user.id, quizId);
  }

  @Post('flashcards/:cardId/publish')
  async publishFlashcard(@Req() req: any, @Param('cardId') cardId: string) {
    return this.service.publishFlashcard(req.user.id, cardId);
  }

  // ── Analysis Results ──

  @Get('analyses/:id')
  async getAnalysis(@Req() req: any, @Param('id') id: string) {
    return this.service.getAnalysis(req.user.id, id);
  }

  @Get('analyses')
  async listAnalyses(
    @Req() req: any,
    @Query('targetType') targetType?: string,
    @Query('targetId') targetId?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listAnalyses(req.user.id, targetType, targetId, take ? parseInt(take) : undefined);
  }

  @Get('recommendations')
  async listRecommendations(
    @Req() req: any,
    @Query('targetType') targetType?: string,
    @Query('targetId') targetId?: string,
    @Query('status') status?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listRecommendations(req.user.id, targetType, targetId, status, take ? parseInt(take) : undefined);
  }

  @Get('weak-points')
  async listWeakPoints(
    @Req() req: any,
    @Query('targetType') targetType?: string,
    @Query('targetId') targetId?: string,
    @Query('status') status?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listWeakPoints(req.user.id, targetType, targetId, status, take ? parseInt(take) : undefined);
  }

  @Get('quizzes/:quizId')
  async getQuiz(@Req() req: any, @Param('quizId') quizId: string) {
    return this.service.getQuiz(req.user.id, quizId);
  }

  @Get('quizzes/:quizId/questions')
  async getQuizQuestions(
    @Req() req: any,
    @Param('quizId') quizId: string,
    @Query('attemptId') attemptId?: string,
  ) {
    return this.service.getQuizQuestions(req.user.id, quizId, attemptId);
  }

  @Get('quizzes')
  async listQuizzes(
    @Req() req: any,
    @Query('knowledgeBaseId') knowledgeBaseId?: string,
    @Query('status') status?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listQuizzes(req.user.id, knowledgeBaseId, status, take ? parseInt(take) : undefined);
  }

  @Post('reanalyze')
  async triggerReanalysis(
    @Req() req: any,
    @Body('targetType') targetType: string,
    @Body('targetId') targetId: string,
  ) {
    return this.service.triggerReanalysis(req.user.id, targetType, targetId);
  }

  @Get('notifications')
  async listNotifications(@Req() req: any, @Query('take') take?: string) {
    return this.service.listNotifications(req.user.id, take ? parseInt(take) : undefined);
  }

  @Post('artifacts/:type/:id/feedback')
  async submitArtifactFeedback(
    @Req() req: any,
    @Param('type') artifactType: string,
    @Param('id') artifactId: string,
    @Body() dto: { feedbackType: string; reason?: string },
  ) {
    return this.service.submitArtifactFeedback(req.user.id, artifactType, artifactId, dto);
  }

  @Post('feedback')
  async submitFeedback(@Req() req: any, @Body() dto: { category: string; content: string; email?: string; deviceInfo?: any }) {
    return this.service.submitFeedback(req.user.id, dto);
  }

  @Get('flashcards/:cardId')
  async getFlashcard(@Req() req: any, @Param('cardId') cardId: string) {
    return this.service.getFlashcard(req.user.id, cardId);
  }

  @Get('flashcards')
  async listFlashcards(
    @Req() req: any,
    @Query('knowledgePointId') knowledgePointId?: string,
    @Query('status') status?: string,
    @Query('take') take?: string,
  ) {
    return this.service.listFlashcards(req.user.id, knowledgePointId, status, take ? parseInt(take) : undefined);
  }
}
