import https from 'node:https';
import { spawn, execSync } from 'node:child_process';
import { mkdir, writeFile, readFile, rm } from 'node:fs/promises';
import path from 'node:path';
import { randomUUID } from 'node:crypto';
import { homedir } from 'node:os';
import { appendUsageRecord } from '../services/usage.js';
import { jobs } from './job-store.js';

function resolveClaude() {
  try { execSync('claude --version', { stdio: 'ignore' }); return 'claude'; } catch {}
  const candidates = [
    path.join(homedir(), '.npm-global', 'bin', 'claude'),
    '/usr/local/bin/claude',
    '/opt/homebrew/bin/claude',
    path.join(homedir(), '.local', 'bin', 'claude'),
    path.join(homedir(), '.nvm', 'versions', 'node', 'current', 'bin', 'claude'),
  ];
  for (const c of candidates) {
    try { execSync(`"${c}" --version`, { stdio: 'ignore' }); return c; } catch {}
  }
  try {
    const found = execSync('bash -lc "which claude"', { encoding: 'utf8' }).trim();
    if (found) return found;
  } catch {}
  return 'claude';
}

export const CLAUDE_BIN = resolveClaude();

// .claude/settings.local.json is the highest-priority settings file in Claude Code.
// Writing alwaysThinkingEnabled:false here reliably overrides the global setting,
// unlike --settings flag which is "additive" and may not override existing keys.
let _fastJobCount = 0;
let _savedLocalSettings = undefined;

async function _acquireFastMode(cwd) {
  _fastJobCount++;
  if (_fastJobCount > 1) return;
  const localPath = path.join(cwd, '.claude', 'settings.local.json');
  try {
    _savedLocalSettings = await readFile(localPath, 'utf8');
    const orig = JSON.parse(_savedLocalSettings);
    if (orig.alwaysThinkingEnabled === false) { _savedLocalSettings = undefined; return; }
    await writeFile(localPath, JSON.stringify({ ...orig, alwaysThinkingEnabled: false }), 'utf8');
  } catch {
    _savedLocalSettings = null;
    await mkdir(path.join(cwd, '.claude'), { recursive: true });
    await writeFile(localPath, JSON.stringify({ alwaysThinkingEnabled: false }), 'utf8');
  }
}

async function _releaseFastMode(cwd) {
  _fastJobCount--;
  if (_fastJobCount > 0) return;
  if (_savedLocalSettings === undefined) return;
  const localPath = path.join(cwd, '.claude', 'settings.local.json');
  if (_savedLocalSettings === null) {
    await rm(localPath, { force: true });
  } else {
    await writeFile(localPath, _savedLocalSettings, 'utf8');
  }
  _savedLocalSettings = undefined;
}

export function startJob(command, { fast = false } = {}) {
  const jobId = randomUUID();
  const job = { chunks: [], done: false, code: null, listeners: new Set() };
  jobs.set(jobId, job);

  const msg = 'IMPORTANTE: Responda SEMPRE em português do Brasil. Todos os arquivos gerados (requirements.md, design.md, tasks.md, validation.md, brief.md, etc.) devem ter seu conteúdo escrito em português do Brasil. Ao criar spec.json, defina "language": "pt-BR". Nunca gere conteúdo em inglês.\n\n' + command;

  const emit = (event) => {
    job.chunks.push(event);
    for (const fn of job.listeners) fn(event);
  };

  const cwd = process.cwd();

  const launch = () => {
    const spawnOpts = { cwd, stdio: ['ignore', 'pipe', 'pipe'] };
    const proc = spawn(CLAUDE_BIN, ['--print', '--dangerously-skip-permissions', msg], spawnOpts);
    let _jobOut = '';
    proc.stdout.on('data', d => { const t = d.toString(); _jobOut += t; emit({ type: 'data', text: t }); });
    proc.stderr.on('data', d => emit({ type: 'data', text: d.toString() }));
    proc.on('close', code => {
      appendUsageRecord('wizard', msg, _jobOut, cwd).catch(() => {});
      job.done = true;
      job.code = code;
      emit({ type: 'done', code });
      job.listeners.clear();
      setTimeout(() => jobs.delete(jobId), 5 * 60_000);
      if (fast) _releaseFastMode(cwd).catch(() => {});
    });
    proc.on('error', err => {
      emit({ type: 'data', text: `Erro ao iniciar claude: ${err.message}\nBinário: ${CLAUDE_BIN}\n` });
      emit({ type: 'error', text: err.message });
      job.done = true;
      job.listeners.clear();
      if (fast) _releaseFastMode(cwd).catch(() => {});
    });
  };

  if (fast) {
    _acquireFastMode(cwd).then(launch).catch(launch);
  } else {
    launch();
  }
  return jobId;
}

export function adoGetFileContent(pat, fullUrl) {
  return new Promise((resolve) => {
    const auth = Buffer.from(':' + pat).toString('base64');
    try {
      const u = new URL(fullUrl);
      const req = https.request({
        hostname: u.hostname, path: u.pathname + u.search, method: 'GET',
        headers: { 'Authorization': 'Basic ' + auth, 'Accept': 'text/plain' },
      }, res => {
        const chunks = [];
        res.on('data', c => chunks.push(c));
        res.on('end', () => resolve({ status: res.statusCode, body: Buffer.concat(chunks).toString() }));
      });
      req.on('error', () => resolve({ status: 0, body: '' }));
      req.end();
    } catch { resolve({ status: 0, body: '' }); }
  });
}
