import { mkdirSync, writeFileSync, rmSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { spaceDataDir, spaceWorkspaceDir, spaceFilesDir, spaceLogsDir } from './paths.js';

export interface SpaceDirParams {
  dataRoot: string;
  worktreeDir: string;
  id: string;
}

/**
 * 案件スペース新規作成時に書き込むデフォルト AGENTS.md。
 * スペースの使われ方に応じてエージェント自身が育てる前提の足場。
 * アプリの実機能（カレンダー / メモリ / スキル / ワークスペース・アプリ）への
 * 導線を最初から織り込み、ユーザーが手で書かなくても賢く振る舞えるようにする。
 */
export function defaultAgentsMd(title: string): string {
  return `# ${title}

このスペース（ワークスペース）で作業するエージェントへの指示です。
スペースの使い方が固まってきたら、このファイル自体を実態に合わせて自由に書き換えてください。更新はエージェントが自分で行って構いません。

## このスペースについて
- 目的・背景・関係者: （未記入。最初のやり取りで分かったことを書き足す）
- 用語・前提・進め方のルール: （随時追記）

## 基本方針

- **この AGENTS.md を育てる**
  作業から分かったルール・前提・用語・段取りは、ここに追記して最新に保つ。スペースの使われ方が変われば構成ごと見直してよい。

- **メモリを更新する**
  ユーザーの役割・決定事項・締め切り・参照先など、次回以降に役立つ事実は \`UpdateUserMemory\` で随時保存する。

- **予定はカレンダーに登録する**
  締め切り・打ち合わせ・リマインドなど日付のある予定は \`AddCalendarEvent\` でこのスペースのカレンダーに入れる。確認は \`ListCalendarEvents\`。

- **HTML 資料はスキルを使う**
  設計書・レポートなどの HTML 資料を作るときは、該当スキルを \`ReadSkill\` で読んでから作る（利用可能なスキルはシステムプロンプトの Skills Index 参照）。

- **GUI が分かりやすいならアプリにする**
  入力フォーム・ダッシュボード・繰り返し使うツールは、文章で返すより「ワークスペース・アプリ」にした方が使いやすいことが多い。その場合は \`ReadToolDoc({ name: "workspace-apps" })\` を読んで \`apps/{アプリ名}/index.html\` に作る。

- **成果物の置き場所**
  生成したファイルはワークスペースのファイル領域に保存する。このスペースは複数人・複数会話で共有されることがあるので、既存ファイルを壊さない。

## ファイル領域のディレクトリ
- \`input/\` : ユーザーが渡す入力ファイル（読み書き可）
- \`output/\` : エージェントの成果物の置き場（ここに書く）
- \`logs/\` : 作業ログ（チェックリスト・実行記録など）
- \`apps/\` : ワークスペース・アプリの HTML
- \`readonly/\` : **閲覧のみ。ユーザー専用の領域。ここのファイルは Read してよいが、Write / Edit / 上書きしてはいけない**（ツール層でも書込はブロックされる）
`;
}

/**
 * 案件スペースのディレクトリ雛形を作る。
 * - data/spaces/{id}/ : AGENTS.md / pieces/ / memory/ / mcp.json
 * - {worktreeDir}/space/{id}/ : files/ / logs/
 * 既に存在する場合は上書きしない（mkdir recursive・writeFile は存在チェック付き）。
 */
export function scaffoldCaseSpace(params: SpaceDirParams & { title: string }): void {
  const data = spaceDataDir(params.dataRoot, params.id);
  mkdirSync(join(data, 'pieces'), { recursive: true });
  mkdirSync(join(data, 'memory'), { recursive: true });
  const agentsPath = join(data, 'AGENTS.md');
  if (!existsSync(agentsPath)) {
    writeFileSync(agentsPath, defaultAgentsMd(params.title), 'utf-8');
  }
  const mcpPath = join(data, 'mcp.json');
  if (!existsSync(mcpPath)) {
    writeFileSync(mcpPath, JSON.stringify({ mcpServers: {} }, null, 2), 'utf-8');
  }
  // 新規ワークスペースでも input/output を最初から見せ、「どこに置けばエージェントが
  // 読むのか」を分かるようにする（既存 local 挙動の ensureWorkspaceDirs と同じ構成）。
  const files = spaceFilesDir(params.worktreeDir, params.id);
  mkdirSync(join(files, 'input'), { recursive: true });
  mkdirSync(join(files, 'output'), { recursive: true });
  // readonly/ : ユーザーが「エージェントに編集されたくないファイル」を置く閲覧専用領域。
  // エージェントは Read 可・Write/Edit 不可（core.ts の assertWritable が強制）。
  mkdirSync(join(files, 'readonly'), { recursive: true });
  mkdirSync(spaceLogsDir(params.worktreeDir, params.id), { recursive: true });
}

/** 作成失敗時のロールバック。data と workspace の両ディレクトリを消す。 */
export function removeSpaceDirs(params: SpaceDirParams): void {
  rmSync(spaceDataDir(params.dataRoot, params.id), { recursive: true, force: true });
  rmSync(spaceWorkspaceDir(params.worktreeDir, params.id), { recursive: true, force: true });
}
