import { __ } from '@wordpress/i18n';

const UNKNOWN_ERROR_CODE = 'unknown_error';
const UNKNOWN_HTTP_STATUS = 0;

export type ApiErrorBody = {
	code: string;
	message: string;
	httpStatus: number;
};

function isRecord( value: unknown ): value is Record< string, unknown > {
	return typeof value === 'object' && value !== null;
}

function readText( record: Record< string, unknown >, key: string ): string {
	const text = record[ key ];

	if ( typeof text !== 'string' ) {
		return '';
	}

	return text;
}

function readHttpStatus( record: Record< string, unknown > ): number {
	const errorData = record.data;

	if ( ! isRecord( errorData ) ) {
		return UNKNOWN_HTTP_STATUS;
	}

	const httpStatus = errorData.status;

	if ( typeof httpStatus !== 'number' ) {
		return UNKNOWN_HTTP_STATUS;
	}

	return httpStatus;
}

export function readApiErrorBody( thrownValue: unknown ): ApiErrorBody {
	if ( ! isRecord( thrownValue ) ) {
		return { code: '', message: '', httpStatus: UNKNOWN_HTTP_STATUS };
	}

	return {
		code: readText( thrownValue, 'code' ),
		message: readText( thrownValue, 'message' ),
		httpStatus: readHttpStatus( thrownValue ),
	};
}

export class ApiError extends Error {
	readonly code: string;
	readonly httpStatus: number;

	constructor( body: ApiErrorBody ) {
		const fallbackMessage = __(
			'The server did not answer. Please try again.',
			'aiplaz-link-checkup'
		);

		super( body.message === '' ? fallbackMessage : body.message );
		this.name = 'ApiError';
		this.code = body.code === '' ? UNKNOWN_ERROR_CODE : body.code;
		this.httpStatus = body.httpStatus;
	}
}
