import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { FeishuBot } from '../entities/feishu-bot.entity';
import { FeishuAssessmentSession } from '../entities/feishu-assessment-session.entity';
import { FeishuService } from '../feishu.service';
import { AssessmentService } from '../../assessment/assessment.service';
import { AssessmentCommandParser } from './assessment-command.parser';
import { AssessmentCommandType } from '../dto/assessment-command.dto';

@Injectable()
export class FeishuAssessmentService {
  private readonly logger = new Logger(FeishuAssessmentService.name);

  constructor(
    @InjectRepository(FeishuAssessmentSession)
    private sessionRepository: Repository<FeishuAssessmentSession>,
    @Inject(forwardRef(() => AssessmentService))
    private assessmentService: AssessmentService,
    @Inject(forwardRef(() => FeishuService))
    private feishuService: FeishuService,
    private commandParser: AssessmentCommandParser,
  ) {}

  /**
   * 处理测评命令
   */
  async handleCommand(
    bot: FeishuBot,
    openId: string,
    message: string,
  ): Promise<void> {
    // Ensure bot user relation is loaded (might be missing if fetched from an old cache or WS connection)
    if (!bot.user) {
      this.logger.log(`Reloading bot ${bot.id} to fetch user relation`);
      const loadedBot = await this.feishuService.getBotById(bot.id);
      if (loadedBot) {
        bot = loadedBot;
      }
    }

    const command = this.commandParser.parse(message);

    if (!command) {
      // 不是测评命令，使用默认聊天处理
      await this.feishuService.processChatMessage(bot, openId, '', message);
      return;
    }

    try {
      switch (command.type) {
        case AssessmentCommandType.START:
          await this.startAssessment(bot, openId, command.parameters);
          break;
        case AssessmentCommandType.ANSWER:
          await this.submitAnswer(bot, openId, command.parameters.join(' '));
          break;
        case AssessmentCommandType.STATUS:
          await this.getStatus(bot, openId);
          break;
        case AssessmentCommandType.RESULT:
          await this.getResult(bot, openId);
          break;
        case AssessmentCommandType.HELP:
          await this.sendHelp(bot, openId);
          break;
        case AssessmentCommandType.CANCEL:
          await this.cancelAssessment(bot, openId);
          break;
        default:
          await this.sendHelp(bot, openId);
      }
    } catch (error) {
      this.logger.error(
        `Failed to handle assessment command: ${error.message}`,
        error,
      );
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `处理测评命令时出错: ${error.message}`,
      );
    }
  }

  /**
   * 开始测评
   */
  async startAssessment(
    bot: FeishuBot,
    openId: string,
    parameters: string[],
  ): Promise<void> {
    // 检查是否已有进行中的测评
    const existingSession = await this.getActiveSession(bot.id, openId);
    if (existingSession) {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '您已有进行中的测评会话，请先完成当前测评或发送 /assessment cancel 取消。',
      );
      return;
    }

    // 解析参数
    const [kbIdOrTemplateId] = parameters;
    let knowledgeBaseId: string | undefined;
    let templateId: string | undefined;

    // 统一作为模板ID处理，因为模板包含了更完整的测评配置
    // 且知识库ID也多为UUID，按长度判断不准确
    if (kbIdOrTemplateId) {
      templateId = kbIdOrTemplateId;
    }

    // 使用机器人配置的知识库或知识组（如果未指定）
    if (!knowledgeBaseId && !templateId) {
      if (bot.knowledgeBaseId) {
        knowledgeBaseId = bot.knowledgeBaseId;
      } else if (bot.knowledgeGroupId) {
        knowledgeBaseId = bot.knowledgeGroupId;
      }
    }

    this.logger.log(
      `Starting assessment: bot=${bot.id}, openId=${openId}, kb=${knowledgeBaseId}, template=${templateId}`,
    );

    // 发送"正在创建"消息
    await this.feishuService.sendTextMessage(
      bot,
      'open_id',
      openId,
      '⏳ 正在创建测评会话，请稍候...',
    );

    try {
      // 创建测评会话
      const session = await this.assessmentService.startSession(
        bot.userId,
        knowledgeBaseId,
        bot.user?.tenantId || 'default',
        'zh',
        templateId,
      );

      // 触发问题生成（startSession 仅创建会话，getSessionState 会触发 agent 生成问题）
      this.logger.log(
        `Triggering question generation for session ${session.id}`,
      );
      const state = await this.assessmentService.getSessionState(
        session.id,
        bot.userId,
      );
      const questions = state.questions || [];

      // 存储飞书会话关联
      const feishuSession = this.sessionRepository.create({
        botId: bot.id,
        openId,
        assessmentSessionId: session.id,
        status: 'active',
        currentQuestionIndex: 0,
      });
      await this.sessionRepository.save(feishuSession);

      // 发送第一个问题
      if (questions && questions.length > 0) {
        const firstQuestion = questions[0];
        const totalQuestions = state.questionCount || questions.length;
        const card = this.buildQuestionCard(
          firstQuestion,
          session.id,
          1,
          totalQuestions,
        );
        await this.feishuService.sendCardMessage(bot, 'open_id', openId, card);
      } else {
        await this.feishuService.sendTextMessage(
          bot,
          'open_id',
          openId,
          '测评会话已创建，但未能生成问题。',
        );
      }
    } catch (error) {
      this.logger.error(`Failed to start assessment: ${error.message}`, error);
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `创建测评会话失败: ${error.message}`,
      );
    }
  }

  /**
   * 提交答案
   */
  async submitAnswer(
    bot: FeishuBot,
    openId: string,
    answer: string,
  ): Promise<void> {
    const session = await this.getActiveSession(bot.id, openId);

    if (!session) {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '没有进行中的测评会话。请发送 /assessment start 开始测评。',
      );
      return;
    }

    if (!answer || answer.trim() === '') {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '请提供答案。',
      );
      return;
    }

    this.logger.log(
      `Submitting answer for session ${session.assessmentSessionId}`,
    );

    // 发送"正在评估"消息
    await this.feishuService.sendTextMessage(
      bot,
      'open_id',
      openId,
      '⏳ 正在评估答案...',
    );

    try {
      // 提交答案到测评服务
      const result = await this.assessmentService.submitAnswer(
        session.assessmentSessionId,
        bot.userId,
        answer,
        'zh',
      );

      this.logger.log(
        `Assessment result for session ${session.assessmentSessionId}: score=${result.finalScore}, hasReport=${!!result.report}, questionsLen=${result.questions?.length}, questionsJsonLen=${result.questions_json?.length}`,
      );
      this.logger.debug(`Result keys: ${Object.keys(result).join(', ')}`);
      if (result.report) {
        this.logger.debug(
          `Result report snippet: ${result.report.substring(0, 100)}...`,
        );
      }

      // 更新会话状态
      session.currentQuestionIndex = result.currentQuestionIndex || 0;

      // 检查是否完成
      if (result.report) {
        session.status = 'completed';
        await this.sessionRepository.save(session);

        // 发送测评结果
        await this.sendAssessmentResult(bot, openId, result);
      } else if (result.questions && result.questions.length > 0) {
        // 更新并保存会话
        await this.sessionRepository.save(session);

        // 发送下一个问题
        const currentQuestionIndex = result.currentQuestionIndex || 0;
        const nextQuestion = result.questions[currentQuestionIndex];
        const totalQuestions = result.questionCount || result.questions.length;

        const card = this.buildQuestionCard(
          nextQuestion,
          session.assessmentSessionId,
          currentQuestionIndex + 1,
          totalQuestions,
        );
        await this.feishuService.sendCardMessage(bot, 'open_id', openId, card);
      } else if (result.questions_json && result.questions_json.length > 0) {
        // 有些版本返回 questions_json
        await this.sessionRepository.save(session);
        const currentQuestionIndex = result.currentQuestionIndex || 0;
        const nextQuestion = result.questions_json[currentQuestionIndex];
        const totalQuestions =
          result.questionCount || result.questions_json.length;

        const card = this.buildQuestionCard(
          nextQuestion,
          session.assessmentSessionId,
          currentQuestionIndex + 1,
          totalQuestions,
        );
        await this.feishuService.sendCardMessage(bot, 'open_id', openId, card);
      } else {
        // 没有更多问题，完成测评
        session.status = 'completed';
        await this.sessionRepository.save(session);
        await this.sendAssessmentResult(bot, openId, result);
      }
    } catch (error) {
      this.logger.error(`Failed to submit answer: ${error.message}`, error);
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `提交答案失败: ${error.message}`,
      );
    }
  }

  /**
   * 获取测评状态
   */
  async getStatus(bot: FeishuBot, openId: string): Promise<void> {
    const session = await this.getActiveSession(bot.id, openId);

    if (!session) {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '没有进行中的测评会话。',
      );
      return;
    }

    try {
      const assessmentState = await this.assessmentService.getSessionState(
        session.assessmentSessionId,
        bot.userId,
      );

      const currentQuestionIndex = assessmentState.currentQuestionIndex || 0;
      const totalQuestions = assessmentState.questions?.length || 0;

      const message =
        `测评状态:\n` +
        `- 进度: ${currentQuestionIndex + 1}/${totalQuestions}\n` +
        `- 状态: ${session.status === 'active' ? '进行中' : '已完成'}\n` +
        `- 开始时间: ${session.createdAt.toLocaleString('zh-CN')}`;

      await this.feishuService.sendTextMessage(bot, 'open_id', openId, message);
    } catch (error) {
      this.logger.error(`Failed to get status: ${error.message}`, error);
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `获取状态失败: ${error.message}`,
      );
    }
  }

  /**
   * 获取测评结果
   */
  async getResult(bot: FeishuBot, openId: string): Promise<void> {
    const session = await this.getActiveSession(bot.id, openId);

    if (!session) {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '没有进行中的测评会话。',
      );
      return;
    }

    if (session.status !== 'completed') {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '测评尚未完成，请先完成所有问题。',
      );
      return;
    }

    try {
      const assessmentState = await this.assessmentService.getSessionState(
        session.assessmentSessionId,
        bot.userId,
      );

      await this.sendAssessmentResult(bot, openId, assessmentState);
    } catch (error) {
      this.logger.error(`Failed to get result: ${error.message}`, error);
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `获取结果失败: ${error.message}`,
      );
    }
  }

  /**
   * 取消测评
   */
  async cancelAssessment(bot: FeishuBot, openId: string): Promise<void> {
    const session = await this.getActiveSession(bot.id, openId);

    if (!session) {
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '没有进行中的测评会话。',
      );
      return;
    }

    try {
      session.status = 'cancelled';
      await this.sessionRepository.save(session);

      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        '测评会话已取消。发送 /assessment start 开始新的测评。',
      );
    } catch (error) {
      this.logger.error(`Failed to cancel assessment: ${error.message}`, error);
      await this.feishuService.sendTextMessage(
        bot,
        'open_id',
        openId,
        `取消测评失败: ${error.message}`,
      );
    }
  }

  /**
   * 发送帮助信息
   */
  async sendHelp(bot: FeishuBot, openId: string): Promise<void> {
    const helpText = this.commandParser.getHelpText('zh');
    await this.feishuService.sendTextMessage(bot, 'open_id', openId, helpText);
  }

  /**
   * 获取活跃会话
   */
  private async getActiveSession(
    botId: string,
    openId: string,
  ): Promise<FeishuAssessmentSession | null> {
    return this.sessionRepository.findOne({
      where: {
        botId,
        openId,
        status: 'active',
      },
      order: { createdAt: 'DESC' },
    });
  }

  /**
   * 构建问题卡片
   */
  private buildQuestionCard(
    question: any,
    sessionId: string,
    currentIndex: number,
    totalQuestions: number,
  ): any {
    const difficultyColors: Record<string, string> = {
      简单: 'green',
      普通: 'blue',
      困难: 'orange',
      专家: 'red',
      Easy: 'green',
      Medium: 'blue',
      Hard: 'orange',
      Advanced: 'orange',
      Expert: 'red',
      Specialist: 'red',
    };

    const difficulty = question.difficulty || '普通';
    const headerColor = difficultyColors[difficulty] || 'blue';

    return {
      config: { wide_screen_mode: true },
      header: {
        template: headerColor,
        title: {
          content: `人才测评 (${currentIndex}/${totalQuestions})`,
          tag: 'plain_text',
        },
      },
      elements: [
        {
          tag: 'div',
          text: {
            content: `**问题 ${currentIndex}:** ${question.questionText || question.text || question.content || '无问题内容'}`,
            tag: 'lark_md',
          },
        },
        ...(question.options
          ? [
              {
                tag: 'div',
                text: {
                  content: `选项:\n${question.options
                    .map(
                      (opt: string, i: number) =>
                        `${String.fromCharCode(65 + i)}. ${opt}`,
                    )
                    .join('\n')}`,
                  tag: 'lark_md',
                },
              },
            ]
          : []),
        {
          tag: 'div',
          text: {
            content: `难度: ${difficulty} | 分值: ${question.score || 1}`,
            tag: 'lark_md',
          },
        },
        {
          tag: 'hr',
        },
        {
          tag: 'note',
          elements: [
            {
              content: `直接回复答案或使用 /assessment answer [你的答案]`,
              tag: 'plain_text',
            },
          ],
        },
      ],
    };
  }

  /**
   * 发送测评结果
   */
  private async sendAssessmentResult(
    bot: FeishuBot,
    openId: string,
    result: any,
  ): Promise<void> {
    const report = result.report || result.finalReport;
    const score = result.finalScore || result.score;

    const resultCard = {
      config: { wide_screen_mode: true },
      header: {
        template: 'green',
        title: {
          content: '测评完成',
          tag: 'plain_text',
        },
      },
      elements: [
        {
          tag: 'div',
          text: {
            content: `**测评结果**`,
            tag: 'lark_md',
          },
        },
        ...(score !== undefined
          ? [
              {
                tag: 'div',
                text: {
                  content: `**总分**: ${score.toFixed(1)}`,
                  tag: 'lark_md',
                },
              },
            ]
          : []),
        {
          tag: 'div',
          text: {
            content: `**报告**:\n${report && report.trim().length > 0 ? report : '未生成详细报告。'}`,
            tag: 'lark_md',
          },
        },
        {
          tag: 'hr',
        },
        {
          tag: 'note',
          elements: [
            {
              content: `发送 /assessment start 开始新的测评`,
              tag: 'plain_text',
            },
          ],
        },
      ],
    };

    await this.feishuService.sendCardMessage(
      bot,
      'open_id',
      openId,
      resultCard,
    );
  }
}
