// ============================================
// CAMPAIGN MANAGEMENT TOOLS
// ============================================

import type { ToolDefinition, ToolResult, GoogleAdsClient } from "../types.js";
import { microsToMoney, formatPercent, formatNumber } from "../types.js";

function text(t: string): ToolResult {
  return { content: [{ type: "text", text: t }] };
}

function errorResult(msg: string): ToolResult {
  return { content: [{ type: "text", text: `❌ ${msg}` }], isError: true };
}

const DATE_RANGE_ENUM = [
  "TODAY", "YESTERDAY", "LAST_7_DAYS", "LAST_30_DAYS",
  "THIS_MONTH", "LAST_MONTH", "THIS_QUARTER", "LAST_QUARTER",
];

// ─── list_campaigns ─────────────────────────────────────────────────
const listCampaigns: ToolDefinition = {
  name: "list_campaigns",
  description:
    "List all campaigns in a Google Ads account with status, type, budget, and basic performance " +
    "metrics. Supports filtering by status and date range.",
  category: "campaigns",
  annotations: {
    title: "List Campaigns",
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      status: {
        type: "string",
        description: "Filter by campaign status.",
        enum: ["ENABLED", "PAUSED", "REMOVED", "ALL"],
        default: "ALL",
      },
      date_range: {
        type: "string",
        description: "Date range for metrics.",
        enum: DATE_RANGE_ENUM,
        default: "LAST_30_DAYS",
      },
      limit: {
        type: "number",
        description: "Max number of campaigns to return (default 50).",
        default: 50,
      },
    },
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const status = args.status || "ALL";
    const dateRange = args.date_range || "LAST_30_DAYS";
    const limit = args.limit || 50;

    const conditions: string[] = [];
    if (status !== "ALL") {
      conditions.push(`campaign.status = '${status}'`);
    }
    conditions.push(`segments.date DURING ${dateRange}`);

    const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";

    const query = `
      SELECT
        campaign.id,
        campaign.name,
        campaign.status,
        campaign.advertising_channel_type,
        campaign.bidding_strategy_type,
        campaign_budget.amount_micros,
        metrics.impressions,
        metrics.clicks,
        metrics.cost_micros,
        metrics.conversions,
        metrics.ctr
      FROM campaign
      ${where}
      ORDER BY metrics.cost_micros DESC
      LIMIT ${limit}
    `;

    const results = await client.query(customerId, query);
    if (!results.length) {
      return text(`No campaigns found${status !== "ALL" ? ` with status ${status}` : ""} for the ${dateRange} period.`);
    }

    const header =
      `| Campaign | Status | Type | Daily Budget | Impressions | Clicks | Cost | Conv. | CTR |\n` +
      `|----------|--------|------|-------------|-------------|--------|------|-------|-----|`;

    const rows = results.map((r: any) => {
      const c = r.campaign;
      const m = r.metrics || {};
      const budget = r.campaignBudget?.amountMicros
        ? `$${microsToMoney(r.campaignBudget.amountMicros)}`
        : "—";
      return (
        `| ${c.name || "—"} | ${c.status} | ${c.advertisingChannelType || "—"} | ${budget} | ` +
        `${formatNumber(m.impressions || 0)} | ${formatNumber(m.clicks || 0)} | ` +
        `$${microsToMoney(m.costMicros || 0)} | ${Number(m.conversions || 0).toFixed(1)} | ` +
        `${formatPercent(m.ctr || 0)} |`
      );
    });

    return text(
      `## Campaigns — \`${customerId}\`\n\n` +
      `**Date range:** ${dateRange} · **Filter:** ${status} · **Showing:** ${results.length} campaign(s)\n\n` +
      `${header}\n${rows.join("\n")}`
    );
  },
};

// ─── get_campaign ───────────────────────────────────────────────────
const getCampaign: ToolDefinition = {
  name: "get_campaign",
  description:
    "Get full details for a single campaign by ID, including settings, bidding, budget, and recent metrics.",
  category: "campaigns",
  annotations: {
    title: "Get Campaign Details",
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "The campaign ID to retrieve.",
      },
      date_range: {
        type: "string",
        description: "Date range for metrics.",
        enum: DATE_RANGE_ENUM,
        default: "LAST_30_DAYS",
      },
    },
    required: ["campaign_id"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const dateRange = args.date_range || "LAST_30_DAYS";

    const query = `
      SELECT
        campaign.id,
        campaign.name,
        campaign.status,
        campaign.advertising_channel_type,
        campaign.advertising_channel_sub_type,
        campaign.bidding_strategy_type,
        campaign.start_date,
        campaign.end_date,
        campaign.serving_status,
        campaign.network_settings.target_google_search,
        campaign.network_settings.target_search_network,
        campaign.network_settings.target_content_network,
        campaign_budget.amount_micros,
        campaign_budget.delivery_method,
        campaign_budget.total_amount_micros,
        metrics.impressions,
        metrics.clicks,
        metrics.cost_micros,
        metrics.conversions,
        metrics.conversions_value,
        metrics.ctr,
        metrics.average_cpc,
        metrics.average_cpm
      FROM campaign
      WHERE campaign.id = ${args.campaign_id}
        AND segments.date DURING ${dateRange}
    `;

    const results = await client.query(customerId, query);
    if (!results.length) return errorResult(`Campaign ${args.campaign_id} not found.`);

    const c = results[0].campaign;
    const m = results[0].metrics || {};
    const b = results[0].campaignBudget || {};
    const net = c.networkSettings || {};

    const budget = b.amountMicros ? `$${microsToMoney(b.amountMicros)}/day` : "—";
    const totalBudget = b.totalAmountMicros ? `$${microsToMoney(b.totalAmountMicros)}` : "—";

    return text(
      `## Campaign: ${c.name}\n\n` +
      `### Settings\n\n` +
      `| Field | Value |\n` +
      `|-------|-------|\n` +
      `| **Campaign ID** | \`${c.id}\` |\n` +
      `| **Status** | ${c.status} |\n` +
      `| **Serving Status** | ${c.servingStatus || "—"} |\n` +
      `| **Channel Type** | ${c.advertisingChannelType || "—"} |\n` +
      `| **Channel Sub-Type** | ${c.advertisingChannelSubType || "—"} |\n` +
      `| **Bidding Strategy** | ${c.biddingStrategyType || "—"} |\n` +
      `| **Start Date** | ${c.startDate || "—"} |\n` +
      `| **End Date** | ${c.endDate || "—"} |\n` +
      `| **Daily Budget** | ${budget} |\n` +
      `| **Total Budget** | ${totalBudget} |\n` +
      `| **Delivery Method** | ${b.deliveryMethod || "—"} |\n\n` +
      `### Network Settings\n\n` +
      `| Network | Enabled |\n` +
      `|---------|---------|\n` +
      `| Google Search | ${net.targetGoogleSearch ? "✅" : "❌"} |\n` +
      `| Search Network | ${net.targetSearchNetwork ? "✅" : "❌"} |\n` +
      `| Content Network | ${net.targetContentNetwork ? "✅" : "❌"} |\n\n` +
      `### Performance (${dateRange})\n\n` +
      `| Metric | Value |\n` +
      `|--------|-------|\n` +
      `| **Impressions** | ${formatNumber(m.impressions || 0)} |\n` +
      `| **Clicks** | ${formatNumber(m.clicks || 0)} |\n` +
      `| **CTR** | ${formatPercent(m.ctr || 0)} |\n` +
      `| **Cost** | $${microsToMoney(m.costMicros || 0)} |\n` +
      `| **Avg. CPC** | $${microsToMoney(m.averageCpc || 0)} |\n` +
      `| **Avg. CPM** | $${microsToMoney(m.averageCpm || 0)} |\n` +
      `| **Conversions** | ${Number(m.conversions || 0).toFixed(1)} |\n` +
      `| **Conv. Value** | $${Number(m.conversionsValue || 0).toFixed(2)} |`
    );
  },
};

// ─── create_campaign ────────────────────────────────────────────────
const createCampaign: ToolDefinition = {
  name: "create_campaign",
  description:
    "⚠️ DESTRUCTIVE: Create a new Google Ads campaign. This will create a campaign budget and " +
    "the campaign itself. The campaign starts in PAUSED status by default for safety. " +
    "Review carefully before enabling.",
  category: "campaigns",
  annotations: {
    title: "Create Campaign",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: false,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      name: {
        type: "string",
        description: "Campaign name.",
      },
      channel_type: {
        type: "string",
        description: "Advertising channel type.",
        enum: ["SEARCH", "DISPLAY", "PERFORMANCE_MAX", "SHOPPING", "VIDEO"],
      },
      bidding_strategy: {
        type: "string",
        description: "Bidding strategy type.",
        enum: [
          "MANUAL_CPC", "MAXIMIZE_CLICKS", "MAXIMIZE_CONVERSIONS",
          "MAXIMIZE_CONVERSION_VALUE", "TARGET_CPA", "TARGET_ROAS", "TARGET_SPEND",
        ],
      },
      budget_amount_per_day: {
        type: "number",
        description: "Daily budget in account currency (e.g., 50.00 for $50/day).",
      },
      start_date: {
        type: "string",
        description: "Campaign start date in YYYY-MM-DD format. Defaults to today.",
      },
      status: {
        type: "string",
        description: "Initial campaign status. Default PAUSED for safety.",
        enum: ["ENABLED", "PAUSED"],
        default: "PAUSED",
      },
    },
    required: ["name", "channel_type", "bidding_strategy", "budget_amount_per_day"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const budgetMicros = Math.round(args.budget_amount_per_day * 1_000_000);
    const tempId = `-1`; // Temporary ID for the budget, referenced by campaign

    const budgetOp = {
      entity: "campaignBudget",
      operation: "create" as const,
      resource: {
        name: `${args.name} Budget`,
        amountMicros: budgetMicros.toString(),
        deliveryMethod: "STANDARD",
        explicitlyShared: false,
      },
    };

    const campaignResource: Record<string, any> = {
      name: args.name,
      advertisingChannelType: args.channel_type,
      status: args.status || "PAUSED",
      campaignBudget: `customers/${customerId}/campaignBudgets/${tempId}`,
    };

    // Map bidding strategy to the correct field
    const biddingMap: Record<string, any> = {
      MANUAL_CPC: { manualCpc: { enhancedCpcEnabled: false } },
      MAXIMIZE_CLICKS: { maximizeClicks: {} },
      MAXIMIZE_CONVERSIONS: { maximizeConversions: {} },
      MAXIMIZE_CONVERSION_VALUE: { maximizeConversionValue: {} },
      TARGET_CPA: { targetCpa: {} },
      TARGET_ROAS: { targetRoas: {} },
      TARGET_SPEND: { targetSpend: {} },
    };

    const biddingConfig = biddingMap[args.bidding_strategy];
    if (biddingConfig) {
      Object.assign(campaignResource, biddingConfig);
    }

    if (args.start_date) {
      campaignResource.startDate = args.start_date.replace(/-/g, "");
    }

    // Network settings for Search campaigns
    if (args.channel_type === "SEARCH") {
      campaignResource.networkSettings = {
        targetGoogleSearch: true,
        targetSearchNetwork: true,
        targetContentNetwork: false,
      };
    }

    const campaignOp = {
      entity: "campaign",
      operation: "create" as const,
      resource: campaignResource,
    };

    const result = await client.mutate(customerId, [budgetOp, campaignOp]);

    const mutateResults = result.mutateOperationResponses || [];
    const campaignRn = mutateResults[1]?.campaignResult?.resourceName || "unknown";

    return text(
      `## ✅ Campaign Created\n\n` +
      `| Field | Value |\n` +
      `|-------|-------|\n` +
      `| **Name** | ${args.name} |\n` +
      `| **Channel** | ${args.channel_type} |\n` +
      `| **Bidding** | ${args.bidding_strategy} |\n` +
      `| **Daily Budget** | $${args.budget_amount_per_day.toFixed(2)} |\n` +
      `| **Status** | ${args.status || "PAUSED"} |\n` +
      `| **Resource** | \`${campaignRn}\` |\n\n` +
      `${(args.status || "PAUSED") === "PAUSED" ? "ℹ️ Campaign created in **PAUSED** status. Use `enable_campaign` to activate it." : "⚡ Campaign is **ENABLED** and will start serving ads."}`
    );
  },
};

// ─── update_campaign ────────────────────────────────────────────────
const updateCampaign: ToolDefinition = {
  name: "update_campaign",
  description:
    "⚠️ DESTRUCTIVE: Update campaign settings such as name, bidding strategy, start/end dates, " +
    "and network settings. Only specified fields will be updated.",
  category: "campaigns",
  annotations: {
    title: "Update Campaign",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "Campaign ID to update.",
      },
      name: {
        type: "string",
        description: "New campaign name.",
      },
      bidding_strategy: {
        type: "string",
        description: "New bidding strategy.",
        enum: [
          "MANUAL_CPC", "MAXIMIZE_CLICKS", "MAXIMIZE_CONVERSIONS",
          "MAXIMIZE_CONVERSION_VALUE", "TARGET_CPA", "TARGET_ROAS", "TARGET_SPEND",
        ],
      },
      start_date: {
        type: "string",
        description: "New start date (YYYY-MM-DD).",
      },
      end_date: {
        type: "string",
        description: "New end date (YYYY-MM-DD).",
      },
    },
    required: ["campaign_id"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const resourceName = `customers/${customerId}/campaigns/${args.campaign_id}`;
    const resource: Record<string, any> = { resourceName };
    const updateFields: string[] = [];

    if (args.name) {
      resource.name = args.name;
      updateFields.push("name");
    }
    if (args.start_date) {
      resource.startDate = args.start_date.replace(/-/g, "");
      updateFields.push("start_date");
    }
    if (args.end_date) {
      resource.endDate = args.end_date.replace(/-/g, "");
      updateFields.push("end_date");
    }
    if (args.bidding_strategy) {
      const biddingMap: Record<string, [string, any]> = {
        MANUAL_CPC: ["manual_cpc", { enhancedCpcEnabled: false }],
        MAXIMIZE_CLICKS: ["maximize_clicks", {}],
        MAXIMIZE_CONVERSIONS: ["maximize_conversions", {}],
        MAXIMIZE_CONVERSION_VALUE: ["maximize_conversion_value", {}],
        TARGET_CPA: ["target_cpa", {}],
        TARGET_ROAS: ["target_roas", {}],
        TARGET_SPEND: ["target_spend", {}],
      };
      const [field, config] = biddingMap[args.bidding_strategy];
      resource[field.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())] = config;
      updateFields.push(field);
    }

    if (!updateFields.length) {
      return errorResult("No fields to update. Provide at least one field (name, bidding_strategy, start_date, end_date).");
    }

    await client.mutate(customerId, [
      {
        entity: "campaign",
        operation: "update",
        resource,
        updateMask: updateFields.join(","),
      },
    ]);

    return text(
      `## ✅ Campaign Updated\n\n` +
      `**Campaign ID:** \`${args.campaign_id}\`\n` +
      `**Fields updated:** ${updateFields.join(", ")}\n\n` +
      updateFields.map((f) => `- **${f}** → ${args[f.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())] || args[f] || "updated"}`).join("\n")
    );
  },
};

// ─── pause_campaign ─────────────────────────────────────────────────
const pauseCampaign: ToolDefinition = {
  name: "pause_campaign",
  description:
    "⚠️ DESTRUCTIVE: Pause a campaign by setting its status to PAUSED. " +
    "The campaign will stop serving ads immediately. Safe to call on already-paused campaigns.",
  category: "campaigns",
  annotations: {
    title: "Pause Campaign",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "Campaign ID to pause.",
      },
    },
    required: ["campaign_id"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const resourceName = `customers/${customerId}/campaigns/${args.campaign_id}`;

    await client.mutate(customerId, [
      {
        entity: "campaign",
        operation: "update",
        resource: { resourceName, status: "PAUSED" },
        updateMask: "status",
      },
    ]);

    return text(
      `## ⏸️ Campaign Paused\n\n` +
      `**Campaign ID:** \`${args.campaign_id}\`\n` +
      `**Status:** PAUSED\n\n` +
      `The campaign has stopped serving ads. Use \`enable_campaign\` to resume.`
    );
  },
};

// ─── enable_campaign ────────────────────────────────────────────────
const enableCampaign: ToolDefinition = {
  name: "enable_campaign",
  description:
    "⚠️ DESTRUCTIVE: Enable a paused campaign by setting its status to ENABLED. " +
    "The campaign will begin serving ads. Safe to call on already-enabled campaigns.",
  category: "campaigns",
  annotations: {
    title: "Enable Campaign",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "Campaign ID to enable.",
      },
    },
    required: ["campaign_id"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const resourceName = `customers/${customerId}/campaigns/${args.campaign_id}`;

    await client.mutate(customerId, [
      {
        entity: "campaign",
        operation: "update",
        resource: { resourceName, status: "ENABLED" },
        updateMask: "status",
      },
    ]);

    return text(
      `## ▶️ Campaign Enabled\n\n` +
      `**Campaign ID:** \`${args.campaign_id}\`\n` +
      `**Status:** ENABLED\n\n` +
      `The campaign is now active and will serve ads based on its settings, budget, and targeting.`
    );
  },
};

// ─── remove_campaign ────────────────────────────────────────────────
const removeCampaign: ToolDefinition = {
  name: "remove_campaign",
  description:
    "⚠️ DESTRUCTIVE & IRREVERSIBLE: Remove a campaign. This sets the campaign to REMOVED status. " +
    "Removed campaigns cannot be re-enabled. All ads in the campaign will stop serving. " +
    "Historical data is preserved but the campaign cannot be reused.",
  category: "campaigns",
  annotations: {
    title: "Remove Campaign",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: false,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "Campaign ID to remove.",
      },
    },
    required: ["campaign_id"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    const resourceName = `customers/${customerId}/campaigns/${args.campaign_id}`;

    await client.mutate(customerId, [
      {
        entity: "campaign",
        operation: "remove",
        resourceName,
      },
    ]);

    return text(
      `## 🗑️ Campaign Removed\n\n` +
      `**Campaign ID:** \`${args.campaign_id}\`\n` +
      `**Status:** REMOVED\n\n` +
      `⚠️ This action is **irreversible**. The campaign and its ads have stopped serving.\n` +
      `Historical performance data remains accessible through reporting tools.`
    );
  },
};

// ─── update_campaign_budget ─────────────────────────────────────────
const updateCampaignBudget: ToolDefinition = {
  name: "update_campaign_budget",
  description:
    "⚠️ DESTRUCTIVE: Change the daily budget for a campaign. Specify the new amount in " +
    "account currency (e.g., 100.00 for $100/day). The change takes effect immediately.",
  category: "campaigns",
  annotations: {
    title: "Update Campaign Budget",
    readOnlyHint: false,
    destructiveHint: true,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID. Uses default if not provided.",
      },
      campaign_id: {
        type: "string",
        description: "Campaign ID whose budget to update.",
      },
      new_budget_amount: {
        type: "number",
        description: "New daily budget in account currency (e.g., 50.00 for $50/day).",
      },
    },
    required: ["campaign_id", "new_budget_amount"],
  },
  _meta: {
    labels: {
      category: "campaigns",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerId = args.customer_id || client.getCustomerId();
    if (!customerId) return errorResult("No customer ID provided and no default configured.");

    // First, get the campaign's budget resource name
    const query = `
      SELECT campaign.id, campaign.name, campaign_budget.resource_name, campaign_budget.amount_micros
      FROM campaign
      WHERE campaign.id = ${args.campaign_id}
    `;

    const results = await client.query(customerId, query);
    if (!results.length) return errorResult(`Campaign ${args.campaign_id} not found.`);

    const campaign = results[0].campaign;
    const budgetRn = results[0].campaignBudget?.resourceName;
    const oldBudgetMicros = results[0].campaignBudget?.amountMicros || "0";

    if (!budgetRn) return errorResult("Could not find budget resource for this campaign.");

    const newBudgetMicros = Math.round(args.new_budget_amount * 1_000_000);

    await client.mutate(customerId, [
      {
        entity: "campaignBudget",
        operation: "update",
        resource: {
          resourceName: budgetRn,
          amountMicros: newBudgetMicros.toString(),
        },
        updateMask: "amount_micros",
      },
    ]);

    return text(
      `## 💰 Budget Updated\n\n` +
      `**Campaign:** ${campaign.name} (\`${args.campaign_id}\`)\n\n` +
      `| | Amount |\n` +
      `|---|--------|\n` +
      `| **Previous Budget** | $${microsToMoney(oldBudgetMicros)}/day |\n` +
      `| **New Budget** | $${args.new_budget_amount.toFixed(2)}/day |\n` +
      `| **Change** | ${args.new_budget_amount > Number(oldBudgetMicros) / 1_000_000 ? "📈" : "📉"} ${((args.new_budget_amount / (Number(oldBudgetMicros) / 1_000_000) - 1) * 100).toFixed(1)}% |\n\n` +
      `The new budget takes effect immediately.`
    );
  },
};

// ─── Export ─────────────────────────────────────────────────────────
const tools: ToolDefinition[] = [
  listCampaigns,
  getCampaign,
  createCampaign,
  updateCampaign,
  pauseCampaign,
  enableCampaign,
  removeCampaign,
  updateCampaignBudget,
];

export default tools;
