import { inspectDrift, readManifest, tildify } from "@designpaca/core";
import { getVersion } from "../skill.ts";
import { runInstall, printOutcomes } from "./install.ts";
import { dim, heading, info, ok, warn } from "../ui.ts";

/**
 * 설치 기록을 그대로 따라가며 재설치한다.
 * 사용자가 고친 파일은 기본적으로 보존된다(applyPlan 이 판단) — 강제로 맞추려면 --force.
 */
export async function runUpdate(opts: { force?: boolean } = {}): Promise<number> {
  const version = await getVersion();
  const manifest = await readManifest();

  if (manifest.installs.length === 0) {
    console.log(warn("설치 기록이 없습니다. `npx designpaca install` 을 먼저 실행해 주세요."));
    return 1;
  }

  console.log(heading(`업데이트 → v${version}`));
  const stale = manifest.installs.filter((i) => i.version !== version);

  if (stale.length === 0) {
    console.log(ok("설치된 스킬이 모두 최신 버전입니다"));

    // 버전이 같아도 파일이 사라졌거나 수정됐을 수 있다. 조용히 넘기면 사용자가 모른다.
    let broken = 0;
    for (const rec of manifest.installs) {
      const drift = await inspectDrift(rec);
      const missing = drift.files.filter((f) => f.status === "missing");
      if (missing.length > 0) {
        broken += missing.length;
        console.log(warn(`${rec.target}: 파일 ${missing.length}개가 사라졌다 ${dim(tildify(rec.root))}`));
      }
      if (drift.modified.length > 0) {
        console.log(info(`${rec.target}: 직접 수정한 파일 ${drift.modified.length}개는 그대로 둔다`));
      }
    }

    if (!opts.force) {
      console.log(dim(broken > 0 ? "  사라진 파일을 복구하려면 --force" : "  강제로 다시 쓰려면 --force"));
      return broken > 0 ? 1 : 0;
    }
  }

  for (const rec of manifest.installs) {
    console.log(info(`${rec.target} (${rec.scope}) ${dim(tildify(rec.root))} — ${rec.version} → ${version}`));
    const outcomes = await runInstall({
      targets: [rec.target],
      scope: rec.scope,
      force: opts.force,
    });
    printOutcomes(outcomes);
  }
  return 0;
}
