/**
 * Connector-ramverk (spec §43). Gemensamt interface:
 * connect, authenticate, import, sync, disconnect, healthCheck.
 *
 * Juridisk grundregel (spec §26, §43, §61.11): endast lagliga API:er,
 * partnerflöden eller licensierade data. Ingen reverse engineering,
 * ingen scraping som kärnfunktion.
 */

export type ConnectorId =
  | "livsmedelsverket"
  | "open-food-facts"
  | "apple-health"
  | "health-connect"
  | "digital-receipts"
  | "future-retailers"
  | "future-smart-fridges"
  | "future-smart-ovens"
  | "future-scales";

export interface ConnectorHealth {
  ok: boolean;
  detail?: string;
  checkedAt: string;
}

export interface ConnectorContext {
  userId?: string;
  householdId?: string;
  credentials?: Record<string, string>;
}

export interface ImportResult<T = unknown> {
  items: T[];
  source: ConnectorId;
  importedAt: string;
  warnings: string[];
}

export interface Connector<TImport = unknown> {
  id: ConnectorId;
  nameSv: string;
  /** Juridisk status – en connector utan klar legal basis får inte aktiveras. */
  legalBasis: "open_data" | "licensed" | "user_consent_platform_api" | "agreement_pending";
  attributionSv?: string;

  connect(ctx: ConnectorContext): Promise<void>;
  authenticate(ctx: ConnectorContext): Promise<boolean>;
  importData(
    ctx: ConnectorContext,
    params?: Record<string, unknown>,
  ): Promise<ImportResult<TImport>>;
  sync(ctx: ConnectorContext): Promise<ImportResult<TImport>>;
  disconnect(ctx: ConnectorContext): Promise<void>;
  healthCheck(): Promise<ConnectorHealth>;
}

export class ConnectorRegistry {
  private connectors = new Map<ConnectorId, Connector>();

  register(connector: Connector): void {
    this.connectors.set(connector.id, connector);
  }

  get(id: ConnectorId): Connector | undefined {
    return this.connectors.get(id);
  }

  list(): Connector[] {
    return [...this.connectors.values()];
  }

  async healthCheckAll(): Promise<Record<string, ConnectorHealth>> {
    const result: Record<string, ConnectorHealth> = {};
    for (const c of this.connectors.values()) {
      result[c.id] = await c.healthCheck().catch((err) => ({
        ok: false,
        detail: err instanceof Error ? err.message : String(err),
        checkedAt: new Date().toISOString(),
      }));
    }
    return result;
  }
}
