import type { IntegrationProvider, CardData, TestResult, PushResult, JsonValue } from "../types";
import { sendWebhook } from "@/lib/webhook";

interface WebhookConfig {
  url: string;
  secret: string;
}

function parseConfig(config: JsonValue): WebhookConfig {
  const c = config as Record<string, unknown>;
  return {
    url: (c.url as string) || "",
    secret: (c.secret as string) || "",
  };
}

export const webhookProvider: IntegrationProvider = {
  id: "webhook",
  name: "Webhook",
  description: "Send card data to any URL via HTTP POST",
  icon: "webhook",
  category: "webhook",
  supportsFieldMapping: false,
  supportsOAuth: false,
  configFields: [
    {
      key: "url",
      label: "Webhook URL",
      type: "url",
      required: true,
      placeholder: "https://example.com/webhook",
    },
    {
      key: "secret",
      label: "Signing Secret (optional)",
      type: "password",
      helpText: "Used to sign payloads with HMAC-SHA256",
    },
  ],

  setupGuide: {
    summary:
      "Webhooks let you POST card data to any URL when trigger events fire. Paste a URL that can receive JSON POSTs. Optionally add a signing secret so your endpoint can verify the request came from Echo OCR.",
    steps: [
      {
        title: "Build or choose an endpoint",
        body: "Any HTTPS URL that accepts POST requests with a JSON body will work. Common options: Zapier/Make webhooks, a serverless function, n8n, or your own backend route.",
      },
      {
        title: "Expect this payload shape",
        body: "Echo OCR POSTs { event: \"card_reviewed\" | \"ocr_complete\" | ..., data: { ...cardFields }, timestamp } as a JSON body. The Content-Type is application/json.",
      },
      {
        title: "(Optional) Add a signing secret",
        body: "If you provide a secret, Echo OCR computes an HMAC-SHA256 of the raw request body and sends it in the X-Echo-Signature header. Your endpoint can recompute the HMAC with the same secret to verify authenticity.",
      },
      {
        title: "Test the connection",
        body: "Click Test Connection to have Echo OCR POST a small { test: true } payload to your URL. Your endpoint should respond with a 2xx status.",
      },
      {
        title: "Pick trigger events",
        body: "On the integration's detail page, choose when webhooks fire — typically \"Card Reviewed\" or \"Card Exported\". Avoid firing on \"OCR Complete\" unless you explicitly want unreviewed data downstream.",
      },
    ],
  },

  async testConnection(config: JsonValue): Promise<TestResult> {
    try {
      const { url, secret } = parseConfig(config);
      if (!url) {
        return { success: false, message: "Webhook URL is required" };
      }
      const result = await sendWebhook(url, secret, "test", {
        test: true,
        timestamp: new Date().toISOString(),
      });
      if (result.ok) {
        return { success: true, message: `Webhook responded with ${result.status}` };
      }
      return { success: false, message: result.error || "Webhook failed" };
    } catch (err) {
      return {
        success: false,
        message: err instanceof Error ? err.message : "Connection failed",
      };
    }
  },

  async pushCard(
    card: CardData,
    config: JsonValue,
  ): Promise<PushResult> {
    try {
      const { url, secret } = parseConfig(config);
      const result = await sendWebhook(
        url,
        secret,
        "card_push",
        card as unknown as Record<string, unknown>
      );
      if (result.ok) {
        return { success: true, message: `Delivered (HTTP ${result.status})` };
      }
      return { success: false, message: result.error || "Delivery failed" };
    } catch (err) {
      return {
        success: false,
        message: err instanceof Error ? err.message : "Push failed",
      };
    }
  },
};
