import type {
  ClassPerformanceDto,
  LearningTrendDto,
  StudentWeaknessDto,
} from "./dtos.js";
import { callWithMetrics } from "./grpc/call-with-metrics.js";
import {
  MOCK_CLASS_PERFORMANCE,
  MOCK_TREND,
  MOCK_WEAKNESS,
} from "./mock-data.js";

/**
 * DataAna 下游客户端接口（对齐 02-architecture-design.md §7.1 交互矩阵）。
 *
 * 方法：
 * - getStudentWeakness: AnalyticsService.GetStudentWeakness（✅ 已有）
 * - getLearningTrend: AnalyticsService.GetLearningTrend（✅ 已有）
 * - getClassPerformance: AnalyticsService.GetClassPerformance（✅ 已有）
 */
export interface DataAnaClient {
  getStudentWeakness(
    studentId: string,
    subjectId: string,
  ): Promise<StudentWeaknessDto>;
  getLearningTrend(
    studentId: string,
    startDate: number,
    endDate: number,
  ): Promise<LearningTrendDto>;
  getClassPerformance(
    classId: string,
    subjectId: string,
    startDate: number,
    endDate: number,
  ): Promise<ClassPerformanceDto>;
}

/**
 * Mock DataAna 客户端（DEV_MODE=true 时使用）。
 *
 * 固定数据：每学生 3 个薄弱点 + 7 天趋势 / 每班级 4 个学生成绩对比。
 */
export class MockDataAnaClient implements DataAnaClient {
  async getStudentWeakness(
    studentId: string,
    _subjectId: string,
  ): Promise<StudentWeaknessDto> {
    const weakness = MOCK_WEAKNESS[studentId];
    if (!weakness) {
      return { studentId, weakPoints: [] };
    }
    return { ...weakness, weakPoints: [...weakness.weakPoints] };
  }

  async getLearningTrend(
    studentId: string,
    _startDate: number,
    _endDate: number,
  ): Promise<LearningTrendDto> {
    const trend = MOCK_TREND[studentId];
    if (!trend) {
      return { studentId, points: [] };
    }
    return { ...trend, points: [...trend.points] };
  }

  async getClassPerformance(
    classId: string,
    _subjectId: string,
    _startDate: number,
    _endDate: number,
  ): Promise<ClassPerformanceDto> {
    const perf = MOCK_CLASS_PERFORMANCE[classId];
    if (!perf) {
      return {
        classId,
        averageScore: 0,
        passRate: 0,
        scores: [],
      };
    }
    return { ...perf, scores: [...perf.scores] };
  }
}

/**
 * gRPC DataAna 客户端。
 *
 * 通过 proto-loader 动态加载 analytics.proto，调用 AnalyticsService RPCs。
 */
export class GrpcDataAnaClient implements DataAnaClient {
  private readonly rawClient: unknown;

  constructor(rawClient: unknown) {
    this.rawClient = rawClient;
  }

  async getStudentWeakness(
    studentId: string,
    subjectId: string,
  ): Promise<StudentWeaknessDto> {
    return callWithMetrics<
      { studentId: string; subjectId: string },
      StudentWeaknessDto
    >(
      this.rawClient,
      "getStudentWeakness",
      { studentId, subjectId },
      "data-ana",
    );
  }

  async getLearningTrend(
    studentId: string,
    startDate: number,
    endDate: number,
  ): Promise<LearningTrendDto> {
    return callWithMetrics<
      { studentId: string; startDate: number; endDate: number },
      LearningTrendDto
    >(
      this.rawClient,
      "getLearningTrend",
      { studentId, startDate, endDate },
      "data-ana",
    );
  }

  async getClassPerformance(
    classId: string,
    subjectId: string,
    startDate: number,
    endDate: number,
  ): Promise<ClassPerformanceDto> {
    return callWithMetrics<
      {
        classId: string;
        subjectId: string;
        startDate: number;
        endDate: number;
      },
      ClassPerformanceDto
    >(
      this.rawClient,
      "getClassPerformance",
      { classId, subjectId, startDate, endDate },
      "data-ana",
    );
  }
}
