/**
 * Exams Resolver - myExams Query.
 *
 * 仲裁依据:
 *   - student-bff.schema.graphql Query.myExams
 *   - coord-final-decisions §2 B2 (gRPC 调用 core-edu)
 *   - coord-final-decisions §2 B6 (Redis 5-30s 短缓存)
 */
import type { StudentBffContext } from "../../shared/graphql/yoga.js";
import { ok, fail } from "../../shared/action-state.js";
import { CacheTTL } from "../../shared/cache/cache.module.js";
import { UnauthorizedError } from "../../shared/errors/application-error.js";

export const examsResolvers = {
  Query: {
    /**
     * myExams: 即将到来的考试列表.
     * @permission STUDENT_EXAM_READ
     * @dataScope OWN
     */
    async myExams(
      _parent: unknown,
      args: { status?: string; classId?: string },
      ctx: StudentBffContext,
    ): Promise<unknown> {
      if (!ctx.userId) {
        throw new UnauthorizedError();
      }

      const cacheKey = `${ctx.userId}:${args.classId ?? "all"}:${args.status ?? "all"}`;
      const cached = await ctx.cache.get<unknown>("exams", cacheKey);
      if (cached) {
        return ok(cached, {
          traceId: ctx.traceId,
          cachedAt: new Date().toISOString(),
        });
      }

      try {
        const result = await ctx.downstream.call(
          "core-edu",
          "ListExamsByClass",
          {
            studentId: ctx.userId,
            classId: args.classId,
            status: args.status ?? "upcoming",
          },
          {
            traceId: ctx.traceId,
            metadata: { "x-user-id": ctx.userId },
          },
        );

        const data = result as { exams: unknown[] };
        await ctx.cache.set("exams", data, CacheTTL.EXAMS, cacheKey);
        return ok(data, { traceId: ctx.traceId });
      } catch (err) {
        return fail(
          "BFF_STUDENT_BAD_GATEWAY",
          `Failed to fetch exams: ${(err as Error).message}`,
          { i18nKey: "error.bffStudent.bad_gateway", traceId: ctx.traceId },
        );
      }
    },
  },
};
