/* eslint-disable @typescript-eslint/no-explicit-any */
import { IOp, ISnapshot } from "@mescius/js-collaboration-ot-client";
import { checkError, req } from "./req";
import { FileFilter, Role } from "../enum";
import { IUser } from "./user";

export interface IDoc {
    id: string;
    name: string;
    type: string;
    createUser: IUser;
    lastModifyUser: IUser;
    lastModifyDate: string;
    role?: Role;
}

async function create(type: string, name?: string, data?: string): Promise<IDoc> {
    const response = await req.post('docs/create', { name, type, data });
    const json = await response.json();

    checkError(response, json);

    return json;
}
async function uploadFile(file: any): Promise<IDoc> {
    const response = await req.upload('docs/upload', file);
    const json = await response.json();
    checkError(response, json);
    return json;
}

async function getFiles(filter: FileFilter): Promise<IDoc[]> {
    const response = await req.get('docs/all');
    let res = await response.json() as IDoc[];

    checkError(response, res);

    if (filter === FileFilter.my) {
        res = res.filter((r => r.role === Role.owner));
    } else if (filter === FileFilter.shared) {
        res = res.filter((r => r.role === Role.editor || r.role === Role.viewer));
    }

    return res.sort((item1: IDoc, item2: IDoc) => (new Date(item2.lastModifyDate) as any) - (new Date(item1.lastModifyDate) as any));
}

async function getOps(id: string): Promise<IOp[]> {
    const response = await req.get('docs/ops/' + id);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function getHistorySnapshot(id: string, version?: number): Promise<ISnapshot> {
    let url = `docs/history-snapshot/${id}`;
    if (version !== undefined) {
        url += `/${version}`
    }
    const response = await req.get(url);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function get(id: string): Promise<IDoc> {
    const response = await req.get('docs/' + id);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function deleteDoc(id: string): Promise<void> {
    const response = await req.get(`docs/delete/${id}`);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function createShareLink(id: string, role: Role): Promise<{ link: string }> {
    const response = await req.get(`docs/create-share-link/${id}/${role}`);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function openShareLink(link: string): Promise<{ docId: string, role: string }> {
    const response = await req.get(`docs/open-share-link/${link}`);
    const json = await response.json();

    checkError(response, json);

    return json;
}

export interface IDocUserRole {
    docId: string;
    userId: string;
    username: string;
    role: string;
}

async function getAccessUsers(docId: string): Promise<IDocUserRole[]> {
    const response = await req.get(`docs/users/${docId}`);
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function inviteUsers(docId: string, userIds: string[], role: Role): Promise<IDocUserRole[]> {
    const response = await req.post(`docs/invite-users`, { docId, userIds, role });
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function updateRole(docId: string, userId: string, role: Role): Promise<IDocUserRole[]> {
    const response = await req.post(`docs/update-user-role`, { docId, userId, role });
    const json = await response.json();

    checkError(response, json);

    return json;
}

async function rename(docId: string, name: string): Promise<IDocUserRole[]> {
    const response = await req.post(`docs/rename`, { docId, name });
    const json = await response.json();

    checkError(response, json);

    return json;
}

export const docReq = {
    create,
    get,
    getFiles,
    getOps,
    rename,
    getHistorySnapshot,
    open,
    uploadFile,
    delete: deleteDoc,
    createShareLink,
    openShareLink,
    getAccessUsers,
    inviteUsers,
    updateRole
};

(window as any).docReq = docReq;