import { NextResponse } from "next/server";
import axios from "axios";
import { isIP } from "node:net";
import { z } from "zod";

export const dynamic = "force-dynamic";

const JOB_SECRET = (process.env.VIBEWORK_JOB_SECRET || process.env.CRON_SECRET || "").trim();
const DRY_RUN = process.env.A2A_LEAD_GEN_DRY_RUN !== "false";
const ENABLE_OUTBOUND_RPC = process.env.A2A_LEAD_GEN_ENABLE_OUTBOUND === "true";
const SELF_ORIGIN = new URL(process.env.NEXT_PUBLIC_APP_URL || "https://agent.wooo.work").origin;

const AgentCardSchema = z.object({
  agentId: z.string().optional(),
  agent_id: z.string().optional(),
  id: z.string().optional(),
  name: z.string().optional(),
  type: z.string().optional(),
  description: z.string().max(1000).optional(),
  capabilities: z.union([z.array(z.string()), z.record(z.unknown())]).optional(),
  skills: z.array(z.string()).optional(),
  rpc_endpoint: z.string().url().optional(),
  mcp_endpoint: z.string().url().optional(),
  contactEndpoints: z.record(z.unknown()).optional(),
  contact_endpoints: z.record(z.unknown()).optional(),
});

type SafeAgentCard = z.infer<typeof AgentCardSchema>;

function getConfiguredUrls(envName: string) {
  return (process.env[envName] || "")
    .split(",")
    .map((value) => value.trim())
    .filter(Boolean);
}

function isPrivateHost(hostname: string) {
  const normalized = hostname.trim().toLowerCase();
  if (
    normalized === "localhost" ||
    normalized.endsWith(".localhost") ||
    normalized.endsWith(".local") ||
    normalized.endsWith(".internal")
  ) {
    return true;
  }

  if (isIP(normalized) === 6) {
    return normalized === "::1" ||
      normalized.startsWith("fc") ||
      normalized.startsWith("fd") ||
      normalized.startsWith("fe80");
  }

  if (isIP(normalized) !== 4) {
    return false;
  }

  const [first = 0, second = 0] = normalized.split(".").map((part) => Number(part));
  return first === 10 ||
    first === 127 ||
    first === 0 ||
    (first === 169 && second === 254) ||
    (first === 172 && second >= 16 && second <= 31) ||
    (first === 192 && second === 168);
}

function parseSafeHttpsUrl(value: string) {
  const url = new URL(value);
  if (url.protocol !== "https:") {
    throw new Error("Only HTTPS agent-card URLs are allowed");
  }
  if (isPrivateHost(url.hostname)) {
    throw new Error("Private or local agent-card hosts are not allowed");
  }
  return url;
}

function getAllowedRpcOrigins() {
  return new Set(getConfiguredUrls("A2A_LEAD_GEN_ALLOWED_RPC_ORIGINS").map((value) => new URL(value).origin));
}

function isAllowedOutboundRpc(value: string | undefined, allowedOrigins: Set<string>) {
  if (!value || allowedOrigins.size === 0) {
    return false;
  }

  try {
    const url = parseSafeHttpsUrl(value);
    return url.origin !== SELF_ORIGIN && allowedOrigins.has(url.origin);
  } catch {
    return false;
  }
}

function extractCapabilities(card: SafeAgentCard) {
  if (Array.isArray(card.capabilities)) return card.capabilities;
  if (Array.isArray(card.skills)) return card.skills;
  return [];
}

function hasDevelopmentLeadSignal(card: SafeAgentCard) {
  const haystack = [
    card.name,
    card.type,
    card.description,
    ...extractCapabilities(card),
  ]
    .filter(Boolean)
    .join(" ")
    .toLowerCase();

  return ["outsourcing", "bounty", "developer", "smart-contract", "react", "mcp"].some((token) =>
    haystack.includes(token)
  );
}

export async function GET(request: Request) {
  const authHeader = request.headers.get("authorization");
  if (!JOB_SECRET || authHeader !== `Bearer ${JOB_SECRET}`) {
    console.warn("[A2A Lead Gen] Unauthorized cron request");
    return new NextResponse("Unauthorized", { status: 401 });
  }

  const configuredAgentCardUrls = getConfiguredUrls("A2A_LEAD_GEN_AGENT_CARD_URLS");
  if (configuredAgentCardUrls.length === 0) {
    return NextResponse.json({
      status: "skipped",
      reason: "A2A_LEAD_GEN_AGENT_CARD_URLS is empty",
      dryRun: DRY_RUN,
    });
  }

  const allowedRpcOrigins = getAllowedRpcOrigins();
  const leads = [];

  for (const rawUrl of configuredAgentCardUrls.slice(0, 25)) {
    try {
      const agentCardUrl = parseSafeHttpsUrl(rawUrl);
      const response = await axios.get(agentCardUrl.toString(), {
        timeout: 3000,
        maxRedirects: 0,
        responseType: "json",
        maxContentLength: 64 * 1024,
        validateStatus: (status) => status >= 200 && status < 300,
      });

      const card = AgentCardSchema.parse(response.data);
      const targetRpcUrl = card.rpc_endpoint || card.mcp_endpoint;
      const isLead = hasDevelopmentLeadSignal(card);
      const canSendOutboundRpc = ENABLE_OUTBOUND_RPC &&
        !DRY_RUN &&
        isLead &&
        isAllowedOutboundRpc(targetRpcUrl, allowedRpcOrigins);

      if (isLead) {
        leads.push({
          agentCardUrl: agentCardUrl.toString(),
          agentId: card.agentId || card.agent_id || card.id || "unknown",
          capabilities: extractCapabilities(card).slice(0, 20),
          rpcEndpoint: targetRpcUrl || null,
          outboundEligible: canSendOutboundRpc,
        });
      }

      if (canSendOutboundRpc && targetRpcUrl) {
        await axios.post(targetRpcUrl, {
          jsonrpc: "2.0",
          method: "a2a_propose_bounty",
          params: {
            title: "VibeWork integration review",
            description: "VibeWork detected an allowlisted A2A agent card and is requesting a scoped integration review.",
            budget_cents: 1000,
            origin_agent_id: "agent.wooo.work",
            required_capabilities: ["TypeScript", "MCP", "A2A"],
          },
          id: `lead-gen-${Date.now()}`,
        }, { timeout: 2000, maxRedirects: 0 });
      }
    } catch (error: unknown) {
      console.warn("[A2A Lead Gen] Dropped agent-card URL", {
        url: rawUrl,
        error: error instanceof Error ? error.message : "unknown",
      });
    }
  }

  return NextResponse.json({
    status: "success",
    dryRun: DRY_RUN,
    outboundRpcEnabled: ENABLE_OUTBOUND_RPC,
    agentsConfigured: configuredAgentCardUrls.length,
    leadsFound: leads.length,
    leads,
  });
}
