import { decryptSecret } from "@/lib/ai/crypto";
import { createAdminClient } from "@/lib/supabase/admin";
import { getIntegrationEventLabel } from "@/lib/integrations/catalog";
import type { WebhookEventEnvelope } from "@/lib/developers/webhooks";
import type { IntegrationConnection } from "@/types";

function buildNotionChildren(envelope: WebhookEventEnvelope) {
  const prettyPayload = JSON.stringify(envelope.data, null, 2);

  return [
    {
      object: "block",
      type: "paragraph",
      paragraph: {
        rich_text: [
          {
            type: "text",
            text: {
              content: `${envelope.workspace.team_id ? "Team" : "Personal"} workspace · ${new Date(
                envelope.created_at
              ).toLocaleString()}`,
            },
          },
        ],
      },
    },
    {
      object: "block",
      type: "code",
      code: {
        language: "json",
        rich_text: [
          {
            type: "text",
            text: {
              content: prettyPayload.slice(0, 1800),
            },
          },
        ],
      },
    },
  ];
}

function buildNotionTitle(envelope: WebhookEventEnvelope) {
  for (const key of ["project", "task", "note", "event"] as const) {
    const value = envelope.data[key];
    if (value && typeof value === "object") {
      const record = value as Record<string, unknown>;
      const title =
        typeof record.name === "string"
          ? record.name
          : typeof record.title === "string"
            ? record.title
            : null;
      if (title && title.trim()) {
        return `${getIntegrationEventLabel(envelope.type)} · ${title.trim()}`;
      }
    }
  }

  return getIntegrationEventLabel(envelope.type);
}

export async function deliverNotionIntegrationEvent(
  admin: ReturnType<typeof createAdminClient>,
  connection: IntegrationConnection & { secret_encrypted: string },
  envelope: WebhookEventEnvelope
) {
  const token = decryptSecret(connection.secret_encrypted);
  const parentPageId =
    typeof connection.config.parentPageId === "string" ? connection.config.parentPageId : null;

  if (!parentPageId) {
    throw new Error("Notion parent page id missing");
  }

  let responseStatus: number | null = null;
  let responseBody: string | null = null;
  let success = false;

  try {
    const response = await fetch("https://api.notion.com/v1/pages", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
        "Notion-Version": "2022-06-28",
        "User-Agent": "Mindavio-Notion/1.0",
      },
      body: JSON.stringify({
        parent: {
          type: "page_id",
          page_id: parentPageId,
        },
        properties: {
          title: {
            title: [
              {
                type: "text",
                text: {
                  content: buildNotionTitle(envelope).slice(0, 1800),
                },
              },
            ],
          },
        },
        children: buildNotionChildren(envelope),
      }),
    });

    responseStatus = response.status;
    responseBody = (await response.text()).slice(0, 4000) || null;
    success = response.ok;
  } catch (error) {
    responseBody =
      error instanceof Error ? error.message.slice(0, 4000) : "Notion delivery failed";
  }

  await admin.from("integration_deliveries").insert({
    connection_id: connection.id,
    user_id: connection.user_id,
    team_id: connection.team_id,
    provider: connection.provider,
    event_type: envelope.type,
    payload: envelope,
    response_status: responseStatus,
    response_body: responseBody,
    success,
  });

  await admin
    .from("integration_connections")
    .update({
      last_delivery_at: new Date().toISOString(),
      last_response_status: responseStatus,
      last_error: success ? null : responseBody,
    })
    .eq("id", connection.id);
}
