import { getDataSource } from '../db/database';
import {
  CommandType,
  QueryType,
  AuthUserPayload,
  ServerPayload,
  JoinRequestPayload
} from './types';
import { handleRegisterUser } from './commands/handlers/registerUser';
import { handleUpsertServer } from './commands/handlers/upsertServer';
import { handleDeleteServer } from './commands/handlers/deleteServer';
import { handleCreateJoinRequest } from './commands/handlers/createJoinRequest';
import { handleUpdateJoinRequestStatus } from './commands/handlers/updateJoinRequestStatus';
import { handleDeleteStaleJoinRequests } from './commands/handlers/deleteStaleJoinRequests';
import { handleGetUserByUsername } from './queries/handlers/getUserByUsername';
import { handleGetUserById } from './queries/handlers/getUserById';
import { handleGetAllPublicServers } from './queries/handlers/getAllPublicServers';
import { handleGetFeaturedServers } from './queries/handlers/getFeaturedServers';
import { handleGetTrendingServers } from './queries/handlers/getTrendingServers';
import { handleGetServerById } from './queries/handlers/getServerById';
import { handleGetJoinRequestById } from './queries/handlers/getJoinRequestById';
import { handleGetPendingRequestsForServer } from './queries/handlers/getPendingRequestsForServer';
import { handleUpdateUserPasswordHash } from './commands/handlers/updateUserPasswordHash';
import { handleUpdateUserSigningPublicKey } from './commands/handlers/updateUserSigningPublicKey';

export const registerUser = (user: AuthUserPayload) =>
  handleRegisterUser({ type: CommandType.RegisterUser, payload: { user } }, getDataSource());

export const upsertServer = (server: ServerPayload) =>
  handleUpsertServer({ type: CommandType.UpsertServer, payload: { server } }, getDataSource());

export const deleteServer = (serverId: string) =>
  handleDeleteServer({ type: CommandType.DeleteServer, payload: { serverId } }, getDataSource());

export const createJoinRequest = (request: JoinRequestPayload) =>
  handleCreateJoinRequest({ type: CommandType.CreateJoinRequest, payload: { request } }, getDataSource());

export const updateJoinRequestStatus = (requestId: string, status: JoinRequestPayload['status']) =>
  handleUpdateJoinRequestStatus({ type: CommandType.UpdateJoinRequestStatus, payload: { requestId, status } }, getDataSource());

export const deleteStaleJoinRequests = (maxAgeMs: number) =>
  handleDeleteStaleJoinRequests({ type: CommandType.DeleteStaleJoinRequests, payload: { maxAgeMs } }, getDataSource());

export const getUserByUsername = (username: string) =>
  handleGetUserByUsername({ type: QueryType.GetUserByUsername, payload: { username } }, getDataSource());

export const getUserById = (userId: string) =>
  handleGetUserById({ type: QueryType.GetUserById, payload: { userId } }, getDataSource());

export const getAllPublicServers = () =>
  handleGetAllPublicServers(getDataSource());

export const getFeaturedServers = (limit?: number) =>
  handleGetFeaturedServers(getDataSource(), limit);

export const getTrendingServers = (limit?: number) =>
  handleGetTrendingServers(getDataSource(), limit);

export const getServerById = (serverId: string) =>
  handleGetServerById({ type: QueryType.GetServerById, payload: { serverId } }, getDataSource());

export const getJoinRequestById = (requestId: string) =>
  handleGetJoinRequestById({ type: QueryType.GetJoinRequestById, payload: { requestId } }, getDataSource());

export const getPendingRequestsForServer = (serverId: string) =>
  handleGetPendingRequestsForServer({ type: QueryType.GetPendingRequestsForServer, payload: { serverId } }, getDataSource());

export const updateUserPasswordHash = (userId: string, passwordHash: string) =>
  handleUpdateUserPasswordHash(getDataSource(), userId, passwordHash);

export const updateUserSigningPublicKey = (userId: string, signingPublicKey: string) =>
  handleUpdateUserSigningPublicKey(getDataSource(), userId, signingPublicKey);
