// TeacherService — GraphQL Resolver 的业务逻辑层（B1 裁决：P2 起 GraphQL）
// 通过 IamClient 调下游 iam gRPC（B2 裁决：首次实现即 gRPC）
// P2: 仅 iam 数据；P3+ 扩展 core-edu / content / data-ana / msg / ai
import { Injectable, Inject } from "@nestjs/common";
import { IAM_CLIENT } from "../clients/iam/iam-client.interface.js";
import type { IamClient } from "../clients/iam/iam-client.interface.js";
import type { CallContext } from "../clients/types.js";
import type {
  UserInfo,
  ViewportItem,
  EffectivePermissions,
} from "../clients/iam/iam.types.js";
import { logger } from "../shared/observability/logger.js";

/** GraphQL User 类型（聚合 UserInfo + EffectivePermissions） */
export interface GraphQLUser {
  id: string;
  email: string;
  name: string;
  roles: string[];
  permissions: string[];
  dataScope: string;
}

/** GraphQL DashboardData 类型 */
export interface DashboardData {
  user: GraphQLUser | null;
  classes: unknown[];
  viewports: ViewportItem[];
  stats: {
    totalExams: number;
    pendingGrading: number;
    todayHomework: number;
  } | null;
}

/** GraphQL Class 类型（P2 mock，P3+ core-edu 真实数据） */
export interface ClassInfo {
  id: string;
  name: string;
  gradeId: string;
}

/** P2 mock 班级数据（president §3.5：P2 班级列表来自 iam 数据，P3+ core-edu） */
const MOCK_CLASSES: ClassInfo[] = [
  { id: "class-001", name: "三年级1班", gradeId: "grade-3" },
  { id: "class-002", name: "三年级2班", gradeId: "grade-3" },
  { id: "class-003", name: "三年级3班", gradeId: "grade-3" },
];

@Injectable()
export class TeacherService {
  constructor(@Inject(IAM_CLIENT) private readonly iam: IamClient) {}

  /** 获取当前用户信息（聚合 iam.GetUserInfo + GetEffectivePermissions） */
  async getCurrentUser(ctx: CallContext): Promise<GraphQLUser> {
    const [userInfo, perms] = await Promise.all([
      this.iam.getUserInfo(ctx),
      this.iam.getEffectivePermissions(ctx),
    ]);
    return {
      id: userInfo.id,
      email: userInfo.email,
      name: userInfo.name,
      roles: userInfo.roles,
      permissions: perms.permissions,
      dataScope: perms.dataScope,
    };
  }

  /** 获取视口配置（iam.GetViewports） */
  async getViewports(ctx: CallContext): Promise<ViewportItem[]> {
    return this.iam.getViewports(ctx);
  }

  /**
   * 获取 Dashboard 聚合数据（president §2.8：P2 仅调 iam gRPC）
   * P2: user + viewports 有数据，classes 返回 mock，stats 返回 null + warning
   * P3+: classes 来自 core-edu，stats 来自 data-ana.GetTeacherDashboard
   */
  async getDashboard(ctx: CallContext): Promise<DashboardData> {
    const [user, viewports] = await Promise.all([
      this.getCurrentUser(ctx),
      this.iam.getViewports(ctx),
    ]);

    // P2: classes 返回 mock 数据（P3+ 替换为 core-edu.GetClassesByTeacher）
    // P2: stats 返回 null（P4+ 替换为 data-ana.GetTeacherDashboard）
    logger.warn(
      { userId: ctx.userId, phase: "P2" },
      "Dashboard P2: classes using mock, stats unavailable (field_unavailable_in_p2)",
    );

    return {
      user,
      viewports,
      classes: MOCK_CLASSES,
      stats: null,
    };
  }

  /** 获取教师班级列表（P2: mock；P3+: core-edu.GetClassesByTeacher） */
  async getClasses(ctx: CallContext): Promise<ClassInfo[]> {
    logger.warn(
      { userId: ctx.userId, phase: "P2" },
      "Classes P2: using mock data (core-edu not ready, field_unavailable_in_p2)",
    );
    return MOCK_CLASSES;
  }

  /** 获取单个班级详情（P2: mock；P3+: core-edu） */
  async getClass(ctx: CallContext, classId: string): Promise<ClassInfo | null> {
    logger.warn(
      { userId: ctx.userId, classId, phase: "P2" },
      "Class P2: using mock data (core-edu not ready, field_unavailable_in_p2)",
    );
    return MOCK_CLASSES.find((c) => c.id === classId) ?? null;
  }
}

/** 导出 EffectivePermissions 类型供外部使用 */
export type { EffectivePermissions, UserInfo };
