import { Client } from '@vulog/aima-client';
import { createPaginableOptionsSchema, PaginableOptions, PaginableResponse } from '@vulog/aima-core';
import { z } from 'zod';

import { UserStatus } from './types';

// /users?page=0&size=50&sort=registrationDate%2CDESC&status=PENDING&profileType=Single&startDate=&endDate=&service=

const statusSchema = z.enum(['PENDING', 'INCOMPLETE', 'SUSPENDED', 'REJECTED', 'APPROVED']);
const profileTypeSchema = z.enum(['Single', 'Business']);
const userFiltersSchema = z.object({
    status: statusSchema.optional(),
    profileType: profileTypeSchema.optional(),
    serviceId: z.string().uuid().optional(),
});

const sortSchema = z.enum(['registrationDate', 'userName', 'firstName', 'lastName', 'updateDate']);
export type UserSort = z.infer<typeof sortSchema>;

export type UserFilters = z.infer<typeof userFiltersSchema>;

export const getUsers = async (
    client: Client,
    options?: PaginableOptions<UserFilters, UserSort>
): Promise<PaginableResponse<UserStatus>> => {
    const paginableOptionsSchema = createPaginableOptionsSchema(
        userFiltersSchema.default({}),
        sortSchema.optional().default('registrationDate')
    );

    const resultOptions = paginableOptionsSchema.safeParse(options ?? {});
    if (!resultOptions.success) {
        throw new TypeError('Invalid options', {
            cause: resultOptions.error.issues,
        });
    }

    const finalOptions = resultOptions.data;

    const searchParams = new URLSearchParams();
    searchParams.append('page', finalOptions.page!.toString());
    searchParams.append('size', finalOptions.pageSize!.toString());
    searchParams.append('sort', `${finalOptions.sort!.toString()},${finalOptions.sortDirection!.toString()}`);

    Object.entries(finalOptions.filters!).forEach(([key, value]) => {
        if (value === undefined) {
            return;
        }
        searchParams.append(key, value as string);
    });

    return client
        .get<UserStatus[]>(`/boapi/proxy/user/fleets/${client.clientOptions.fleetId}/users?${searchParams.toString()}`)
        .then(({ data, headers }) => {
            return {
                data,
                page: headers.number,
                pageSize: headers.size,
                total: headers.totalelements,
                totalPages: headers.totalpages,
            };
        });
};
