// GraphQL Yoga endpoint（B1 裁决：P2 起直接 GraphQL）
// POST /graphql — GraphQL query/mutation endpoint
// GET /graphql — GraphQL Playground（开发环境）/ schema introspection
import { Controller, Post, Get, Req, Res, Inject } from "@nestjs/common";
import { createYoga } from "graphql-yoga";
import type { Request, Response } from "express";
import { env } from "../config/env.js";
import { logger } from "../shared/observability/logger.js";
import { loadSchema } from "./schema-loader.js";
import { buildGraphQLContext } from "./context.js";
import { TeacherService } from "../teacher/teacher.service.js";
import { buildResolvers } from "../teacher/teacher.resolver.js";

@Controller("graphql")
export class GraphQLController {
  // Yoga 实例类型复杂，用内联类型避免泛型不匹配
  private readonly yoga: (req: Request, res: Response) => Promise<void>;

  constructor(@Inject(TeacherService) service: TeacherService) {
    const resolvers = buildResolvers(service);
    const schema = loadSchema(resolvers);

    const yoga = createYoga({
      schema,
      graphqlEndpoint: env.GRAPHQL_PATH,
      // graphql-yoga v5：request 是 WHATWG Request，headers 需用 .get() 提取
      context: ({ request }) => {
        const req = {
          headers: {
            "x-user-id": request.headers.get("x-user-id") ?? undefined,
            "x-request-id": request.headers.get("x-request-id") ?? undefined,
            "x-user-roles": request.headers.get("x-user-roles") ?? undefined,
          },
        } as unknown as Request;
        return buildGraphQLContext(req);
      },
      logging: {
        debug: (msg: unknown) => logger.debug({ yoga: msg }, "GraphQL Yoga"),
        info: (msg: unknown) => logger.info({ yoga: msg }, "GraphQL Yoga"),
        warn: (msg: unknown) => logger.warn({ yoga: msg }, "GraphQL Yoga"),
        error: (msg: unknown) => logger.error({ yoga: msg }, "GraphQL Yoga"),
      },
      // GraphQL Playground（开发环境启用）
      graphiql: env.NODE_ENV === "development",
    });

    this.yoga = yoga as unknown as (
      req: Request,
      res: Response,
    ) => Promise<void>;

    logger.info(
      { graphqlEndpoint: env.GRAPHQL_PATH },
      "GraphQL Yoga endpoint initialized",
    );
  }

  @Post()
  async handleGraphQL(
    @Req() req: Request,
    @Res() res: Response,
  ): Promise<void> {
    await this.yoga(req, res);
  }

  @Get()
  async handleGraphiQL(
    @Req() req: Request,
    @Res() res: Response,
  ): Promise<void> {
    await this.yoga(req, res);
  }
}
