import type { Hono } from 'hono';
import type { CryptoProvider } from '@shade/core';
import { createPrekeyRoutes } from './routes.js';
import { MemoryPrekeyStore } from './memory-store.js';
import type { PrekeyStore } from './store.js';
import type { PrekeyServerEvents } from './events.js';
import {
  KeyTransparencyService,
  type KeyTransparencyConfig,
} from './kt-integration.js';

export { createPrekeyRoutes } from './routes.js';
export { MemoryPrekeyStore } from './memory-store.js';
export type { PrekeyStore } from './store.js';
export { verifyPayload, signPayload, canonicalizePayload, validateAddress } from './auth.js';
export { KeyTransparencyService, encodeSthForWire, encodeProofForWire } from './kt-integration.js';
export type { KeyTransparencyConfig } from './kt-integration.js';
export { createKTRoutes } from './kt-routes.js';

/**
 * Create a standalone Shade Prekey Server.
 *
 * Requires a CryptoProvider for signature verification on write routes.
 *
 * Standalone:
 *   const crypto = new SubtleCryptoProvider();
 *   const server = createPrekeyServer({ crypto });
 *   export default { port: 3900, fetch: server.fetch };
 *
 * Embedded in another Hono app:
 *   const app = new Hono();
 *   app.route('/shade', createPrekeyServer({ crypto }));
 */
export function createPrekeyServer(options: {
  crypto: CryptoProvider;
  store?: PrekeyStore;
  disableRateLimit?: boolean;
  events?: PrekeyServerEvents;
  /** Existing KT service (already initialized via `KeyTransparencyService.create`). */
  keyTransparency?: KeyTransparencyService;
}): Hono {
  const store = options.store ?? new MemoryPrekeyStore();
  const routesOptions: Parameters<typeof createPrekeyRoutes>[2] = {};
  if (options.disableRateLimit !== undefined) {
    routesOptions.disableRateLimit = options.disableRateLimit;
  }
  if (options.events !== undefined) {
    routesOptions.events = options.events;
  }
  if (options.keyTransparency !== undefined) {
    routesOptions.keyTransparency = options.keyTransparency;
  }
  return createPrekeyRoutes(store, options.crypto, routesOptions);
}

/**
 * Convenience: create both the KT service and the prekey server in one call.
 * Async because `KeyTransparencyService.create` reads existing state.
 */
export async function createPrekeyServerWithKT(options: {
  crypto: CryptoProvider;
  store?: PrekeyStore;
  disableRateLimit?: boolean;
  events?: PrekeyServerEvents;
  keyTransparency: KeyTransparencyConfig;
}): Promise<{ app: Hono; kt: KeyTransparencyService }> {
  const kt = await KeyTransparencyService.create(options.crypto, options.keyTransparency);
  const passOpts: Parameters<typeof createPrekeyServer>[0] = {
    crypto: options.crypto,
    keyTransparency: kt,
  };
  if (options.store !== undefined) passOpts.store = options.store;
  if (options.disableRateLimit !== undefined) passOpts.disableRateLimit = options.disableRateLimit;
  if (options.events !== undefined) passOpts.events = options.events;
  const app = createPrekeyServer(passOpts);
  return { app, kt };
}

export { RateLimiter, MemoryRateLimitStore } from './rate-limit.js';
export type { RateLimitStore, RateLimitConfig } from './rate-limit.js';
export { PrekeyServerEvents, shortHash as serverShortHash } from './events.js';
export type { PrekeyServerEvent, PrekeyServerEventName, PrekeyServerEventMap, PrekeyServerEventListener } from './events.js';
