#!/usr/bin/env node
import {
  getSkillDisplayLabel
} from "./chunk-INKJBMPJ.js";
import {
  resolveAlias
} from "./chunk-GFDGYQ6M.js";
import {
  typedEntries,
  typedKeys
} from "./chunk-T4EXUIBY.js";
import {
  warn
} from "./chunk-C4QI54PN.js";
import {
  DEFAULT_PRESELECTED_SKILLS,
  DEFAULT_PUBLIC_SOURCE_NAME
} from "./chunk-FTD5Z6QD.js";
import {
  init_esm_shims
} from "./chunk-DHET7RCE.js";

// src/cli/stores/wizard-store.ts
init_esm_shims();
import { unique } from "remeda";
import { create } from "zustand";
var BUILT_IN_DOMAINS = ["web", "api", "cli", "mobile", "shared"];
function getAllDomainsFromCategories(categories) {
  const allDomains = unique(
    Object.values(categories).map((cat) => cat?.domain).filter((d) => d != null)
  );
  return [...BUILT_IN_DOMAINS, ...allDomains.filter((d) => !BUILT_IN_DOMAINS.includes(d))];
}
var DOMAIN_AGENTS = {
  web: [
    "web-developer",
    "web-reviewer",
    "web-researcher",
    "web-tester",
    "web-pm",
    "web-architecture"
  ],
  api: ["api-developer", "api-reviewer", "api-researcher"],
  cli: ["cli-developer", "cli-tester", "cli-reviewer", "cli-migrator"]
};
var SOURCE_SORT_TIER_LOCAL = 1;
var SOURCE_SORT_TIER_SCOPED = 2;
var SOURCE_SORT_TIER_PUBLIC = 3;
var SOURCE_SORT_TIER_THIRD_PARTY = 4;
function getSourceSortTier(source) {
  if (source.type === "local") return SOURCE_SORT_TIER_LOCAL;
  if (source.primary) return SOURCE_SORT_TIER_SCOPED;
  if (source.type === "public") return SOURCE_SORT_TIER_PUBLIC;
  return SOURCE_SORT_TIER_THIRD_PARTY;
}
var SOURCE_DISPLAY_NAMES = {
  local: "Local"
};
function formatSourceLabel(source) {
  const displayName = SOURCE_DISPLAY_NAMES[source.name] ?? source.name;
  const prefix = source.installed ? "\u2713 " : "";
  return `${prefix}${displayName}`;
}
function resolveSkillForPopulation(skillId, skills, categories) {
  const skill = skills[skillId];
  if (!skill?.category) {
    warn(
      `Installed skill '${skillId}' is missing from the marketplace \u2014 it may have been removed or renamed`
    );
    return null;
  }
  const subcat = skill.category;
  const domain = categories[subcat]?.domain;
  if (!domain) {
    warn(`Installed skill '${skillId}' has unknown category '${skill.category}' \u2014 skipping`);
    return null;
  }
  return { domain, subcat, techId: skillId };
}
function buildBoundSkillOptions(boundSkills, alias, selectedSource) {
  return boundSkills.filter((b) => b.boundTo === alias).map((bound) => ({
    id: bound.sourceName,
    label: formatSourceLabel({
      name: bound.sourceName,
      installed: false
    }),
    selected: selectedSource === bound.sourceName,
    installed: false
  }));
}
function getSkillAlias(skillId, matrix) {
  const displayName = matrix.displayNames?.[skillId];
  if (displayName) return displayName;
  const segments = skillId.split("-");
  const fallback = segments[segments.length - 1] || skillId;
  warn(`No display name found for skill '${skillId}', using fallback alias '${fallback}'`);
  return fallback;
}
var createInitialState = () => ({
  step: "stack",
  approach: null,
  selectedStackId: null,
  stackAction: null,
  selectedDomains: [],
  currentDomainIndex: 0,
  domainSelections: {},
  showLabels: false,
  expertMode: false,
  installMode: "local",
  sourceSelections: {},
  customizeSources: false,
  showSettings: false,
  showHelp: false,
  enabledSources: {},
  selectedAgents: [],
  boundSkills: [],
  history: []
});
var useWizardStore = create((set, get) => ({
  ...createInitialState(),
  setStep: (step) => set((state) => ({
    step,
    history: [...state.history, state.step]
  })),
  setApproach: (approach) => set({ approach }),
  selectStack: (stackId) => set({ selectedStackId: stackId }),
  setStackAction: (action) => set({ stackAction: action }),
  populateFromStack: (stack, categories) => set(() => {
    const domainSelections = {};
    const domains = /* @__PURE__ */ new Set();
    for (const agentConfig of Object.values(stack.agents)) {
      for (const [subcat, assignments] of typedEntries(
        agentConfig
      )) {
        const category = categories[subcat];
        const domain = category?.domain;
        if (!domain || !assignments) {
          continue;
        }
        domains.add(domain);
        if (!domainSelections[domain]) {
          domainSelections[domain] = {};
        }
        if (!domainSelections[domain][subcat]) {
          domainSelections[domain][subcat] = [];
        }
        for (const assignment of assignments) {
          if (!domainSelections[domain][subcat].includes(assignment.id)) {
            domainSelections[domain][subcat].push(assignment.id);
          }
        }
      }
    }
    return {
      domainSelections,
      selectedDomains: getAllDomainsFromCategories(categories)
    };
  }),
  populateFromSkillIds: (skillIds, skills, categories) => set(() => {
    const domainSelections = {};
    let skippedCount = 0;
    for (const skillId of skillIds) {
      const resolved = resolveSkillForPopulation(skillId, skills, categories);
      if (!resolved) {
        skippedCount++;
        continue;
      }
      const { domain, subcat, techId } = resolved;
      if (!domainSelections[domain]) domainSelections[domain] = {};
      if (!domainSelections[domain][subcat]) domainSelections[domain][subcat] = [];
      if (!domainSelections[domain][subcat].includes(techId)) {
        domainSelections[domain][subcat].push(techId);
      }
    }
    if (skippedCount > 0) {
      warn(`${skippedCount} installed skill(s) could not be resolved and were skipped`);
    }
    const selectedDomains = typedKeys(domainSelections);
    return { domainSelections, selectedDomains };
  }),
  toggleDomain: (domain) => set((state) => {
    const isSelected = state.selectedDomains.includes(domain);
    if (isSelected) {
      const { [domain]: _removed, ...remainingSelections } = state.domainSelections;
      return {
        selectedDomains: state.selectedDomains.filter((d) => d !== domain),
        domainSelections: remainingSelections
      };
    }
    return {
      selectedDomains: [...state.selectedDomains, domain]
    };
  }),
  toggleTechnology: (domain, subcategory, technology, exclusive) => set((state) => {
    const currentSelections = state.domainSelections[domain]?.[subcategory] || [];
    const isSelected = currentSelections.includes(technology);
    let newSelections;
    if (exclusive) {
      newSelections = isSelected ? [] : [technology];
    } else {
      newSelections = isSelected ? currentSelections.filter((t) => t !== technology) : [...currentSelections, technology];
    }
    return {
      domainSelections: {
        ...state.domainSelections,
        [domain]: {
          ...state.domainSelections[domain],
          [subcategory]: newSelections
        }
      }
    };
  }),
  nextDomain: () => {
    const state = get();
    if (state.currentDomainIndex < state.selectedDomains.length - 1) {
      set({
        currentDomainIndex: state.currentDomainIndex + 1
      });
      return true;
    }
    return false;
  },
  prevDomain: () => {
    const state = get();
    if (state.currentDomainIndex > 0) {
      set({
        currentDomainIndex: state.currentDomainIndex - 1
      });
      return true;
    }
    return false;
  },
  toggleShowLabels: () => set((state) => ({ showLabels: !state.showLabels })),
  toggleExpertMode: () => set((state) => ({ expertMode: !state.expertMode })),
  toggleInstallMode: () => set((state) => ({
    installMode: state.installMode === "plugin" ? "local" : "plugin"
  })),
  setSourceSelection: (skillId, sourceId) => set((state) => {
    if (!skillId) {
      warn("Ignoring setSourceSelection call with empty skillId");
      return state;
    }
    if (!sourceId) {
      warn(`Ignoring setSourceSelection call with empty sourceId for skill '${skillId}'`);
      return state;
    }
    return {
      sourceSelections: { ...state.sourceSelections, [skillId]: sourceId }
    };
  }),
  setCustomizeSources: (customize) => set({ customizeSources: customize }),
  toggleSettings: () => set((state) => ({ showSettings: !state.showSettings })),
  toggleHelp: () => set((state) => ({ showHelp: !state.showHelp })),
  setEnabledSources: (sources) => {
    const invalidKeys = Object.keys(sources).filter((key) => !key.trim());
    if (invalidKeys.length > 0) {
      warn("Ignoring setEnabledSources call with empty source name(s)");
    }
    const validSources = Object.fromEntries(Object.entries(sources).filter(([key]) => key.trim()));
    return set({ enabledSources: validSources });
  },
  bindSkill: (skill) => set((state) => {
    const exists = state.boundSkills.some(
      (b) => b.id === skill.id && b.sourceUrl === skill.sourceUrl
    );
    if (exists) {
      warn(`Skill '${skill.id}' from '${skill.sourceUrl}' is already bound \u2014 skipping duplicate`);
      return state;
    }
    return { boundSkills: [...state.boundSkills, skill] };
  }),
  goBack: () => set((state) => {
    const history = [...state.history];
    const previousStep = history.pop();
    return {
      step: previousStep || "stack",
      history
    };
  }),
  toggleAgent: (agent) => set((state) => {
    const isSelected = state.selectedAgents.includes(agent);
    return {
      selectedAgents: isSelected ? state.selectedAgents.filter((a) => a !== agent) : [...state.selectedAgents, agent]
    };
  }),
  preselectAgentsFromDomains: () => set(() => {
    const agents = [];
    for (const domain of get().selectedDomains) {
      const domainAgents = DOMAIN_AGENTS[domain];
      if (domainAgents) {
        agents.push(...domainAgents);
      }
    }
    return { selectedAgents: agents.sort() };
  }),
  reset: () => set(createInitialState()),
  getAllSelectedTechnologies: () => {
    const state = get();
    const technologies = [];
    for (const domain of typedKeys(state.domainSelections)) {
      const domainSel = state.domainSelections[domain];
      if (!domainSel) continue;
      for (const subcategory of typedKeys(domainSel)) {
        const techs = domainSel[subcategory];
        if (techs) technologies.push(...techs);
      }
    }
    return technologies;
  },
  getSelectedTechnologiesPerDomain: () => {
    const state = get();
    const result = {};
    for (const domain of typedKeys(state.domainSelections)) {
      const domainSel = state.domainSelections[domain];
      if (!domainSel) continue;
      const techs = [];
      for (const subcategory of typedKeys(domainSel)) {
        const subTechs = domainSel[subcategory];
        if (subTechs) techs.push(...subTechs);
      }
      if (techs.length > 0) {
        result[domain] = techs;
      }
    }
    return result;
  },
  getCurrentDomain: () => {
    const state = get();
    return state.selectedDomains[state.currentDomainIndex] || null;
  },
  getDefaultMethodologySkills: () => {
    return [...DEFAULT_PRESELECTED_SKILLS];
  },
  getTechnologyCount: () => {
    return get().getAllSelectedTechnologies().length;
  },
  getStepProgress: () => {
    const state = get();
    const completed = [];
    const skipped = [];
    if (state.step !== "stack") {
      completed.push("stack");
    }
    if (state.approach === "stack" && state.selectedStackId && state.stackAction === "defaults") {
      skipped.push("build");
      skipped.push("sources");
      skipped.push("agents");
    } else if (state.step === "confirm") {
      completed.push("build");
      completed.push("sources");
      completed.push("agents");
    } else if (state.step === "agents") {
      completed.push("build");
      completed.push("sources");
    } else if (state.step === "sources") {
      completed.push("build");
    }
    return { completedSteps: completed, skippedSteps: skipped };
  },
  canGoToNextDomain: () => {
    const state = get();
    return state.currentDomainIndex < state.selectedDomains.length - 1;
  },
  canGoToPreviousDomain: () => {
    const state = get();
    return state.currentDomainIndex > 0;
  },
  buildSourceRows: (matrix) => {
    const state = get();
    const selectedTechnologies = get().getAllSelectedTechnologies();
    const { sourceSelections, boundSkills } = state;
    return selectedTechnologies.map((tech) => {
      const skillId = resolveAlias(tech, matrix);
      const skill = matrix.skills[skillId];
      const selectedSource = sourceSelections[skillId] || skill?.activeSource?.name || DEFAULT_PUBLIC_SOURCE_NAME;
      const alias = getSkillAlias(skillId, matrix);
      const displayLabel = skill ? getSkillDisplayLabel(skill) : skillId;
      const sortedSources = [...skill?.availableSources || []].sort(
        (a, b) => getSourceSortTier(a) - getSourceSortTier(b)
      );
      const options = sortedSources.length > 0 ? sortedSources.map((source) => ({
        id: source.name,
        label: formatSourceLabel({
          name: source.name,
          installed: source.installed
        }),
        selected: selectedSource === source.name,
        installed: source.installed
      })) : [
        {
          id: DEFAULT_PUBLIC_SOURCE_NAME,
          label: DEFAULT_PUBLIC_SOURCE_NAME,
          selected: selectedSource === DEFAULT_PUBLIC_SOURCE_NAME,
          installed: false
        }
      ];
      options.push(...buildBoundSkillOptions(boundSkills, alias, selectedSource));
      return { skillId, displayName: displayLabel, alias, options };
    });
  }
}));

export {
  useWizardStore
};
//# sourceMappingURL=chunk-SPSGZWTZ.js.map