import { Body, Controller, Logger, Post } from "@nestjs/common";
import { InstancesService } from "../instances/instances.service";
import { MessagesService } from "../messages/messages.service";

type EvolutionWebhookBody = {
  event?: string;
  instance?: string;
  data?: unknown;
  sender?: string;
  destination?: string;
  date_time?: string;
  server_url?: string;
  apikey?: string;
};

@Controller("webhooks")
export class WebhooksController {
  private readonly logger = new Logger(WebhooksController.name);

  constructor(
    private readonly messages: MessagesService,
    private readonly instances: InstancesService,
  ) {}

  @Post("evolution")
  async handle(@Body() body: EvolutionWebhookBody) {
    const event = (body.event || "").toUpperCase().replace(/\./g, "_");
    const instanceName = body.instance || "";
    if (!instanceName) {
      return { ok: false, reason: "missing instance" };
    }

    this.logger.debug(`webhook ${event} instance=${instanceName}`);

    if (event === "QRCODE_UPDATED" || event.includes("QRCODE")) {
      const data = body.data as { qrcode?: { base64?: string }; base64?: string };
      const qr =
        data?.qrcode?.base64 ||
        data?.base64 ||
        (typeof (body.data as { qrcode?: string })?.qrcode === "string"
          ? (body.data as { qrcode: string }).qrcode
          : null);
      if (qr) {
        await this.instances.updateFromWebhook(instanceName, {
          status: "qr",
          qrBase64: qr,
        });
      }
      return { ok: true, event };
    }

    if (event === "CONNECTION_UPDATE" || event.includes("CONNECTION")) {
      const data = body.data as {
        state?: string;
        statusReason?: number;
        instance?: { state?: string; owner?: string; ownerJid?: string };
      };
      const state =
        data?.state || data?.instance?.state || (body.data as { status?: string })?.status;
      const mapped =
        state === "open"
          ? "open"
          : state === "close"
            ? "close"
            : state === "connecting"
              ? "connecting"
              : undefined;
      const phone =
        data?.instance?.ownerJid ||
        data?.instance?.owner ||
        null;
      await this.instances.updateFromWebhook(instanceName, {
        status: mapped,
        phoneJid: phone,
        qrBase64: state === "open" ? null : undefined,
      });
      return { ok: true, event, state };
    }

    if (
      event === "MESSAGES_SET" ||
      event === "MESSAGES_UPSERT" ||
      event === "SEND_MESSAGE" ||
      event.includes("MESSAGES") ||
      event.includes("SEND_MESSAGE")
    ) {
      const result = await this.messages.ingestEvolutionPayload(
        instanceName,
        event,
        body.data,
      );
      return { ok: true, event, ...result };
    }

    if (event.includes("CHATS")) {
      // Chats are created lazily on message upsert; acknowledge.
      return { ok: true, event, ignored: true };
    }

    return { ok: true, event, ignored: true };
  }
}
