import { z } from 'zod';

export type PaginableOptions<T = void, S = string> = T extends void
    ? {
          page?: number;
          pageSize?: number;
          sort?: S;
          sortDirection?: 'ASC' | 'DESC';
      }
    : {
          page?: number;
          pageSize?: number;
          sort?: S;
          sortDirection?: 'ASC' | 'DESC';
          filters?: T;
      };

export const createPaginableOptionsSchema = <T extends z.ZodTypeAny, S extends z.ZodTypeAny>(
    optionsSchema?: T,
    sortSchema: S = z.string().optional() as unknown as S
) => {
    return z.object({
        page: z.number().int().nonnegative().default(0),
        pageSize: z.number().int().positive().lte(1000).default(100),
        sort: sortSchema,
        sortDirection: z.enum(['ASC', 'DESC']).optional().default('ASC'),
        ...(optionsSchema ? { filters: optionsSchema } : {}),
    });
};

export type PaginableResponse<T> = {
    data: T[];
    page: number;
    pageSize: number;
    total: number;
    totalPages: number;
};

export type PatchAction<T extends string> =
    | {
          op: 'add' | 'replace';
          path: T;
          value: string;
      }
    | {
          op: 'remove';
          path: T;
      };
