import {
  applyPlan,
  planInstall,
  tildify,
  type Scope,
  type TargetId,
} from "@designpaca/core";
import { getSkill } from "../skill.ts";
import { bad, dim, fold, heading, info, ok, warn } from "../ui.ts";

export interface InstallOptions {
  targets: TargetId[];
  scope: Scope;
  force?: boolean;
  /** 실제로 쓰지 않고 계획만 출력 */
  dryRun?: boolean;
}

export interface InstallOutcome {
  target: TargetId;
  root: string;
  written: number;
  skipped: string[];
  blocked?: string;
}

/** install/update/TUI 가 공유하는 실제 설치 실행부 */
export async function runInstall(opts: InstallOptions): Promise<InstallOutcome[]> {
  const skill = await getSkill();
  const outcomes: InstallOutcome[] = [];

  for (const target of opts.targets) {
    const plan = await planInstall(target, opts.scope, skill);
    if (plan.blocked) {
      outcomes.push({ target, root: "", written: 0, skipped: [], blocked: plan.blocked });
      continue;
    }
    if (opts.dryRun) {
      outcomes.push({ target, root: plan.root, written: plan.actions.length, skipped: [] });
      continue;
    }
    const res = await applyPlan(plan, skill.version, { force: opts.force });
    outcomes.push({
      target,
      root: plan.root,
      written: res.written.length,
      skipped: res.skipped,
    });
  }
  return outcomes;
}

export function printOutcomes(outcomes: InstallOutcome[], dryRun = false): void {
  console.log(heading(dryRun ? "설치 계획" : "설치 결과"));
  for (const o of outcomes) {
    if (o.blocked) {
      console.log(bad(`${o.target}: ${o.blocked}`));
      continue;
    }
    const verb = dryRun ? "쓸 파일" : "설치됨";
    console.log(ok(`${o.target} — ${verb} ${o.written}개  ${dim(tildify(o.root))}`));
    if (o.skipped.length > 0) {
      console.log(warn(`  직접 수정하신 파일이라 그대로 두었습니다 (--force 로 덮어쓸 수 있습니다):`));
      for (const s of fold(o.skipped)) console.log(dim(`    ${tildify(s)}`));
    }
  }
}

/** 설치 후 안내 — 여기서 끝내지 말고 다음 행동을 알려준다 */
export function printNextSteps(targets: TargetId[]): void {
  console.log(heading("다음 단계"));
  if (targets.includes("claude-code")) {
    console.log(info(`Claude Code 를 새로 연 뒤 ${dim("/designpaca")} 를 실행해 주세요`));
  }
  if (targets.includes("codex")) {
    console.log(info(`Codex CLI 에서 designpaca 스킬이 자동으로 잡힌다`));
  }
  if (targets.includes("zcode")) {
    console.log(info(`ZCode 는 새 세션부터 designpaca 스킬이 자동으로 잡힌다`));
  }
  if (targets.includes("cursor")) {
    console.log(info(`Cursor 는 새 창을 열 때 ${dim(".cursor/skills/designpaca")} 스킬을 읽는다`));
  }
  if (targets.includes("agents")) {
    console.log(
      info(
        `${dim(".agents/skills")} 는 중립 경로다 — Cursor · Antigravity · ZCode 등 규약을 읽는 하네스가 함께 잡는다`,
      ),
    );
  }
  if (targets.includes("antigravity")) {
    console.log(
      info(`Antigravity 는 전역 ${dim("~/.gemini/antigravity-cli/skills")} 를 읽는다 (워크스페이스는 .agents/skills)`),
    );
  }
  if (targets.includes("gemini-cli")) {
    console.log(info(`Gemini CLI 는 ${dim("~/.gemini/skills")} 에서 스킬을 읽는다`));
  }
  if (targets.includes("windsurf")) {
    console.log(
      info(`Windsurf(Cascade) 는 ${dim(".windsurf/skills/designpaca")} 스킬을 읽는다`),
    );
  }
  if (targets.includes("copilot")) {
    console.log(
      info(`GitHub Copilot 은 ${dim(".github/skills")} (~/.copilot/skills) 의 SKILL.md 를 읽는다`),
    );
  }
  if (targets.includes("agents-md")) {
    console.log(
      info(`AGENTS.md 에는 포인터만 넣었다 — 본문은 ${dim(".designpaca/SKILL.md")} 에 있다`),
    );
  }
  console.log(info(`문서: ${dim("https://designpaca.chanpaca.net")}`));
}
