import { Controller } from "@nestjs/common";
import { GrpcMethod } from "@nestjs/microservices";
import { TemplatesService } from "../templates/templates.service.js";
import {
  createTemplateSchema,
  updateTemplateSchema,
  listTemplatesSchema,
  renderTemplateSchema,
} from "../templates/templates.dto.js";
import type { NotificationTemplate } from "../notifications/notifications.schema.js";

/**
 * TemplatesGrpcController —— gRPC 入口（NotificationTemplateService 6 RPC）。
 *
 * 仲裁依据：
 * - msg.proto §NotificationTemplateService（6 RPC）
 * - proto-loader 默认 keepCase=false，字段名 camelCase
 */

interface GrpcTemplate {
  id: string;
  code: string;
  type: string;
  titleTemplate: string;
  contentTemplate: string;
  defaultChannels: string[];
  variables: string[];
  locale: string;
  status: string;
  createdAt: number;
  updatedAt: number;
}

function opt(val: unknown): string | undefined {
  if (typeof val === "string" && val.length > 0) return val;
  return undefined;
}

function toGrpcTemplate(t: NotificationTemplate): GrpcTemplate {
  return {
    id: t.id,
    code: t.code,
    type: t.type,
    titleTemplate: t.titleTemplate,
    contentTemplate: t.contentTemplate,
    defaultChannels: t.defaultChannels,
    variables: t.variables,
    locale: t.locale,
    status: t.status,
    createdAt: t.createdAt instanceof Date ? t.createdAt.getTime() : 0,
    updatedAt: t.updatedAt instanceof Date ? t.updatedAt.getTime() : 0,
  };
}

@Controller()
export class TemplatesGrpcController {
  constructor(private readonly service: TemplatesService) {}

  @GrpcMethod("NotificationTemplateService", "CreateTemplate")
  async createTemplate(data: Record<string, unknown>): Promise<GrpcTemplate> {
    const dto = createTemplateSchema.parse({
      code: data.code,
      type: data.type,
      titleTemplate: data.titleTemplate,
      contentTemplate: data.contentTemplate,
      defaultChannels: Array.isArray(data.defaultChannels)
        ? data.defaultChannels
        : [],
      variables: Array.isArray(data.variables) ? data.variables : [],
      locale: opt(data.locale),
    });
    const tpl = await this.service.create(dto);
    return toGrpcTemplate(tpl);
  }

  @GrpcMethod("NotificationTemplateService", "GetTemplate")
  async getTemplate(data: Record<string, unknown>): Promise<GrpcTemplate> {
    const tpl = await this.service.getById(String(data.id ?? ""));
    return toGrpcTemplate(tpl);
  }

  @GrpcMethod("NotificationTemplateService", "ListTemplates")
  async listTemplates(data: Record<string, unknown>): Promise<{
    templates: GrpcTemplate[];
  }> {
    const dto = listTemplatesSchema.parse({
      type: opt(data.type),
      status: opt(data.status),
    });
    const templates = await this.service.list(dto);
    return { templates: templates.map(toGrpcTemplate) };
  }

  @GrpcMethod("NotificationTemplateService", "UpdateTemplate")
  async updateTemplate(data: Record<string, unknown>): Promise<GrpcTemplate> {
    const dto = updateTemplateSchema.parse({
      titleTemplate: opt(data.titleTemplate),
      contentTemplate: opt(data.contentTemplate),
      defaultChannels: Array.isArray(data.defaultChannels)
        ? data.defaultChannels
        : undefined,
      variables: Array.isArray(data.variables) ? data.variables : undefined,
      status: opt(data.status),
    });
    const tpl = await this.service.update(String(data.id ?? ""), dto);
    return toGrpcTemplate(tpl);
  }

  @GrpcMethod("NotificationTemplateService", "DeleteTemplate")
  async deleteTemplate(
    data: Record<string, unknown>,
  ): Promise<Record<string, never>> {
    await this.service.delete(String(data.id ?? ""));
    return {};
  }

  @GrpcMethod("NotificationTemplateService", "RenderTemplate")
  async renderTemplate(data: Record<string, unknown>): Promise<{
    title: string;
    content: string;
  }> {
    const dto = renderTemplateSchema.parse({
      code: data.code,
      variables: data.variables ?? {},
      locale: opt(data.locale),
    });
    const result = await this.service.render(dto);
    return { title: result.title, content: result.content };
  }
}
