/**
 * Mock AI Provider HTTP Server
 * 用于集成测试中替代 DeepSeek API。
 * 支持: 正常响应 / 超时 / 429 / 500 / 非法 JSON
 */
import { createServer, Server, IncomingMessage, ServerResponse } from 'http';

interface Behavior {
  status: number;
  response: unknown;
  delayMs?: number;
}

const DEFAULT_RESPONSE = {
  id: 'mock-deepseek-001',
  object: 'chat.completion',
  created: Math.floor(Date.now() / 1000),
  model: 'deepseek-chat',
  choices: [{
    index: 0,
    message: {
      role: 'assistant',
      content: JSON.stringify({
        score: 85,
        summary: 'Mock AI: good understanding of the topic',
        strengths: ['Clear explanation', 'Accurate facts'],
        weaknesses: ['Could elaborate more on edge cases'],
        confidence: 0.9,
        learningState: 'proficient',
        riskLevel: 'low',
      }),
    },
    finish_reason: 'stop',
  }],
  usage: { prompt_tokens: 100, completion_tokens: 50, total_tokens: 150 },
};

export class MockAIProvider {
  private server: Server | null = null;
  private port = 0;
  private behavior: Behavior = { status: 200, response: DEFAULT_RESPONSE };

  // ========== behavior controls ==========

  setNormal() {
    this.behavior = { status: 200, response: DEFAULT_RESPONSE };
  }

  setTimeout() {
    this.behavior = { status: 200, response: DEFAULT_RESPONSE, delayMs: 120_000 };
  }

  set429() {
    this.behavior = { status: 429, response: { error: { message: 'Rate limit exceeded', type: 'rate_limit_error' } } };
  }

  set500() {
    this.behavior = { status: 500, response: { error: { message: 'Internal server error' } } };
  }

  setInvalidJson() {
    this.behavior = { status: 200, response: 'not valid json {{{{{' };
  }

  get url(): string {
    return `http://127.0.0.1:${this.port}`;
  }

  async start(): Promise<number> {
    return new Promise((resolve, reject) => {
      this.server = createServer((_req: IncomingMessage, res: ServerResponse) => {
        const b = this.behavior;

        if (b.delayMs) {
          // Simulate timeout — never respond
          return;
        }

        if (typeof b.response === 'string') {
          res.writeHead(b.status, { 'Content-Type': 'text/plain' });
          res.end(b.response);
        } else {
          res.writeHead(b.status, { 'Content-Type': 'application/json' });
          res.end(JSON.stringify(b.response));
        }
      });

      this.server.on('error', reject);
      this.server.listen(0, '127.0.0.1', () => {
        const addr = this.server!.address();
        if (addr && typeof addr === 'object') {
          this.port = addr.port;
          resolve(this.port);
        } else {
          reject(new Error('Could not get port'));
        }
      });
    });
  }

  async stop(): Promise<void> {
    return new Promise((resolve) => {
      if (this.server) {
        this.server.close(() => resolve());
        this.server = null;
      } else {
        resolve();
      }
    });
  }
}
