/**
 * AI Resolver - aiChat Query/Mutation (P5 扩展).
 *
 * 仲裁依据:
 *   - student-bff.schema.graphql (待补充 aiChat Query)
 *   - coord-final-decisions §2 B2 (gRPC 调用 ai)
 *   - coord-final-decisions §2 B4 (强制自我越权防御)
 *   - president-final-rulings §2.3 (跨阶段扩展例外)
 *
 * AI 答疑流式响应 (StreamChat) 通过 SSE 端点单独实现 (P5),
 * 本 Resolver 仅处理同步 Chat.
 */
import { z } from "zod";
import type { StudentBffContext } from "../../shared/graphql/yoga.js";
import { ok, fail } from "../../shared/action-state.js";
import {
  UnauthorizedError,
  ValidationError,
} from "../../shared/errors/application-error.js";

const AIChatInputSchema = z.object({
  messages: z
    .array(
      z.object({
        role: z.enum(["user", "assistant"]),
        content: z.string().min(1).max(8000),
      }),
    )
    .min(1)
    .max(20),
  model: z
    .enum(["gpt-4o-mini", "baichuan-53b", "local-qwen-7b"])
    .default("gpt-4o-mini"),
  context: z
    .object({
      subject: z.string().optional(),
      knowledgePointId: z.string().optional(),
    })
    .optional(),
});

export const aiResolvers = {
  Query: {
    /**
     * aiChat: AI 答疑 (同步).
     * @permission STUDENT_AI_CHAT
     * @dataScope OWN
     *
     * 实际为 Mutation (写操作, 消耗 AI 配额), 但 schema 设计为 Query 便于前端 GET 缓存.
     * 后续如需限流, 改为 Mutation.
     */
    async aiChat(
      _parent: unknown,
      args: { input: unknown },
      ctx: StudentBffContext,
    ): Promise<unknown> {
      if (!ctx.userId) {
        throw new UnauthorizedError();
      }

      const parseResult = AIChatInputSchema.safeParse(args.input);
      if (!parseResult.success) {
        throw new ValidationError(
          "Invalid aiChat input",
          parseResult.error.flatten(),
        );
      }
      const input = parseResult.data;

      try {
        const result = await ctx.downstream.call("ai", "Chat", {
          userId: ctx.userId,
          messages: input.messages,
          model: input.model,
          context: input.context,
        }, {
          traceId: ctx.traceId,
          metadata: { "x-user-id": ctx.userId },
          // AI 调用可能耗时较长, 延长超时
          timeoutMs: 30000,
        });

        return ok(result, { traceId: ctx.traceId });
      } catch (err) {
        return fail(
          "BFF_STUDENT_BAD_GATEWAY",
          `Failed to chat with AI: ${(err as Error).message}`,
          { i18nKey: "error.bffStudent.bad_gateway", traceId: ctx.traceId },
        );
      }
    },
  },
};
