import { Platform } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import { config } from '~/config';
import i18n from '~/locale/i18n';
import {
	handleRequestData,
	jsonToURLEncoded,
} from './helper';

import settings from './settings';
import network from './network';
import auth from './auth';
import assistance from './assistance';
import imagePicker from './imagePicker';

const HTTP_STATUS = {
	BAD_GATEWAY: 502,
};

const fetcher = (fetchPromise, timeout) => {
	const abortPromise = new Promise((resolve, reject) => {
		setTimeout(() => reject(new Error(i18n.t('common.noInternetConnection'))), timeout);
	});
	const abortablePromise = Promise.race([
		fetchPromise,
		abortPromise,
	]);
	return abortablePromise;
};

const fetchPromise = (url, reqCfg) =>
	new Promise((resolve, reject) => {
		fetch(url, reqCfg).then((response) =>
			resolve(response))
			.then((jsonData) => {
				resolve(jsonData);
			}).catch((err) => {
				reject(err);
			});
	});

export const callApi = (method, url, callCfg = {}) => {
	const {
		token = null,
		data = null,
		params = null,
		headers,
		baseUrl = config.urls.mobileApi,
		...otherCfg
	} = callCfg;
	const reqCfg = {
		method,
		headers: {
			'content-type': 'application/json',
			source: 'mobile',
			appVersion: DeviceInfo.getVersion(),
			deviceModel: DeviceInfo.getModel(),
			devicePlatform: Platform.OS,
			devicePlatformVersion: Platform.Version,
			...headers,
		},
		...otherCfg,
	};
	if (token && typeof token === 'string') {
		reqCfg.headers.Authorization = `Bearer ${token}`;
	}
	if (data !== null) {
		reqCfg.body = handleRequestData(reqCfg.headers['content-type'], data);
	}
	const query = (params !== null) ? `?${jsonToURLEncoded(params)}` : '';
	console.log('here callApi config', `${baseUrl}${url}${query}`, reqCfg);
	return fetcher(fetchPromise(`${baseUrl}${url}${query}`, reqCfg), config.network.fetchTimeout)
		.then(async (res) => {
			if (res.status === HTTP_STATUS.BAD_GATEWAY) return Promise.reject(new Error(i18n.t('common.errorOccured')));
			// console.log('here callApi', url, ' result', res);
			const responseText = await res.text();
			console.log('here callApi', url, ' responseText', responseText);
			let responseJson;
			try {
				responseJson = responseText ? JSON.parse(responseText) : '';
			} catch (e) {
				return Promise.reject(new Error(i18n.t('common.errorOccured')));
			}
			if (!res.ok) {
				return Promise.reject(responseJson);
			}
			return responseJson;
		}).catch((err) => Promise.reject(err));
};

export const API = {
	settings: settings(callApi),
	auth: auth(callApi),
	assistance: assistance(callApi),
	network: network(),
	imagePicker: imagePicker(),
};
