/* eslint-disable @typescript-eslint/no-floating-promises */
import { Octokit } from '@octokit/rest';
import { Content } from '../models/github-model';
import {
	GetResponseTypeFromEndpointMethod,
	GetResponseDataTypeFromEndpointMethod
} from '@octokit/types';
import { EditorView } from 'prosemirror-view';
import { getWebEditorAttributes } from '../utils/getAttributes';
import { Node as ProsemirrorNode } from 'prosemirror-model';
import { relativeToAbsolute } from '../utils/fileHandlers';
import { getPosParam, images } from '../models/editor-model';
import { updateImagesMap } from '../imageHandlers/updateImageMap';
import { getGitHubPersonalAccessToken } from './fetch';

export const githubApi = 'https://api.github.com';
const octokit = new Octokit();
type GetRepoResponseType = GetResponseTypeFromEndpointMethod<typeof octokit.repos.get>;
type GetRepoResponseDataType = GetResponseDataTypeFromEndpointMethod<typeof octokit.repos.get>;

export async function listGitHubImages(org: string, repo: string) {
	const { data } = await octokit.request('GET /search/code', {
		q: `q=repo:${org}/${repo}+extension:png+extension:jpg+extension:jpeg+extension:gif+extension:bmp`
	});
	if (data) {
		return data;
	}
	return null;
}

export async function getRepo(org: string, repo: string) {
	const token = await getGitHubPersonalAccessToken();
	const octokit = new Octokit({
		auth: token
	});
	const { data } = (await octokit.request(`GET /repos/${org}/${repo}`, {
		owner: org,
		repo
	})) as GetRepoResponseType;
	if (data) {
		return data as GetRepoResponseDataType;
	}
	return null;
}

export async function fetchImageFromGitHub(
	org: string,
	repo: string,
	branch: string,
	fileName: string
) {
	const token = await getGitHubPersonalAccessToken();
	const octokit = new Octokit({
		auth: token
	});
	const { data } = await octokit.rest.repos.getContent({
		owner: org,
		repo,
		path: fileName,
		ref: branch ? branch : (await getRepo(org, repo)).default_branch
	});

	if (data) {
		const { name, content } = data as Content;
		const extension = name.split('.').pop();
		// data:image/jpeg;base64,<data>
		const image = `data:image/${extension};base64,${content}`;
		return image.replace(/\n/g, '');
	}
	return null;
}

export function getImageFromGitHubAndSetSrc(
	view: EditorView,
	getPos: getPosParam,
	node: ProsemirrorNode,
	updateNode: (view: EditorView, getPos: getPosParam, attributes: any) => void,
	id: number
): void {
	const src = node.attrs.src as string;
	const alt = node.attrs.alt as string;
	const { repo, org, path, branch } = getWebEditorAttributes();
	const fileName = relativeToAbsolute(path, src);
	fetchImageFromGitHub(org, repo, branch, fileName).then(imageResponse => {
		updateImagesMap(images, src, {
			data: imageResponse,
			file: null,
			id: id.toString()
		});
		updateNode(view, getPos, { src: imageResponse, alt });
	});
}
