import { Controller } from "@nestjs/common";
import { GrpcMethod } from "@nestjs/microservices";
import { TextbooksService } from "../textbooks/textbooks.service.js";
import type { Textbook } from "../textbooks/textbooks.schema.js";
import type {
  CreateTextbookRequest,
  GetTextbookRequest,
  ListTextbooksRequest,
  ListTextbooksResponse,
  UpdateTextbookRequest,
  DeleteTextbookRequest,
  GrpcTextbook,
  Empty,
} from "./grpc-types.js";

function toGrpcTextbook(t: Textbook): GrpcTextbook {
  return {
    id: t.id,
    title: t.title,
    subject_id: t.subjectId,
    grade_id: t.gradeId,
    version: t.version,
    status: t.status,
    tenant_id: t.tenantId ?? "",
    metadata: t.metadata ?? null,
    created_at: t.createdAt.getTime(),
    updated_at: t.updatedAt.getTime(),
  };
}

@Controller()
export class TextbookGrpcController {
  constructor(private readonly service: TextbooksService) {}

  @GrpcMethod("TextbookService", "CreateTextbook")
  async createTextbook(data: CreateTextbookRequest): Promise<GrpcTextbook> {
    const { id } = await this.service.create({
      title: data.title,
      subjectId: data.subject_id,
      gradeId: data.grade_id,
      version: data.version,
      metadata: data.metadata ?? null,
    });
    const textbook = await this.service.getById(id);
    return toGrpcTextbook(textbook);
  }

  @GrpcMethod("TextbookService", "GetTextbook")
  async getTextbook(data: GetTextbookRequest): Promise<GrpcTextbook> {
    const textbook = await this.service.getById(data.id);
    return toGrpcTextbook(textbook);
  }

  @GrpcMethod("TextbookService", "ListTextbooks")
  async listTextbooks(
    data: ListTextbooksRequest,
  ): Promise<ListTextbooksResponse> {
    const pageSize = data.page_size ?? 20;
    const page = data.page_token ? Number(data.page_token) : 1;
    const textbooks = await this.service.list({
      subjectId: data.subject_id,
      gradeId: data.grade_id,
      page,
      pageSize,
    });
    return {
      textbooks: textbooks.map(toGrpcTextbook),
      next_page_token: textbooks.length === pageSize ? String(page + 1) : "",
    };
  }

  @GrpcMethod("TextbookService", "UpdateTextbook")
  async updateTextbook(data: UpdateTextbookRequest): Promise<GrpcTextbook> {
    await this.service.update(data.id, {
      title: data.title,
      status: data.status,
      metadata: data.metadata,
    });
    const textbook = await this.service.getById(data.id);
    return toGrpcTextbook(textbook);
  }

  @GrpcMethod("TextbookService", "DeleteTextbook")
  async deleteTextbook(data: DeleteTextbookRequest): Promise<Empty> {
    await this.service.delete(data.id);
    return {};
  }
}
