'use strict';

import {generateUUID, chunkArray} from "./utils";

let asset =  function() {
    return {
        getAssetList:  ({type = 'instanceType', instanceType, assetType, size = 20, startKey = null, roomId, ids}) => {
			return chunkArray(ids, 50)
				.reduce((promiseChain, idsChunk) => {
					return promiseChain.then(chainResponse => {
						let apiParams = {
							type,
							...(instanceType && {instanceType: instanceType === true ? this.__instanceType : instanceType }),
							...(assetType && {assetType}),
							...(size && !ids && {size}),
							...(idsChunk?.length && {ids: idsChunk.join(',')}),
							...(roomId && {roomId}),
							...(startKey && {startKey})
						};
						return this.__privates.auth.__client
							.then(client => client.apis.asset.getAssetList(apiParams))
							.then(response => type === 'ids' ? ({
								data: {
									items: [...chainResponse.data.items, ...response.data.items],
									size: chainResponse.data.size + response.data.size,
									startKey: null,
								},
							}) : response);
					});
				}, Promise.resolve({data: {items: [], size: 0, startKey: null}}));
        },
		getAssetById: (id) => {
			return this.__privates.auth.__client
				.then(client => client.apis.asset.getAssetById({id}))
		},
        updateAsset: ({id, assetType, title, roomIds, customAttributes, encodeTransparency} = {}) => {
            return this.__privates.auth.__client
                .then(client => client.apis.asset.updateAsset({id}, {requestBody:{assetType, title, roomIds, customAttributes, encodeTransparency}}))
        },
        deleteAsset: (id) => {
            return this.__privates.auth.__client
                .then(client => client.apis.asset.deleteAsset({id}))
        },

		initiateAssetUpload: (id = null) => {
			return this.__privates.auth.__client
				.then(client => client.apis.asset.initiateAssetUpload())
		},

		uploadAsset: (file, roomIds, id = null, initiationData = null, assetData = null) => {
			return this.__privates.auth.__client
				.then(client => Promise.all([client, initiationData ? Promise.resolve(initiationData) : client.apis.asset.initiateAssetUpload({id: id || generateUUID()})]))
				.then(([client, response]) => Promise.all([client, client.http({url: response.data.signedUrl, method: response.data.httpMethod, headers: {"Content-Type":file.type}, body:file}), response.data.id]))
				.then(([client, response, idn]) => Promise.all([client.apis.asset.publishAsset({id:idn}, {requestBody: {title: file.name, ...(roomIds ? {roomIds} : {}), ...(assetData ? assetData : {})}}), idn]))
				;
		},

		uploadAssetWithProgress: (file, roomIds, id = null, initiationData = null, assetData = null, onProgress = null) => {
			return this.__privates.auth.__client
				.then(client => Promise.all([client, initiationData ? Promise.resolve(initiationData) : client.apis.asset.initiateAssetUpload({id: id || generateUUID()})]))
				.then(([client, response]) => {
					return new Promise((resolve, reject) => {
						const xhr = new XMLHttpRequest();

						// Set up progress tracking
						if (onProgress && xhr.upload) {
							xhr.upload.onprogress = (event) => {
								if (event.lengthComputable) {
									onProgress(event.loaded, event.total);
								}
							};
						}

						xhr.onload = () => {
							if (xhr.status >= 200 && xhr.status < 300) {
								resolve([client, { status: xhr.status, responseText: xhr.responseText }, response.data.id]);
							} else {
								reject(new Error(`Upload failed with status ${xhr.status}`));
							}
						};

						xhr.onerror = () => reject(new Error('Upload failed'));

						// Open and send the request
						xhr.open(response.data.httpMethod, response.data.signedUrl, true);
						xhr.setRequestHeader('Content-Type', file.type);
						xhr.send(file);
					});
				})
				.then(([client, response, idn]) =>
					Promise.all([
						client.apis.asset.publishAsset(
							{id: idn},
							{requestBody: {
									title: file.name,
									...(roomIds ? {roomIds} : {}),
									...(assetData ? assetData : {})
								}}
						),
						idn
					])
				);
		},

	    downloadAsset: (url, options = {}) => {
		    return this.__privates.auth.__client
			    .then(client => client.http({url, method: 'GET', ...options}))
	    },

		createStreamAsset: (id, title, streamType, regionalPreference, ingestType, source, profile) => {
			return this.__privates.auth.__client
				.then(client => client.apis.asset.publishAsset({id}, {requestBody: {assetType: 'stream', title, stream: {streamType, regionalPreference, ingestType, source, profile}}}));
	    },

		createHighlightAsset: (id, title, roomIds, highlight = {}) => {
			return this.__privates.auth.__client
				.then(client => client.apis.asset.publishAsset({id}, {requestBody: {assetType: 'highlight',...(roomIds ? {roomIds} : {}), title, customAttributes: {highlight}}}));
	    },

		createHighlightAssetWithThumbnail: (file, id, title, roomIds, highlight = {}, initiationData = null) => {
			return this.__privates.auth.__client
				.then(client => Promise.all([client, initiationData ? Promise.resolve(initiationData) : client.apis.asset.initiateAssetUpload({id: id || generateUUID()})]))
				.then(([client, response]) => Promise.all([client, client.http({url: response.data.signedUrl, method: response.data.httpMethod, headers: {"Content-Type":file.type}, body:file}), response.data.id]))
				.then(([client, response, idn]) => Promise.all([client.apis.asset.publishAsset({id:idn}, {requestBody: {assetType: 'highlight', title: title, ...(roomIds ? {roomIds} : {}), customAttributes: {highlight}}}), idn]))
				;
		},
    }
};

export default asset;
