import { appConfig } from './appConfig';
import { agentRegistryEntry, AGENT_ACTIONS } from './agentTypes';
import { joinUrl, toWebSocketUrl } from './httpPaths';

export default class ShireScanForgeAgentClient {
  constructor({ apiBaseUrl, getToken } = {}) {
    this.apiBaseUrl = apiBaseUrl ?? appConfig.shireApiBaseUrl;
    this.getToken = getToken || (() => null);
  }

  async request(path, options = {}) {
    const token = this.getToken();
    const headers = { Accept: 'application/json', ...(options.body ? { 'Content-Type': 'application/json' } : {}), ...(options.headers || {}) };
    if (token) headers.Authorization = `Bearer ${token}`;
    const response = await fetch(joinUrl(this.apiBaseUrl, path), {
      credentials: 'same-origin',
      ...options,
      headers
    });
    if (response.status === 401 || response.status === 403) throw new Error('SHIRE_SESSION_EXPIRED');
    if (!response.ok) throw new Error(`SHIRE_AGENT_REQUEST_FAILED (${response.status})`);
    return response.status === 204 ? null : response.json();
  }

  getMetadata() { return this.request('/api/v1/agents/scanforge'); }
  getStatus() { return this.request('/api/v1/agents/scanforge/status'); }
  getCapabilities() { return this.request('/api/v1/agents/scanforge/capabilities'); }
  start() { return this.request('/api/v1/agents/scanforge/start', { method: 'POST' }); }
  stop() { return this.request('/api/v1/agents/scanforge/stop', { method: 'POST' }); }
  restart() { return this.request('/api/v1/agents/scanforge/restart', { method: 'POST' }); }
  listProjects() { return this.request('/api/v1/agents/scanforge/projects'); }
  listJobs() { return this.request('/api/v1/agents/scanforge/jobs'); }

  performAction(action) {
    if (!AGENT_ACTIONS.includes(action?.action)) throw new Error('UNSUPPORTED_AGENT_ACTION');
    return this.request('/api/v1/agents/scanforge/actions', { method: 'POST', body: JSON.stringify(action) });
  }

  agentSocket() {
    const token = this.getToken();
    const protocols = token ? [`shire-bearer.${token}`] : [];
    return new WebSocket(toWebSocketUrl(this.apiBaseUrl, '/ws/v1/agents/scanforge'), protocols);
  }

  static registryEntry() { return agentRegistryEntry; }
}
