/** Fleet node groups — persisted in localStorage, shared across Roster + Crucible. */

export interface FleetGroup {
  id: string;
  name: string;
  color: string;
  agentIds: string[];
  createdAt: string;
}

export const FLEET_GROUP_COLORS = [
  '#00f5ff',
  '#39ff14',
  '#ff2da6',
  '#b24bf3',
  '#ffb020',
  '#ff6b35',
  '#00d4aa',
  '#3a86ff',
  '#f72585',
  '#ffd60a',
  '#06d6a0',
  '#e63946',
] as const;

export const FLEET_GROUPS_STORAGE_KEY = 'aetherforge_fleet_groups';
export const FLEET_GROUPS_CHANGED_EVENT = 'aetherforge-fleet-groups-changed';

export function normalizeGroupColor(color: string): string {
  const c = color.trim();
  if (/^#[0-9A-Fa-f]{6}$/.test(c)) return c;
  if (/^#[0-9A-Fa-f]{3}$/.test(c)) {
    const r = c[1];
    const g = c[2];
    const b = c[3];
    return `#${r}${r}${g}${g}${b}${b}`;
  }
  return FLEET_GROUP_COLORS[0];
}

export function loadFleetGroups(): FleetGroup[] {
  try {
    const raw = localStorage.getItem(FLEET_GROUPS_STORAGE_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw) as unknown;
    if (!Array.isArray(parsed)) return [];
    return parsed
      .map((g) => {
        if (!g || typeof g !== 'object') return null;
        const o = g as Record<string, unknown>;
        const name = typeof o.name === 'string' ? o.name.trim() : '';
        if (!name) return null;
        const agentIds = Array.isArray(o.agentIds)
          ? [...new Set(o.agentIds.filter((id): id is string => typeof id === 'string' && id.length > 0))]
          : [];
        return {
          id: typeof o.id === 'string' && o.id ? o.id : `fg-${Date.now()}`,
          name,
          color: normalizeGroupColor(typeof o.color === 'string' ? o.color : FLEET_GROUP_COLORS[0]),
          agentIds,
          createdAt: typeof o.createdAt === 'string' ? o.createdAt : new Date().toISOString(),
        } satisfies FleetGroup;
      })
      .filter((g): g is FleetGroup => g !== null);
  } catch {
    return [];
  }
}

export function saveFleetGroups(groups: FleetGroup[]): void {
  localStorage.setItem(FLEET_GROUPS_STORAGE_KEY, JSON.stringify(groups));
  window.dispatchEvent(new Event(FLEET_GROUPS_CHANGED_EVENT));
}

export function createFleetGroup(name: string, color: string, agentIds: string[]): FleetGroup {
  return {
    id: `fg-${crypto.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`}`,
    name: name.trim(),
    color: normalizeGroupColor(color),
    agentIds: [...new Set(agentIds)],
    createdAt: new Date().toISOString(),
  };
}

/** Groups that contain this agent (preserves group list order). */
export function groupsForAgent(groups: FleetGroup[], agentId: string): FleetGroup[] {
  return groups.filter((g) => g.agentIds.includes(agentId));
}

/** First group color for an agent (roster stripe / Crucible accent). */
export function primaryGroupForAgent(groups: FleetGroup[], agentId: string): FleetGroup | undefined {
  return groups.find((g) => g.agentIds.includes(agentId));
}

export function notifyFleetGroupsChanged(): void {
  window.dispatchEvent(new Event(FLEET_GROUPS_CHANGED_EVENT));
}
