"use strict";

const fs = require("fs");
const path = require("path");

const { GLOBAL_CLAUDE_DIR, PACKAGE_ROOT } = require("./constants");
const {
  log,
  logHeader,
  logSuccess,
  logWarning,
  logError,
} = require("./logging");
const { writeSettingsAtomic } = require("./fs-utils");
const { stripECKSettings, ECK_STYLE_FILES } = require("./cleanup");
const { installSkills, installAssets } = require("./install-phases");
const { registerSettingsEntries } = require("./settings");

function resolveDisabledMarker(globalDir) {
  return path.join(globalDir, "evolv-coder-kit", ".disabled");
}

function updateGlobalState(globalDir, fields) {
  const statePath = path.join(
    globalDir,
    "evolv-coder-kit",
    "global-state.json",
  );
  if (!fs.existsSync(statePath)) return;
  let existing = {};
  try {
    existing = JSON.parse(fs.readFileSync(statePath, "utf-8"));
  } catch (err) {
    logWarning(`Could not update global-state.json: ${err.message}`);
    return;
  }
  const updated = Object.assign({}, existing, fields);
  const content = JSON.stringify(updated, null, 2) + "\n";
  const tmp = statePath + ".tmp";
  fs.writeFileSync(tmp, content, "utf-8");
  fs.renameSync(tmp, statePath);
}

function disableECK({ dryRun = false, globalDir = GLOBAL_CLAUDE_DIR } = {}) {
  const kitDir = path.join(globalDir, "evolv-coder-kit");
  const markerPath = resolveDisabledMarker(globalDir);

  if (fs.existsSync(markerPath)) {
    return {
      success: true,
      alreadyDisabled: true,
      removedSkills: 0,
      removedHooks: 0,
      removedOutputModes: 0,
      strippedSettings: 0,
      dryRun,
    };
  }

  logHeader("Disabling ECK");
  log("Removing ECK runtime surface (state preserved — reverse with --enable)");
  log("");

  let removedSkills = 0;
  let removedHooks = 0;
  let removedOutputModes = 0;
  let strippedSettings = 0;

  // 1. Remove skills/eck-* directories
  const skillsDir = path.join(globalDir, "skills");
  try {
    if (fs.existsSync(skillsDir)) {
      const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
      for (const entry of entries) {
        if (entry.isDirectory() && entry.name.startsWith("eck-")) {
          const dirPath = path.join(skillsDir, entry.name);
          if (!dryRun) {
            fs.rmSync(dirPath, { recursive: true, force: true });
          }
          removedSkills++;
        }
      }
    }
  } catch (err) {
    logWarning(`Could not process skills: ${err.message}`);
  }

  // 2. Remove hooks/evolv-* files
  const hooksDir = path.join(globalDir, "hooks");
  try {
    if (fs.existsSync(hooksDir)) {
      const entries = fs.readdirSync(hooksDir);
      for (const entry of entries) {
        if (entry.startsWith("evolv-")) {
          const filePath = path.join(hooksDir, entry);
          if (!dryRun) {
            fs.rmSync(filePath, { force: true });
          }
          removedHooks++;
        }
      }
    }
  } catch (err) {
    logWarning(`Could not process hooks: ${err.message}`);
  }

  // 3. Remove ECK-owned output mode files
  const modesDir = path.join(globalDir, "output-modes");
  try {
    if (fs.existsSync(modesDir)) {
      const entries = fs.readdirSync(modesDir);
      for (const entry of entries) {
        if (ECK_STYLE_FILES.includes(entry)) {
          const filePath = path.join(modesDir, entry);
          if (!dryRun) {
            fs.rmSync(filePath, { force: true });
          }
          removedOutputModes++;
        }
      }
    }
  } catch (err) {
    logWarning(`Could not process output-modes: ${err.message}`);
  }

  // 4. Strip ECK settings
  const settingsPath = path.join(globalDir, "settings.json");
  try {
    if (fs.existsSync(settingsPath)) {
      let raw;
      try {
        raw = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
      } catch {
        raw = null;
      }
      if (raw) {
        const { settings: stripped, stripped: count } = stripECKSettings(raw);
        strippedSettings = count;
        if (count > 0 && !dryRun) {
          writeSettingsAtomic(settingsPath, stripped);
        }
      }
    }
  } catch (err) {
    logWarning(`Could not strip settings.json: ${err.message}`);
  }

  if (!dryRun) {
    // 5. Write .disabled marker
    fs.mkdirSync(kitDir, { recursive: true });
    const pkg = require(path.join(PACKAGE_ROOT, "package.json"));
    const marker = {
      schemaVersion: 1,
      disabledAt: new Date().toISOString(),
      version: pkg.version,
    };
    fs.writeFileSync(
      markerPath,
      JSON.stringify(marker, null, 2) + "\n",
      "utf-8",
    );

    // 6. Update global-state.json
    updateGlobalState(globalDir, { enabled: false });

    logSuccess(
      `Disabled: ${removedSkills} skills, ${removedHooks} hooks, ${removedOutputModes} output modes, ${strippedSettings} settings entries`,
    );
    log("Run evolv-coder-kit --enable to restore.");
  }

  return {
    success: true,
    alreadyDisabled: false,
    removedSkills,
    removedHooks,
    removedOutputModes,
    strippedSettings,
    dryRun,
  };
}

function enableECK({ dryRun = false, globalDir = GLOBAL_CLAUDE_DIR } = {}) {
  const markerPath = resolveDisabledMarker(globalDir);

  if (!fs.existsSync(markerPath)) {
    return { success: true, alreadyEnabled: true, dryRun };
  }

  logHeader("Enabling ECK");
  log("Restoring ECK runtime surface");
  log("");

  let skillsResult, assetsResult, settingsResult;
  try {
    skillsResult = installSkills({
      overwrite: false,
      dryRun,
      silent: true,
    });
  } catch (err) {
    logError(`Failed to enable ECK (installSkills): ${err.message}`);
    return {
      success: false,
      error: err.message,
      phase: "installSkills",
      dryRun,
    };
  }
  try {
    assetsResult = installAssets({
      overwrite: false,
      dryRun,
      silent: true,
    });
  } catch (err) {
    logError(`Failed to enable ECK (installAssets): ${err.message}`);
    return {
      success: false,
      error: err.message,
      phase: "installAssets",
      dryRun,
    };
  }
  try {
    settingsResult = registerSettingsEntries({
      dryRun,
      globalDir,
      silent: true,
    });
  } catch (err) {
    logError(`Failed to enable ECK (registerSettingsEntries): ${err.message}`);
    return {
      success: false,
      error: err.message,
      phase: "registerSettingsEntries",
      dryRun,
    };
  }

  if (!dryRun) {
    fs.rmSync(markerPath, { force: true });
    updateGlobalState(globalDir, { enabled: true });
    logSuccess("ECK re-enabled.");
  }

  return {
    success: true,
    alreadyEnabled: false,
    restored: {
      skills: skillsResult,
      assets: assetsResult,
      settings: settingsResult,
    },
    dryRun,
  };
}

module.exports = { disableECK, enableECK };
