import path from 'node:path';

export function estimateTokens(text) {
  if (!text) return 0;
  return Math.ceil(text.length / 3.5);
}

export async function getUserIdentifier() {
  try {
    const { execSync: ex } = await import('node:child_process');
    const email = ex('git config user.email', { encoding: 'utf8', stdio: ['ignore','pipe','ignore'] }).trim();
    if (email) return email.replace(/[^a-zA-Z0-9._-]/g, '_');
  } catch {}
  try {
    const { execSync: ex } = await import('node:child_process');
    const name = ex('git config user.name', { encoding: 'utf8', stdio: ['ignore','pipe','ignore'] }).trim();
    if (name) return name.replace(/[^a-zA-Z0-9._-]/g, '_');
  } catch {}
  return 'unknown';
}

export async function appendUsageRecord(feature, inputText, outputText, cwd, model = 'sonnet') {
  try {
    const { appendFile, mkdir } = await import('node:fs/promises');
    const user = await getUserIdentifier();
    const dir = path.join(cwd, '.sdd', 'usage');
    await mkdir(dir, { recursive: true });
    const record = { ts: new Date().toISOString(), user, feature, in: estimateTokens(inputText), out: estimateTokens(outputText), model };
    await appendFile(path.join(dir, `sdd-usage-${user}.jsonl`), JSON.stringify(record) + '\n', 'utf8');
  } catch {}
}

export async function getUsageSummary(cwd) {
  try {
    const { readdir, readFile: rf } = await import('node:fs/promises');
    const dir = path.join(cwd, '.sdd', 'usage');
    const files = await readdir(dir).catch(() => []);
    const records = [];
    for (const f of files) {
      if (!f.startsWith('sdd-usage-') || !f.endsWith('.jsonl')) continue;
      const content = await rf(path.join(dir, f), 'utf8').catch(() => '');
      for (const line of content.split('\n').filter(Boolean)) {
        try { records.push(JSON.parse(line)); } catch {}
      }
    }
    return records;
  } catch { return []; }
}

export async function syncUsageToAdo(cwd, orgUrl, project, pat, repo) {
  if (!orgUrl || !pat || !repo) return { ok: false, error: 'Configuração ADO incompleta (orgUrl, PAT e Repositório são obrigatórios)' };
  try {
    const { readdir, readFile: rf } = await import('node:fs/promises');
    const user = await getUserIdentifier();
    const dir = path.join(cwd, '.sdd', 'usage');
    const localFile = path.join(dir, `sdd-usage-${user}.jsonl`);
    const content = await rf(localFile, 'utf8').catch(() => '');
    if (!content.trim()) return { ok: false, error: 'Nenhum dado local para sincronizar' };

    const org = orgUrl.replace(/\/$/, '');
    const auth = 'Basic ' + Buffer.from(':' + pat).toString('base64');
    const repoBase = `${org}/${encodeURIComponent(project)}/_apis/git/repositories/${encodeURIComponent(repo)}`;

    const repoRes = await fetch(`${repoBase}?api-version=7.0`, { headers: { Authorization: auth } });
    if (!repoRes.ok) return { ok: false, error: `Repositório não encontrado: ${repo}` };
    const repoInfo = await repoRes.json();
    const defaultBranch = (repoInfo.defaultBranch || 'refs/heads/main').replace('refs/heads/', '');

    const refsRes = await fetch(`${repoBase}/refs?filter=heads/${defaultBranch}&api-version=7.0`, { headers: { Authorization: auth } });
    const refsData = await refsRes.json();
    const latestSha = refsData.value?.[0]?.objectId;
    if (!latestSha) return { ok: false, error: 'Não foi possível obter o SHA do último commit' };

    const remotePath = `/.sdd/usage/sdd-usage-${user}.jsonl`;
    let changeType = 'add';
    const existsRes = await fetch(`${repoBase}/items?path=${encodeURIComponent(remotePath)}&api-version=7.0`, { headers: { Authorization: auth } });
    if (existsRes.ok) changeType = 'edit';

    const pushBody = {
      refUpdates: [{ name: `refs/heads/${defaultBranch}`, oldObjectId: latestSha }],
      commits: [{ comment: 'chore: sdd-fp usage log', changes: [{
        changeType,
        item: { path: remotePath },
        newContent: { content: Buffer.from(content).toString('base64'), contentType: 'base64encoded' }
      }] }]
    };

    const pushRes = await fetch(`${repoBase}/pushes?api-version=7.0`, {
      method: 'POST', headers: { Authorization: auth, 'Content-Type': 'application/json' },
      body: JSON.stringify(pushBody)
    });
    if (!pushRes.ok) {
      const err = await pushRes.json().catch(() => ({}));
      return { ok: false, error: err.message || err.typeKey || 'Falha no push' };
    }
    return { ok: true };
  } catch (e) { return { ok: false, error: e.message }; }
}
