import type { IntegrationManifest } from "../manifest/schema.js";

export const quickbooksManifest: IntegrationManifest = {
  id: "quickbooks-online",
  version: "1.0.0",
  name: "QuickBooks Online",
  description: "Sync customers, post invoices when quotes are awarded, look up items and accounts.",
  category: "accounting",
  vendor: "Intuit",
  source: "builtin",
  homepage: "https://quickbooks.intuit.com",
  docsUrl: "https://developer.intuit.com/app/developer/qbo/docs/develop",
  icon: "QuickBooks",
  tags: ["accounting", "invoicing", "oauth"],
  connection: {
    baseUrl: "https://quickbooks.api.intuit.com/v3/company/{{config.realmId}}",
    allowedHosts: ["quickbooks.api.intuit.com", "appcenter.intuit.com", "oauth.platform.intuit.com"],
    auth: {
      type: "oauth2",
      flow: "authorization_code",
      authUrl: "https://appcenter.intuit.com/connect/oauth2",
      tokenUrl: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer",
      scopes: ["com.intuit.quickbooks.accounting"],
      scopeSeparator: " ",
      tokenPlacement: "header",
      tokenParamName: "Authorization",
      tokenPrefix: "Bearer ",
      pkce: false,
      extraAuthParams: {},
      extraTokenParams: {},
      tokenRequestStyle: "form",
    },
    fields: [
      {
        key: "realmId",
        label: "Realm ID (Company ID)",
        type: "string",
        required: true,
        helpText: "Returned by Intuit on the OAuth callback. Auto-populated after the first connect.",
      },
      {
        key: "environment",
        label: "Environment",
        type: "select",
        default: "production",
        options: [
          { value: "production", label: "Production" },
          { value: "sandbox", label: "Sandbox" },
        ],
      },
    ],
    test: { method: "GET", path: "/companyinfo/{{config.realmId}}", expectStatus: [200], headers: {} },
  },
  capabilities: {
    actions: [
      {
        id: "find_customer",
        name: "Find customer by display name",
        description: "Lookup a QuickBooks customer by display name.",
        input: [{ name: "displayName", type: "string", description: "Customer display name", required: true }],
        output: { select: "$.QueryResponse.Customer[0]" },
        request: {
          method: "GET",
          path: "/query",
          query: { query: "select * from Customer where DisplayName = '{{input.displayName}}'", minorversion: "70" },
          headers: { Accept: "application/json" },
          body: undefined,
          bodyEncoding: "none",
          timeoutMs: 30_000,
          retry: { maxAttempts: 3, initialDelayMs: 500, backoff: "exponential", retryOnStatus: [408, 429, 500, 502, 503, 504] },
        },
        mutates: false,
        requiresConfirmation: false,
        tags: ["read"],
      },
      {
        id: "create_invoice",
        name: "Create invoice",
        description: "Create a QuickBooks invoice — typically called when a Bidwright quote is awarded.",
        input: [
          { name: "customerId", type: "string", description: "QuickBooks Customer Id", required: true },
          { name: "lineItems", type: "array", description: "Array of { description, amount, qty? }", required: true },
        ],
        output: { select: "$.Invoice", map: { id: "$.Invoice.Id", docNumber: "$.Invoice.DocNumber" } },
        request: {
          method: "POST",
          path: "/invoice",
          query: { minorversion: "70" },
          headers: {},
          body: {
            CustomerRef: { value: "{{input.customerId}}" },
            Line: "{{input.lineItems}}",
          },
          bodyEncoding: "json",
          timeoutMs: 30_000,
          retry: { maxAttempts: 3, initialDelayMs: 500, backoff: "exponential", retryOnStatus: [408, 429, 500, 502, 503, 504] },
        },
        mutates: true,
        requiresConfirmation: true,
        tags: ["invoice", "write"],
      },
    ],
    triggers: [],
    syncs: [
      {
        id: "customers",
        name: "Customers",
        description: "Pull QuickBooks customers into ExternalRecord for mapping to Bidwright Customer rows.",
        direction: "pull",
        schedule: "0 */12 * * *",
        request: {
          method: "GET",
          path: "/query",
          query: {
            query: "select * from Customer startposition {{cursor}} maxresults 100",
            minorversion: "70",
          },
          headers: { Accept: "application/json" },
          body: undefined,
          bodyEncoding: "none",
          timeoutMs: 30_000,
          retry: { maxAttempts: 3, initialDelayMs: 500, backoff: "exponential", retryOnStatus: [408, 429, 500, 502, 503, 504] },
        },
        recordsPath: "$.QueryResponse.Customer",
        externalIdPath: "$.Id",
        mapping: {
          name: "$.DisplayName",
          email: "$.PrimaryEmailAddr.Address",
          phone: "$.PrimaryPhone.FreeFormNumber",
        },
        target: "Customer",
      },
    ],
  },
  ui: { sections: [] },
};
