import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
import { type GitHubClient } from './github.js';
import type { TrelloClient } from '../trello/client.js';

const execFileAsync = promisify(execFile);

const CACHE_TTL_MS = 60_000; // 60 seconds

interface ContextBundle {
  claudeMdSnippet: string;
  gitLog: string;
  trelloSummary: string;
  githubCommits: string;
  githubPRs: string;
  cachedAt: number;
}

let _cache: ContextBundle | null = null;

async function readClaudeMd(repoPath: string): Promise<string> {
  try {
    const raw = await readFile(join(repoPath, 'CLAUDE.md'), 'utf-8');
    // Take first ~100 lines - project overview + tech stack, skip the long component registry
    const lines = raw.split('\n');
    const cutoff = lines.findIndex(
      (l) => l.startsWith('## Component Registry') || l.startsWith('| Component'),
    );
    const trimmed = cutoff > 0 ? lines.slice(0, cutoff) : lines.slice(0, 100);
    return trimmed.join('\n').trim();
  } catch {
    return '(CLAUDE.md not readable)';
  }
}

async function readGitLog(repoPath: string): Promise<string> {
  try {
    const { stdout } = await execFileAsync('git', ['log', '--oneline', '-20'], { cwd: repoPath });
    return stdout.trim();
  } catch {
    return '(git log unavailable)';
  }
}

async function buildTrelloSummary(trello: TrelloClient): Promise<string> {
  try {
    const entries = await trello.getBoardSummary();
    return entries.map((e) => `${e.list.name}: ${e.count} cards`).join('\n');
  } catch {
    return '(Trello unavailable)';
  }
}

async function buildGithubContext(github: GitHubClient): Promise<{ commits: string; prs: string }> {
  try {
    const [commits, prs] = await Promise.all([github.getRecentCommits(15), github.getRecentPRs(8)]);

    const commitsText = commits
      .map((c) => {
        const date = new Date(c.date).toLocaleDateString('en-IL', { timeZone: 'Asia/Jerusalem' });
        return `${c.sha} ${c.message} (${c.author}, ${date})`;
      })
      .join('\n');

    const prsText = prs
      .map((pr) => {
        const date = new Date(pr.createdAt).toLocaleDateString('en-IL', {
          timeZone: 'Asia/Jerusalem',
        });
        return `#${pr.number} [${pr.state}] ${pr.title} (${pr.author}, ${date})`;
      })
      .join('\n');

    return { commits: commitsText, prs: prsText };
  } catch {
    return { commits: '(GitHub unavailable)', prs: '(GitHub unavailable)' };
  }
}

export async function getProjectContext(
  repoPath: string,
  trello: TrelloClient,
  github: GitHubClient,
): Promise<ContextBundle> {
  const now = Date.now();
  if (_cache && now - _cache.cachedAt < CACHE_TTL_MS) {
    return _cache;
  }

  const [claudeMdSnippet, gitLog, trelloSummary, githubCtx] = await Promise.all([
    readClaudeMd(repoPath),
    readGitLog(repoPath),
    buildTrelloSummary(trello),
    buildGithubContext(github),
  ]);

  _cache = {
    claudeMdSnippet,
    gitLog,
    trelloSummary,
    githubCommits: githubCtx.commits,
    githubPRs: githubCtx.prs,
    cachedAt: now,
  };

  return _cache;
}

export function buildContextPrompt(
  ctx: ContextBundle,
  question: string,
  chatHistory: string | null = null,
  systemPrompt = 'You are a helpful project assistant.',
): string {
  const historySection = chatHistory ? `\n### Recent group conversation\n${chatHistory}\n` : '';

  return `${systemPrompt}

---

You are HetziBot, a helpful AI assistant for the Hetzi development team. Answer any question - about the project, the recent conversation, or any general topic.

For project questions, use the context below. For questions about the chat history, use the "Recent group conversation" section. For general questions, answer from your own knowledge.
Respond in the same language as the question (Hebrew or English).

## Project context (Hetzi - Hebrew-first PWA marketplace)

### Codebase (CLAUDE.md)
${ctx.claudeMdSnippet}

### Recent commits
${ctx.gitLog}

### Trello board
${ctx.trelloSummary}

### GitHub recent commits
${ctx.githubCommits}

### GitHub recent PRs
${ctx.githubPRs}
${historySection}
---

Question: ${question}`;
}

export function buildDirectPrompt(question: string, chatHistory: string | null = null): string {
  const historySection = chatHistory ? `\n## Recent group conversation\n${chatHistory}\n` : '';

  return `You are HetziBot, a helpful AI assistant. Answer the following question concisely.
Respond in the same language as the question (Hebrew or English).
${historySection}
Question: ${question}`;
}
