import { ApiError, request, type Manga, type Page } from './client';

export type Collection = {
    id: string;
    user_id: string;
    name: string;
    description: string | null;
    created_at: string;
    updated_at: string;
};

/** Returned by `GET /v1/me/collections` — enriched for card rendering. */
export type CollectionSummary = Collection & {
    manga_count: number;
    /** Up to 3 cover image keys, newest-added first. */
    sample_covers: string[];
};

export type CollectionsPage = {
    items: CollectionSummary[];
    page: Page;
};

export type CollectionMangasPage = {
    items: Manga[];
    page: Page;
};

export type NewCollection = {
    name: string;
    description?: string | null;
};

export type CollectionPatch = {
    name?: string;
    description?: string | null;
};

export type ListMyOptions = { limit?: number; offset?: number };

export async function listMyCollections(
    opts: ListMyOptions = {}
): Promise<CollectionsPage> {
    const params = new URLSearchParams();
    if (opts.limit != null) params.set('limit', String(opts.limit));
    if (opts.offset != null) params.set('offset', String(opts.offset));
    const qs = params.toString();
    return request<CollectionsPage>(`/v1/me/collections${qs ? `?${qs}` : ''}`);
}

/** Empty page on 401 so guest-rendering pages don't have to special-case. */
export async function listMyCollectionsOrEmpty(): Promise<CollectionsPage> {
    try {
        return await listMyCollections();
    } catch (e) {
        if (e instanceof ApiError && e.status === 401) {
            return { items: [], page: { limit: 50, offset: 0, total: null } };
        }
        throw e;
    }
}

export async function createCollection(
    input: NewCollection
): Promise<Collection> {
    return request<Collection>('/v1/collections', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(input)
    });
}

export async function getCollection(id: string): Promise<Collection> {
    return request<Collection>(`/v1/collections/${encodeURIComponent(id)}`);
}

export async function updateCollection(
    id: string,
    patch: CollectionPatch
): Promise<Collection> {
    return request<Collection>(`/v1/collections/${encodeURIComponent(id)}`, {
        method: 'PATCH',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(patch)
    });
}

export async function deleteCollection(id: string): Promise<void> {
    await request<void>(`/v1/collections/${encodeURIComponent(id)}`, {
        method: 'DELETE'
    });
}

export async function listCollectionMangas(
    id: string,
    opts: ListMyOptions = {}
): Promise<CollectionMangasPage> {
    const params = new URLSearchParams();
    if (opts.limit != null) params.set('limit', String(opts.limit));
    if (opts.offset != null) params.set('offset', String(opts.offset));
    const qs = params.toString();
    return request<CollectionMangasPage>(
        `/v1/collections/${encodeURIComponent(id)}/mangas${qs ? `?${qs}` : ''}`
    );
}

export async function addMangaToCollection(
    collectionId: string,
    mangaId: string
): Promise<void> {
    await request<void>(
        `/v1/collections/${encodeURIComponent(collectionId)}/mangas`,
        {
            method: 'POST',
            headers: { 'content-type': 'application/json' },
            body: JSON.stringify({ manga_id: mangaId })
        }
    );
}

export async function removeMangaFromCollection(
    collectionId: string,
    mangaId: string
): Promise<void> {
    await request<void>(
        `/v1/collections/${encodeURIComponent(collectionId)}/mangas/${encodeURIComponent(mangaId)}`,
        { method: 'DELETE' }
    );
}

/** Which of the user's collections currently contain this manga. */
export async function getMyCollectionsContaining(
    mangaId: string
): Promise<string[]> {
    const r = await request<{ collection_ids: string[] }>(
        `/v1/mangas/${encodeURIComponent(mangaId)}/my-collections`
    );
    return r.collection_ids;
}
