import type {Page, PageList} from "../types/page.ts";
import {fetchWithToken} from "./repo.ts";
import {PageListSchema, PageSchema} from "../types/page.ts";
import {bytesToBase64} from "../admin/util.ts";
import {z} from "zod";

export class PageRepo {
    constructor(private token: string) {}

    public async listPages(branch: string = "master"): Promise<PageList> {
        return await fetchWithToken(this.token, `/page?branch=${branch}`)
            .then(value => value.json())
            .then(PageListSchema.parse)
            .then(value => value.map(value1 => ({...value1, path: value1.path.replace("src/content/", "")})))
    }

    public async getPage(id: number, branch: string = "master"): Promise<Page> {
        return await fetchWithToken(this.token, `/page/${id}?branch=${branch}`)
            .then(value => value.json())
            .then(PageSchema.parse)
    }

    public async updatePage(id: number, content: string, sha: string, message: string, branch: string = "master"): Promise<void> {
        await fetchWithToken(this.token, `/page/${id}?branch=${branch}`, {
            method: "PUT",
            body: JSON.stringify({
                content: bytesToBase64(new TextEncoder().encode(content)),
                sha, message
            })
        })
    }

    public async getBranches(): Promise<string[]> {
        return await fetchWithToken(this.token, "/page/branch")
            .then(value => value.json())
            .then(value => z.array(z.string()).parse(value))
    }

    public async createBranch(branch: string): Promise<void> {
        await fetchWithToken(this.token, `/page/branch`, {method: "POST", body: JSON.stringify({branch})})
    }

    public async deleteBranch(branch: string): Promise<void> {
        await fetchWithToken(this.token, `/page/branch`, {method: "DELETE", body: JSON.stringify({branch})})
    }

    public async createFile(path: string, branch: string = "master"): Promise<void> {
        await fetchWithToken(this.token, `/page?branch=${branch}`, {method: "POST", body: JSON.stringify({path})})
    }

    public async merge(branch: string, message: string): Promise<void> {
        await fetchWithToken(this.token, `/page/branch/merge`, {method: "POST", body: JSON.stringify({branch, message})})
    }

    public async deletePage(id: number, message: string, sha: string, branch: string = "master"): Promise<void> {
        await fetchWithToken(this.token, `/page/${id}?branch=${branch}`, {method: "DELETE", body: JSON.stringify({message, sha})})
    }
}