import 'dart:convert';

import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';

import 'auth_api.dart';
import 'share_api.dart';
import 'sync_api.dart';

Handler buildApiHandler({
  AuthApi? authApi,
  SyncApi? syncApi,
  ShareApi? shareApi,
}) {
  final router = Router()
    ..get('/health', (Request request) {
      return Response.ok(
        jsonEncode({'status': 'ok'}),
        headers: {'content-type': 'application/json'},
      );
    });

  if (authApi != null) {
    router
      ..post('/auth/register', authApi.register)
      ..post('/auth/login', authApi.loginUser)
      ..post(
        '/auth/logout',
        authenticationMiddleware(authApi.authenticateRequest.execute)(
          authApi.logoutUser,
        ),
      );
  }

  if (syncApi != null) {
    router
      ..post(
        '/sync/push',
        authenticationMiddleware(syncApi.authenticateRequest.execute)(
          syncApi.push,
        ),
      )
      ..get(
        '/sync/pull',
        authenticationMiddleware(syncApi.authenticateRequest.execute)(
          syncApi.pull,
        ),
      )
      ..post(
        '/sync/exchange',
        authenticationMiddleware(syncApi.authenticateRequest.execute)(
          syncApi.exchange,
        ),
      );
  }

  if (shareApi != null) {
    router
      ..post(
        '/shares',
        authenticationMiddleware(shareApi.authenticateRequest.execute)(
          shareApi.create,
        ),
      )
      ..get(
        '/shares/inbox',
        authenticationMiddleware(shareApi.authenticateRequest.execute)(
          shareApi.inbox,
        ),
      )
      ..post(
        '/shares/<id>/accept',
        authenticationMiddleware(shareApi.authenticateRequest.execute)(
          (request) => shareApi.accept(request, request.params['id']!),
        ),
      )
      ..post(
        '/shares/<id>/decline',
        authenticationMiddleware(shareApi.authenticateRequest.execute)(
          (request) => shareApi.decline(request, request.params['id']!),
        ),
      )
      ..post(
        '/shares/<id>/revoke',
        authenticationMiddleware(shareApi.authenticateRequest.execute)(
          (request) => shareApi.revoke(request, request.params['id']!),
        ),
      );
  }

  return const Pipeline().addMiddleware(logRequests()).addHandler(router.call);
}
