// ============================================
// ACCOUNT MANAGEMENT TOOLS
// ============================================

import type { ToolDefinition, ToolResult, GoogleAdsClient } from "../types.js";
import { microsToMoney, 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 };
}

// ─── list_accessible_customers ──────────────────────────────────────
const listAccessibleCustomers: ToolDefinition = {
  name: "list_accessible_customers",
  description:
    "List all Google Ads customer accounts accessible with the current credentials. " +
    "Returns customer IDs that can be used with other tools. Useful for discovering " +
    "which accounts you can manage.",
  category: "accounts",
  annotations: {
    title: "List Accessible Customers",
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {},
  },
  _meta: {
    labels: {
      category: "accounts",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (_args: Record<string, any>, client: GoogleAdsClient): Promise<ToolResult> => {
    const customerIds = await client.listAccessibleCustomers();

    if (!customerIds.length) {
      return text("No accessible customer accounts found with the current credentials.");
    }

    const lines = customerIds.map((id, i) => `  ${i + 1}. \`${id}\``);
    const defaultId = client.getCustomerId();
    const defaultNote = defaultId ? `\n\n**Default customer ID:** \`${defaultId}\`` : "";

    return text(
      `## Accessible Customer Accounts\n\n` +
      `Found **${customerIds.length}** accessible account(s):\n\n` +
      `${lines.join("\n")}${defaultNote}\n\n` +
      `Use \`get_account_info\` with a customer ID to get details about a specific account.`
    );
  },
};

// ─── get_account_info ───────────────────────────────────────────────
const getAccountInfo: ToolDefinition = {
  name: "get_account_info",
  description:
    "Get detailed information about a Google Ads account including name, currency, " +
    "timezone, manager status, and account status.",
  category: "accounts",
  annotations: {
    title: "Get Account Info",
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Google Ads customer ID (e.g., '1234567890'). Uses default if not provided.",
      },
    },
  },
  _meta: {
    labels: {
      category: "accounts",
      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 query = `
      SELECT
        customer.id,
        customer.descriptive_name,
        customer.currency_code,
        customer.time_zone,
        customer.manager,
        customer.status
      FROM customer
    `;

    const results = await client.query(customerId, query);
    if (!results.length) return errorResult("No account data found for this customer ID.");

    const c = results[0].customer;

    return text(
      `## Account Info\n\n` +
      `| Field | Value |\n` +
      `|-------|-------|\n` +
      `| **Customer ID** | \`${c.id}\` |\n` +
      `| **Name** | ${c.descriptiveName || "—"} |\n` +
      `| **Currency** | ${c.currencyCode || "—"} |\n` +
      `| **Timezone** | ${c.timeZone || "—"} |\n` +
      `| **Manager Account** | ${c.manager ? "Yes" : "No"} |\n` +
      `| **Status** | ${c.status || "—"} |`
    );
  },
};

// ─── get_account_hierarchy ──────────────────────────────────────────
const getAccountHierarchy: ToolDefinition = {
  name: "get_account_hierarchy",
  description:
    "Get the manager-to-client account hierarchy tree. Shows all sub-accounts " +
    "under a manager account with their names, IDs, and status.",
  category: "accounts",
  annotations: {
    title: "Get Account Hierarchy",
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
  inputSchema: {
    type: "object",
    properties: {
      customer_id: {
        type: "string",
        description: "Manager account customer ID. Uses default if not provided.",
      },
    },
  },
  _meta: {
    labels: {
      category: "accounts",
      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 query = `
      SELECT
        customer_client.client_customer,
        customer_client.id,
        customer_client.descriptive_name,
        customer_client.currency_code,
        customer_client.time_zone,
        customer_client.manager,
        customer_client.level,
        customer_client.status,
        customer_client.hidden
      FROM customer_client
      ORDER BY customer_client.level ASC, customer_client.descriptive_name ASC
    `;

    const results = await client.query(customerId, query);
    if (!results.length) {
      return text("No client accounts found. This may not be a manager account.");
    }

    const header =
      `| Level | Customer ID | Name | Manager | Currency | Status | Hidden |\n` +
      `|-------|-------------|------|---------|----------|--------|--------|`;

    const rows = results.map((r: any) => {
      const cc = r.customerClient;
      const indent = "  ".repeat(cc.level || 0);
      return (
        `| ${cc.level ?? "—"} | \`${cc.id}\` | ${indent}${cc.descriptiveName || "—"} | ` +
        `${cc.manager ? "✅" : "—"} | ${cc.currencyCode || "—"} | ${cc.status || "—"} | ` +
        `${cc.hidden ? "Yes" : "No"} |`
      );
    });

    return text(
      `## Account Hierarchy for \`${customerId}\`\n\n` +
      `Found **${results.length}** account(s) in hierarchy.\n\n` +
      `${header}\n${rows.join("\n")}`
    );
  },
};

// ─── get_billing_info ───────────────────────────────────────────────
const getBillingInfo: ToolDefinition = {
  name: "get_billing_info",
  description:
    "Get billing setup information for a Google Ads account, including " +
    "billing status and payments account details.",
  category: "accounts",
  annotations: {
    title: "Get Billing Info",
    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.",
      },
    },
  },
  _meta: {
    labels: {
      category: "accounts",
      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 query = `
      SELECT
        billing_setup.id,
        billing_setup.status,
        billing_setup.payments_account,
        billing_setup.payments_account_info.payments_account_id,
        billing_setup.payments_account_info.payments_account_name,
        billing_setup.payments_account_info.payments_profile_id,
        billing_setup.payments_account_info.payments_profile_name
      FROM billing_setup
    `;

    const results = await client.query(customerId, query);
    if (!results.length) {
      return text("No billing setup found for this account.");
    }

    const sections = results.map((r: any, i: number) => {
      const bs = r.billingSetup;
      const info = bs.paymentsAccountInfo || {};
      return (
        `### Billing Setup ${i + 1}\n\n` +
        `| Field | Value |\n` +
        `|-------|-------|\n` +
        `| **Setup ID** | \`${bs.id}\` |\n` +
        `| **Status** | ${bs.status || "—"} |\n` +
        `| **Payments Account** | ${bs.paymentsAccount || "—"} |\n` +
        `| **Payments Account ID** | ${info.paymentsAccountId || "—"} |\n` +
        `| **Payments Account Name** | ${info.paymentsAccountName || "—"} |\n` +
        `| **Payments Profile ID** | ${info.paymentsProfileId || "—"} |\n` +
        `| **Payments Profile Name** | ${info.paymentsProfileName || "—"} |`
      );
    });

    return text(
      `## Billing Info for \`${customerId}\`\n\n` +
      `Found **${results.length}** billing setup(s).\n\n` +
      sections.join("\n\n")
    );
  },
};

// ─── get_account_budget ─────────────────────────────────────────────
const getAccountBudget: ToolDefinition = {
  name: "get_account_budget",
  description:
    "Get account-level budget information including approved and proposed budgets, " +
    "spending limits, and budget periods.",
  category: "accounts",
  annotations: {
    title: "Get Account Budget",
    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.",
      },
    },
  },
  _meta: {
    labels: {
      category: "accounts",
      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 query = `
      SELECT
        account_budget.id,
        account_budget.name,
        account_budget.status,
        account_budget.approved_start_date_time,
        account_budget.approved_end_date_time,
        account_budget.approved_spending_limit_micros,
        account_budget.approved_spending_limit_type,
        account_budget.proposed_start_date_time,
        account_budget.proposed_end_date_time,
        account_budget.proposed_spending_limit_micros,
        account_budget.proposed_spending_limit_type,
        account_budget.amount_served_micros,
        account_budget.billing_setup
      FROM account_budget
      ORDER BY account_budget.status ASC
    `;

    const results = await client.query(customerId, query);
    if (!results.length) {
      return text("No account budgets found for this account.");
    }

    const sections = results.map((r: any, i: number) => {
      const ab = r.accountBudget;

      const approvedLimit = ab.approvedSpendingLimitMicros
        ? `$${microsToMoney(ab.approvedSpendingLimitMicros)}`
        : ab.approvedSpendingLimitType || "—";

      const proposedLimit = ab.proposedSpendingLimitMicros
        ? `$${microsToMoney(ab.proposedSpendingLimitMicros)}`
        : ab.proposedSpendingLimitType || "—";

      const served = ab.amountServedMicros
        ? `$${microsToMoney(ab.amountServedMicros)}`
        : "—";

      return (
        `### Budget ${i + 1}: ${ab.name || "(unnamed)"}\n\n` +
        `| Field | Value |\n` +
        `|-------|-------|\n` +
        `| **Budget ID** | \`${ab.id}\` |\n` +
        `| **Status** | ${ab.status || "—"} |\n` +
        `| **Approved Start** | ${ab.approvedStartDateTime || "—"} |\n` +
        `| **Approved End** | ${ab.approvedEndDateTime || "—"} |\n` +
        `| **Approved Limit** | ${approvedLimit} |\n` +
        `| **Proposed Start** | ${ab.proposedStartDateTime || "—"} |\n` +
        `| **Proposed End** | ${ab.proposedEndDateTime || "—"} |\n` +
        `| **Proposed Limit** | ${proposedLimit} |\n` +
        `| **Amount Served** | ${served} |\n` +
        `| **Billing Setup** | ${ab.billingSetup || "—"} |`
      );
    });

    return text(
      `## Account Budgets for \`${customerId}\`\n\n` +
      `Found **${results.length}** budget(s).\n\n` +
      sections.join("\n\n")
    );
  },
};

// ─── Export ─────────────────────────────────────────────────────────
const tools: ToolDefinition[] = [
  listAccessibleCustomers,
  getAccountInfo,
  getAccountHierarchy,
  getBillingInfo,
  getAccountBudget,
];

export default tools;
