const chalk = require('chalk')
const inquirer = require('inquirer')
const {
  storeToken,
  validateToken,
  normalizeIdTokenForBearerHeader,
} = require('../lib/auth')

function readStdinAsString() {
  return new Promise((resolve, reject) => {
    /** @type {Buffer[]} */
    const chunks = []
    process.stdin.on('data', (chunk) => chunks.push(chunk))
    process.stdin.on('end', () => {
      const buf = Buffer.concat(chunks)
      resolve(String(buf).replace(/^\uFEFF/, '').trim())
    })
    process.stdin.on('error', reject)
  })
}

/**
 * Store an ID token / bearer JWT in the keychain (same persistence as `bild login`).
 *
 * @param {string[]} [tokenParts] - Commander argv segments (e.g. ["Bearer", "<jwt>"] when unquoted)
 */
async function tokenSetCommand(tokenParts) {
  try {
    let raw = ''
    if (Array.isArray(tokenParts) && tokenParts.length > 0) {
      raw = tokenParts.join(' ').trim()
    }

    if (!raw) {
      if (!process.stdin.isTTY) {
        raw = await readStdinAsString()
      } else {
        const prompt = inquirer.createPromptModule()
        const { token: pasted } = await prompt([
          {
            type: 'password',
            name: 'token',
            message: 'Paste bearer token:',
            mask: '*',
            validate: (input) => {
              if (!input || !String(input).trim()) return 'Token is required'
              if (String(input).trim().length < 50) {
                return 'Token seems too short (should be at least ~50 characters)'
              }
              return true
            },
          },
        ])
        raw = pasted ? String(pasted).trim() : ''
      }
    }

    if (!raw) {
      console.error(chalk.red('No token to store (provide an argument, pipe stdin, or paste when prompted)'))
      process.exit(1)
    }

    const clean = normalizeIdTokenForBearerHeader(raw)
    if (!validateToken(clean)) {
      console.log(chalk.yellow('Warning: token does not look like a JWT; storing anyway.'))
    }

    const ok = await storeToken(clean)
    if (!ok) {
      console.error(chalk.red('Failed to store token in the keychain'))
      process.exit(1)
    }

    console.log(
      chalk.green(
        '✓ Token saved to keychain. The CLI uses it when BILD_TOKEN and CMS_TOKEN are not set.',
      ),
    )
  } catch (e) {
    console.error(chalk.red(e.message || String(e)))
    process.exit(1)
  }
}

module.exports = tokenSetCommand
