#!/usr/bin/env node

/**
 * Cody CLI postinstall
 *
 * 1. Cleans stale cached data from older builds
 * 2. Auto-provisions an AINative trial account if none exists
 *    - Calls POST /api/v1/public/instant-db (no auth, no signup)
 *    - Writes credentials to ~/.cody/credentials.json
 *    - tmp_ key works for both LLM inference (/v1/messages) and ZeroDB
 *    - 72-hour trial, claimable at the printed URL
 */

const fs = require('fs')
const path = require('path')
const os = require('os')

const HOME = os.homedir()
const CODY_DIR = path.join(HOME, '.cody')
const CREDENTIALS_PATH = path.join(CODY_DIR, 'credentials.json')
const AINATIVE_API = 'https://api.ainative.studio'
const STALE_MARKERS = ['anthropic.com/api', 'claude.ai/api', 'console.anthropic.com']

// ── Cleanup ────────────────────────────────────────────────────────────────────

function cleanDir(dirPath) {
  if (!fs.existsSync(dirPath)) return

  try {
    const credFiles = ['credentials.json', 'oauth.json', 'tokens.json', '.credentials']
    for (const f of credFiles) {
      const fp = path.join(dirPath, f)
      if (fs.existsSync(fp)) {
        try {
          const content = fs.readFileSync(fp, 'utf8')
          if (STALE_MARKERS.some(m => content.includes(m))) {
            fs.unlinkSync(fp)
            console.log(`  Cleaned stale credentials: ${f}`)
          }
        } catch {}
      }
    }

    const settingsFile = path.join(dirPath, 'settings.json')
    if (fs.existsSync(settingsFile)) {
      try {
        const content = fs.readFileSync(settingsFile, 'utf8')
        if (STALE_MARKERS.some(m => content.includes(m))) {
          fs.unlinkSync(settingsFile)
          console.log(`  Cleaned stale settings`)
        }
      } catch {}
    }

    const cacheDir = path.join(dirPath, 'cache')
    if (fs.existsSync(cacheDir)) {
      try {
        fs.rmSync(cacheDir, { recursive: true, force: true })
        console.log(`  Cleared cache`)
      } catch {}
    }
  } catch {}
}

// ── Provisioning ───────────────────────────────────────────────────────────────

function hasValidCredentials() {
  if (!fs.existsSync(CREDENTIALS_PATH)) return false
  try {
    const creds = JSON.parse(fs.readFileSync(CREDENTIALS_PATH, 'utf8'))
    // Valid if it has an api_key AND not expired (or no expiry = permanent)
    if (!creds.api_key) return false
    if (creds.expires_at) {
      const expiresAt = new Date(creds.expires_at)
      if (expiresAt < new Date()) return false // expired
    }
    // Skip re-provisioning if already using a permanent sk_ key (logged-in user)
    return true
  } catch {
    return false
  }
}

function writeCredentials(data) {
  try {
    fs.mkdirSync(CODY_DIR, { recursive: true })
    const tmp = CREDENTIALS_PATH + '.tmp'
    fs.writeFileSync(tmp, JSON.stringify(data, null, 2), 'utf8')
    fs.renameSync(tmp, CREDENTIALS_PATH)
  } catch (e) {
    // Non-fatal — user can still log in manually
  }
}

async function provisionTrialAccount() {
  // Check if ANTHROPIC_API_KEY or CODY_API_KEY already set — skip if so
  if (process.env.ANTHROPIC_API_KEY || process.env.CODY_API_KEY) return
  // Skip if valid credentials already on disk
  if (hasValidCredentials()) return

  try {
    // Use built-in fetch (Node 18+) or skip silently on older Node
    if (typeof fetch === 'undefined') return

    const res = await fetch(`${AINATIVE_API}/api/v1/public/instant-db`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ agree_terms: true, on_behalf_of: 'cody-cli' }),
      signal: AbortSignal.timeout(12000),
    })

    if (!res.ok) return // Silent fail — user can run `cody login` manually

    const data = await res.json()
    if (!data.api_key || !data.project_id) return

    writeCredentials({
      api_key: data.api_key,
      project_id: data.project_id,
      base_url: AINATIVE_API,
      expires_at: data.expires_at,
      claim_url: data.claim_url,
      claimed: false,
      provisioned_by: 'cody-cli-postinstall',
      provisioned_at: new Date().toISOString(),
    })

    console.log('')
    console.log('┌─────────────────────────────────────────────────────────────┐')
    console.log('│  Cody CLI — AINative trial account provisioned              │')
    console.log('│                                                             │')
    console.log('│  You\'re ready to code. No signup required.                 │')
    console.log('│                                                             │')
    console.log(`│  Trial expires: ${new Date(data.expires_at).toLocaleDateString().padEnd(43)}│`)
    console.log('│                                                             │')
    console.log('│  Claim your free account to keep access permanently:        │')
    console.log(`│  → ${(data.claim_url || '').slice(0, 56).padEnd(57)}│`)
    console.log('│                                                             │')
    console.log('│  Run `cody` to start coding.                               │')
    console.log('└─────────────────────────────────────────────────────────────┘')
    console.log('')
  } catch {
    // Never fail the install
  }
}

// ── Main ───────────────────────────────────────────────────────────────────────

async function main() {
  // Step 1: cleanup stale data
  try {
    const configDirs = [
      CODY_DIR,
      path.join(HOME, '.config', 'cody-cli'),
    ]
    let cleaned = false
    for (const dir of configDirs) {
      if (fs.existsSync(dir)) {
        cleanDir(dir)
        cleaned = true
      }
    }
    if (cleaned) {
      console.log('Cody CLI: cleaned stale data from previous versions.')
    }
  } catch {}

  // Step 2: provision trial account
  await provisionTrialAccount()
}

main().catch(() => {}) // Never fail the install
