import { Controller } from "@nestjs/common";
import { GrpcMethod } from "@nestjs/microservices";
import { ChaptersService } from "../chapters/chapters.service.js";
import type { Chapter } from "../chapters/chapters.schema.js";
import type {
  CreateChapterRequest,
  GetChapterRequest,
  ListChaptersRequest,
  ListChaptersResponse,
  UpdateChapterRequest,
  DeleteChapterRequest,
  GrpcChapter,
  Empty,
} from "./grpc-types.js";

function toGrpcChapter(c: Chapter): GrpcChapter {
  return {
    id: c.id,
    textbook_id: c.textbookId,
    title: c.title,
    order: c.order,
    parent_id: c.parentId ?? "",
    status: c.status,
    created_at: c.createdAt.getTime(),
    updated_at: c.updatedAt.getTime(),
  };
}

@Controller()
export class ChapterGrpcController {
  constructor(private readonly service: ChaptersService) {}

  @GrpcMethod("ChapterService", "CreateChapter")
  async createChapter(data: CreateChapterRequest): Promise<GrpcChapter> {
    const { id } = await this.service.createChapter({
      textbookId: data.textbook_id,
      title: data.title,
      order: data.order,
      parentId: data.parent_id,
    });
    const chapter = await this.service.getChapter(id);
    return toGrpcChapter(chapter);
  }

  @GrpcMethod("ChapterService", "GetChapter")
  async getChapter(data: GetChapterRequest): Promise<GrpcChapter> {
    const chapter = await this.service.getChapter(data.id);
    return toGrpcChapter(chapter);
  }

  @GrpcMethod("ChapterService", "ListChapters")
  async listChapters(data: ListChaptersRequest): Promise<ListChaptersResponse> {
    const chapters = await this.service.listChaptersByTextbook(
      data.textbook_id,
    );
    return { chapters: chapters.map(toGrpcChapter) };
  }

  @GrpcMethod("ChapterService", "UpdateChapter")
  async updateChapter(data: UpdateChapterRequest): Promise<GrpcChapter> {
    await this.service.updateChapter(data.id, {
      title: data.title,
      order: data.order ?? undefined,
      status: data.status,
    });
    const chapter = await this.service.getChapter(data.id);
    return toGrpcChapter(chapter);
  }

  @GrpcMethod("ChapterService", "DeleteChapter")
  async deleteChapter(data: DeleteChapterRequest): Promise<Empty> {
    await this.service.deleteChapter(data.id);
    return {};
  }
}
