// Connection seeds: idempotent seeding of the marketplace `connection` kind.
//
// A connection is a service the user pairs once and reuses across many tools
// (e.g. one Anthropic key powers any Anthropic-engine agent; one GitHub token
// unlocks 11 gh_* tools). Connections live in `marketplace_items` (kind =
// 'connection') with their setup contract serialized into manifest_json.
//
// Setup kinds:
//   - api_key       — collect one or more passwords, verify with provider
//   - oauth2        — "Sign in with…" authorization-code flow (tokens in vault)
//   - qr_pair       — WhatsApp pairing through the Baileys bridge daemon
//   - binary_detect — local binary / directory probe (Hermes)
//
// OAuth2 connections never embed a secret: the operator's app client id/secret
// are collected once as `api_key`-style fields and referenced from the vault by
// name (`*_ref`); the minted access/refresh tokens land in `*_ACCESS_TOKEN` /
// `*_REFRESH_TOKEN`. A declarative `health_check` block gives them a generic
// "Test connection" through verifyViaHealthCheck — no per-service route code.

/**
 * Build an OAuth2 business-connection seed from a compact descriptor. Keeps the
 * (verbose, security-sensitive) manifest shape consistent across every provider.
 */
function oauthConnectionSeed({
  slug, title, description, category = 'integration', provider, scopes,
  prefix, extraCredentials = [], unlocks, healthEndpoint, risk, tags,
}) {
  const accessRef = `${prefix}_ACCESS_TOKEN`;
  return {
    slug,
    title,
    description,
    category,
    author: 'madarx',
    source_kind: 'builtin',
    source_url: null,
    version: null,
    risk_summary: risk,
    tags,
    manifest: {
      service_key: slug,
      setup_kind: 'oauth2',
      benefit: `Sign in with ${title} to unlock ${unlocks.length} tool${unlocks.length === 1 ? '' : 's'}. No code, no .env editing.`,
      // Operator app credentials, supplied once. Referenced by the oauth block via *_ref.
      credentials: [
        { name: `${prefix}_CLIENT_ID`, label: `${title} client ID`, type: 'text', required: true, help_text: `Create an app on the ${title} developer console and paste its client ID.` },
        { name: `${prefix}_CLIENT_SECRET`, label: `${title} client secret`, type: 'password', required: true, help_text: 'Stored encrypted in the local vault — never echoed back.' },
        ...extraCredentials,
      ],
      oauth: {
        provider,
        scopes,
        pkce: provider === 'google' || provider === 'tiktok',
        redirect_path: `/api/connections/${slug}/oauth/callback`,
        client_id_ref: `${prefix}_CLIENT_ID`,
        client_secret_ref: `${prefix}_CLIENT_SECRET`,
        access_token_ref: accessRef,
        refresh_token_ref: `${prefix}_REFRESH_TOKEN`,
      },
      health_check: {
        endpoint: healthEndpoint,
        method: 'GET',
        expect_status: 200,
        auth: { in: 'header', name: 'Authorization', prefix: 'Bearer ', credential: accessRef },
      },
      verify_endpoint: `/api/connections/${slug}/verify`,
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: unlocks,
      engines: [],
      logo_glyph: slug,
    },
  };
}

const CONNECTION_SEEDS = [
  {
    slug: 'anthropic',
    title: 'Anthropic',
    description:
      'Power any agent running on the Anthropic engine (Claude Opus, Sonnet, Haiku). Your key is encrypted on this Mac and never leaves the vault.',
    category: 'engine',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://console.anthropic.com/settings/keys',
    version: null,
    risk_summary: 'API key only — no destructive scope.',
    tags: ['engine', 'anthropic', 'claude'],
    manifest: {
      service_key: 'anthropic',
      setup_kind: 'api_key',
      benefit:
        'Unlock the Anthropic engine for sub-agents and the main agent. Required for /api/orchestrator/command on default mode.',
      credentials: [
        {
          name: 'ANTHROPIC_API_KEY',
          label: 'API key',
          type: 'password',
          placeholder: 'sk-ant-…',
          help_url: 'https://console.anthropic.com/settings/keys',
          help_text: 'Generate a key in the Anthropic console.',
          required: true,
        },
      ],
      verify_endpoint: '/api/connections/anthropic/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [],
      engines: ['anthropic'],
      logo_glyph: 'anthropic',
    },
  },
  {
    slug: 'openai',
    title: 'OpenAI',
    description:
      'Use OpenAI models for agents that prefer GPT. Stored encrypted; never echoed back.',
    category: 'engine',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://platform.openai.com/api-keys',
    version: null,
    risk_summary: 'API key only.',
    tags: ['engine', 'openai', 'gpt'],
    manifest: {
      service_key: 'openai',
      setup_kind: 'api_key',
      benefit: 'Unlock OpenAI models for agents and transcription.',
      credentials: [
        {
          name: 'OPENAI_API_KEY',
          label: 'API key',
          type: 'password',
          placeholder: 'sk-…',
          help_url: 'https://platform.openai.com/api-keys',
          help_text: 'Create a key in the OpenAI dashboard.',
          required: true,
        },
      ],
      verify_endpoint: '/api/connections/openai/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [],
      engines: ['openai'],
      logo_glyph: 'openai',
    },
  },
  {
    slug: 'kimi',
    title: 'Kimi (Moonshot)',
    description:
      'Connect Moonshot AI — Kimi models for long-context Chinese + English reasoning. Stored encrypted.',
    category: 'engine',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://platform.moonshot.ai/console/api-keys',
    version: null,
    risk_summary: 'API key only.',
    tags: ['engine', 'kimi', 'moonshot'],
    manifest: {
      service_key: 'kimi',
      setup_kind: 'api_key',
      benefit: 'Unlock Kimi (Moonshot) models for the kimi engine.',
      credentials: [
        {
          name: 'KIMI_API_KEY',
          label: 'API key',
          type: 'password',
          placeholder: 'sk-…',
          help_url: 'https://platform.moonshot.ai/console/api-keys',
          help_text: 'Create a key in the Moonshot console.',
          required: true,
        },
      ],
      verify_endpoint: '/api/connections/kimi/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [],
      engines: ['kimi'],
      logo_glyph: 'kimi',
    },
  },
  {
    slug: 'github',
    title: 'GitHub',
    description:
      'Unlock 11 GitHub tools: read repos, list PRs, create issues, dispatch workflows, and (with approval) merge PRs. Token is encrypted at rest.',
    category: 'integration',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://github.com/settings/tokens',
    version: null,
    risk_summary: 'Some GitHub tools are irreversible (e.g. gh_pr_merge) and always require approval.',
    tags: ['integration', 'github', 'git'],
    manifest: {
      service_key: 'github',
      setup_kind: 'api_key',
      benefit: 'Unlock 11 GitHub tools across read, issue, and PR workflows.',
      credentials: [
        {
          name: 'GITHUB_TOKEN',
          label: 'Personal access token',
          type: 'password',
          placeholder: 'ghp_…',
          help_url: 'https://github.com/settings/tokens',
          help_text: 'Use a fine-grained token. Grant only the scopes you need.',
          required: true,
        },
      ],
      verify_endpoint: '/api/connections/github/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [
        'gh_repo_read',
        'gh_repo_list',
        'gh_issue_list',
        'gh_issue_create',
        'gh_issue_comment',
        'gh_pr_list',
        'gh_pr_create',
        'gh_pr_comment',
        'gh_pr_merge',
        'gh_actions_dispatch',
        'gh_release_create',
      ],
      engines: [],
      logo_glyph: 'github',
    },
  },
  {
    slug: 'resend',
    title: 'Resend',
    description:
      'Send transactional email. A default recipient_domain allowlist is seeded from git config user.email — add more in the marketplace afterwards.',
    category: 'integration',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://resend.com/api-keys',
    version: null,
    risk_summary: 'email_send is irreversible and always requires approval.',
    tags: ['integration', 'email', 'resend'],
    manifest: {
      service_key: 'resend',
      setup_kind: 'api_key',
      benefit: 'Unlock email_send and email_status_lookup for transactional email.',
      credentials: [
        {
          name: 'RESEND_API_KEY',
          label: 'API key',
          type: 'password',
          placeholder: 're_…',
          help_url: 'https://resend.com/api-keys',
          help_text: 'Create a Resend API key.',
          required: true,
        },
        {
          name: 'RESEND_FROM_EMAIL',
          label: 'From email',
          type: 'text',
          placeholder: 'agent@yourdomain.com',
          help_url: 'https://resend.com/domains',
          help_text: 'A verified sender address on a verified Resend domain.',
          required: true,
        },
      ],
      verify_endpoint: '/api/connections/resend/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: ['email_send', 'email_status_lookup'],
      engines: [],
      logo_glyph: 'resend',
    },
  },
  {
    slug: 'supabase',
    title: 'Supabase',
    description:
      'Connect a Supabase project. Service role key bypasses RLS — destructive ops (supabase_rest_delete, supabase_sql) are always approval-gated.',
    category: 'integration',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://supabase.com/dashboard',
    version: null,
    risk_summary: 'Service role key bypasses Row-Level Security. Some tools (supabase_sql) always require approval.',
    tags: ['integration', 'database', 'supabase'],
    manifest: {
      service_key: 'supabase',
      setup_kind: 'api_key',
      benefit: 'Unlock 7 Supabase tools: REST select/insert/upsert/update/delete, RPC, and SQL.',
      credentials: [
        {
          name: 'SUPABASE_URL',
          label: 'Project URL',
          type: 'text',
          placeholder: 'https://xxxx.supabase.co',
          help_url: 'https://supabase.com/dashboard',
          help_text: 'Project Settings → API → Project URL.',
          required: true,
        },
        {
          name: 'SUPABASE_SERVICE_ROLE_KEY',
          label: 'Service role key',
          type: 'password',
          placeholder: 'eyJ…',
          help_url: 'https://supabase.com/dashboard',
          help_text: 'Project Settings → API → service_role. Treat as a database password.',
          required: false,
        },
        {
          name: 'SUPABASE_ANON_KEY',
          label: 'Anon key',
          type: 'password',
          placeholder: 'eyJ…',
          help_url: 'https://supabase.com/dashboard',
          help_text: 'Project Settings → API → anon. Used for verify when service-role is absent.',
          required: false,
        },
        {
          name: 'SUPABASE_ACCESS_TOKEN',
          label: 'Personal access token',
          type: 'password',
          placeholder: 'sbp_…',
          help_url: 'https://supabase.com/dashboard/account/tokens',
          help_text: 'Required only if you want the agent to list / manage your Supabase projects via the Management API. Distinct from the project keys above.',
          required: false,
        },
      ],
      verify_endpoint: '/api/connections/supabase/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [
        'supabase_list_projects',
        'supabase_rest_select',
        'supabase_rest_insert',
        'supabase_rest_upsert',
        'supabase_rest_update',
        'supabase_rest_delete',
        'supabase_rpc',
        'supabase_sql',
      ],
      engines: [],
      logo_glyph: 'supabase',
    },
  },
  {
    slug: 'vercel',
    title: 'Vercel',
    description:
      'Trigger deployments and read project state. v1 saves the token without a live verify — failures surface on first call.',
    category: 'integration',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: 'https://vercel.com/account/tokens',
    version: null,
    risk_summary: 'vercel_create_deployment is high risk and approval-gated.',
    tags: ['integration', 'vercel', 'deploy'],
    manifest: {
      service_key: 'vercel',
      setup_kind: 'api_key',
      benefit: 'Unlock 3 Vercel tools: list projects, list deployments, create deployment.',
      credentials: [
        {
          name: 'VERCEL_TOKEN',
          label: 'Access token',
          type: 'password',
          placeholder: 'vercel_…',
          help_url: 'https://vercel.com/account/tokens',
          help_text: 'Create a token scoped to the right team.',
          required: true,
        },
        {
          name: 'VERCEL_TEAM_ID',
          label: 'Team ID (optional)',
          type: 'text',
          placeholder: 'team_…',
          help_url: 'https://vercel.com/teams',
          help_text: 'Only required for team-scoped tokens.',
          required: false,
        },
      ],
      verify_endpoint: '/api/connections/vercel/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global', 'project', 'agent'],
      unlocks_tool_slugs: [
        'vercel_list_projects',
        'vercel_list_deployments',
        'vercel_create_deployment',
      ],
      engines: [],
      logo_glyph: 'vercel',
    },
  },
  {
    slug: 'whatsapp',
    title: 'WhatsApp',
    description:
      'Text the main agent like you text Hermes. Pairs a dedicated WhatsApp number via Baileys. Operations (allowlist, message log) live at /whatsapp.',
    category: 'channel',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: null,
    version: null,
    risk_summary: 'Pair only a dedicated number — Baileys is an unofficial Web client; the paired account can be banned.',
    tags: ['channel', 'whatsapp', 'messaging'],
    manifest: {
      service_key: 'whatsapp',
      setup_kind: 'qr_pair',
      benefit: 'Receive WhatsApp messages and let the main agent reply through your number.',
      credentials: [],
      verify_endpoint: '/api/connections/whatsapp/verify',
      verify_supported: true,
      deep_link: '/whatsapp',
      requires_daemon: 'npm run whatsapp:bridge',
      supports_scopes: ['global'],
      unlocks_tool_slugs: ['whatsapp_send'],
      engines: [],
      logo_glyph: 'whatsapp',
    },
  },
  {
    slug: 'hermes',
    title: 'Hermes Agent',
    description:
      'Route long-running orchestrator jobs to the local Hermes binary. Detection probes ../hermes-agent and scripts/hermes-command.py.',
    category: 'engine',
    author: 'madarx',
    source_kind: 'builtin',
    source_url: null,
    version: null,
    risk_summary: 'Local subprocess execution — Hermes jobs inherit your local env.',
    tags: ['engine', 'hermes', 'local'],
    manifest: {
      service_key: 'hermes',
      setup_kind: 'binary_detect',
      benefit: 'Unlock the Hermes engine and the start_hermes_job orchestrator tool.',
      credentials: [
        {
          name: 'HERMES_AGENT_DIR',
          label: 'Hermes agent directory (optional)',
          type: 'text',
          placeholder: '/Users/you/Projects/hermes-agent',
          help_url: null,
          help_text: 'Defaults to ../hermes-agent relative to this repo. Override to point at a different checkout.',
          required: false,
        },
      ],
      verify_endpoint: '/api/connections/hermes/verify',
      verify_supported: true,
      deep_link: null,
      supports_scopes: ['global'],
      unlocks_tool_slugs: ['start_hermes_job', 'send_to_hermes'],
      engines: ['hermes'],
      logo_glyph: 'hermes',
    },
  },

  // ── Business OAuth2 connections (P0/P1 foundation) ──────────────────────────
  // These collect the operator's provider-app credentials once, then use the
  // local-first authorization-code flow to mint tokens into the vault. The tools
  // they unlock are authored as connectors (Tool-Smith) or shipped later; the
  // connection + grant machinery is ready for them today. All ad/spend writes
  // they unlock remain irreversible_external → always approval-gated.
  oauthConnectionSeed({
    slug: 'meta-ads',
    title: 'Meta Ads',
    description: 'Build and report on Facebook + Instagram ad campaigns. Campaign/budget writes are always approval-gated.',
    category: 'marketing',
    provider: 'meta',
    prefix: 'META',
    scopes: ['ads_management', 'ads_read', 'business_management'],
    unlocks: ['meta_ads.insights_read', 'meta_ads.campaign_create', 'meta_ads.adset_create', 'meta_ads.budget_set'],
    healthEndpoint: 'https://graph.facebook.com/v19.0/me',
    risk: 'Campaign create, budget set, and audience create are irreversible and always require approval.',
    tags: ['marketing', 'ads', 'meta', 'oauth'],
  }),
  oauthConnectionSeed({
    slug: 'google-ads',
    title: 'Google Ads',
    description: 'Manage Google Ads campaigns and pull GAQL reports. Requires a developer token in addition to OAuth sign-in.',
    category: 'marketing',
    provider: 'google',
    prefix: 'GOOGLE_ADS',
    scopes: ['https://www.googleapis.com/auth/adwords'],
    extraCredentials: [
      { name: 'GOOGLE_ADS_DEVELOPER_TOKEN', label: 'Developer token', type: 'password', required: true, help_text: 'Google Ads API access requires a developer token alongside OAuth.' },
    ],
    unlocks: ['google_ads.report', 'google_ads.campaign_create', 'google_ads.budget_set'],
    healthEndpoint: 'https://googleads.googleapis.com/v17/customers:listAccessibleCustomers',
    risk: 'Campaign create and budget set are irreversible and always require approval.',
    tags: ['marketing', 'ads', 'google', 'oauth'],
  }),
  oauthConnectionSeed({
    slug: 'ga4',
    title: 'Google Analytics 4',
    description: 'Read GA4 metrics for marketing reports. Read-only — no external writes.',
    category: 'analytics',
    provider: 'google',
    prefix: 'GA4',
    scopes: ['https://www.googleapis.com/auth/analytics.readonly'],
    unlocks: ['ga4.run_report', 'ga4.realtime_report'],
    healthEndpoint: 'https://analyticsdata.googleapis.com/v1beta/properties',
    risk: 'Read-only analytics access.',
    tags: ['analytics', 'ga4', 'google', 'oauth'],
  }),
  oauthConnectionSeed({
    slug: 'hubspot-crm',
    title: 'HubSpot CRM',
    description: 'Read and (with approval) write contacts, deals, and activity in HubSpot.',
    category: 'sales',
    provider: 'hubspot',
    prefix: 'HUBSPOT',
    scopes: ['crm.objects.contacts.read', 'crm.objects.deals.read', 'crm.objects.contacts.write'],
    unlocks: ['hubspot.contacts_read', 'hubspot.deals_read', 'hubspot.contact_upsert'],
    healthEndpoint: 'https://api.hubapi.com/crm/v3/objects/contacts',
    risk: 'CRM writes (contact/deal upsert) require approval.',
    tags: ['sales', 'crm', 'hubspot', 'oauth'],
  }),
];

function upsertConnection(db, seed) {
  const existing = db
    .prepare("SELECT id FROM marketplace_items WHERE kind = 'connection' AND slug = ?")
    .get(seed.slug);
  const id = existing?.id || `connection:${seed.slug}`;
  const manifestJson = seed.manifest ? JSON.stringify(seed.manifest) : null;
  const tagsJson = seed.tags ? JSON.stringify(seed.tags) : null;

  if (existing) {
    db.prepare(`
      UPDATE marketplace_items
         SET title = ?, description = ?, category = ?, author = ?, source_kind = ?,
             source_url = ?, version = ?, manifest_json = ?, risk_summary = ?, tags = ?
       WHERE id = ?
    `).run(
      seed.title,
      seed.description,
      seed.category,
      seed.author,
      seed.source_kind,
      seed.source_url,
      seed.version,
      manifestJson,
      seed.risk_summary,
      tagsJson,
      id,
    );
  } else {
    db.prepare(`
      INSERT INTO marketplace_items
        (id, kind, slug, title, description, category, author,
         source_kind, source_url, version, manifest_json, risk_summary, tags, created_at)
      VALUES (?, 'connection', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `).run(
      id,
      seed.slug,
      seed.title,
      seed.description,
      seed.category,
      seed.author,
      seed.source_kind,
      seed.source_url,
      seed.version,
      manifestJson,
      seed.risk_summary,
      tagsJson,
      new Date().toISOString(),
    );

    db.prepare(`
      INSERT OR IGNORE INTO marketplace_installations (item_id, installed)
      VALUES (?, 0)
    `).run(id);
  }
}

export function seedConnections(db) {
  try {
    for (const seed of CONNECTION_SEEDS) upsertConnection(db, seed);
  } catch (err) {
    console.warn('[connection-seeds] seed failed:', err?.message || err);
  }
}

export const CONNECTION_SLUGS = CONNECTION_SEEDS.map(s => s.slug);
export { CONNECTION_SEEDS };
