import type { ReactNode } from 'react';
import React from 'react';
import { BRAND_TITLES, DEFAULT_BRAND_TITLE } from '@theorchard/constants';
import { formatJsxMessage, formatMessage, hasMessage } from '@theorchard/suite-i18n';
import { clearAppStorage } from './storage';
import type { SuiteError } from '../types';
import type { FormatMessageArgs } from '@theorchard/suite-i18n';

export const ERROR_CODES = Object.freeze({
    GENERIC: 'generic',
    FAILED_TO_START: 'failedToStart',
});

export const getErrorCode = ({ code }: SuiteError) => code || ERROR_CODES.GENERIC;

export const formatErrorMessage = (code: string, brand: string, params: FormatMessageArgs) => {
    if (code === 'impersonationFailed' || code === 'noImpersonationAccess')
        return formatJsxMessage(`error_${code}_message`, {
            guidebook: ({ children }: { children?: React.ReactNode }) => (
                <a href="https://www.notion.so/Impersonation-guidebook-5e4e154591c04dfeae6119f55c556170">
                    {children}
                </a>
            ),
        });
    if (hasMessage(`errors.${code}_message_${brand}`))
        return formatMessage(`errors.${code}_message_${brand}`, params);
    if (hasMessage(`errors.${code}_message`))
        return formatMessage(`errors.${code}_message`, params);
    if (hasMessage(`error_${code}_message_${brand}`))
        return formatMessage(`error_${code}_message_${brand}`, params);
    if (hasMessage(`error_${code}_message`)) return formatMessage(`error_${code}_message`, params);
    return formatMessage('error_generic_message');
};

export const formatErrorTitle = (code: string, brand: string, params: FormatMessageArgs) => {
    if (hasMessage(`errors.${code}_title_${brand}`))
        return formatMessage(`errors.${code}_title_${brand}`, params);
    if (hasMessage(`errors.${code}_title`)) return formatMessage(`errors.${code}_title`, params);
    if (hasMessage(`error_${code}_title_${brand}`))
        return formatMessage(`error_${code}_title_${brand}`, params);
    if (hasMessage(`error_${code}_title`)) return formatMessage(`error_${code}_title`, params);
    return formatMessage('error_generic_title');
};

export const reloadApp = () => {
    window.location.replace('/');
};

const defaultRetryHandler = () => {
    clearAppStorage();
    reloadApp();
};

interface SuiteErrorInfo {
    code: string;
    message: ReactNode;
    title: string;
    retry: (() => void) | false;
}

export const getErrorInfo = (error: SuiteError, brand: string, appName: string): SuiteErrorInfo => {
    const code = getErrorCode(error);
    const params = {
        appName,
        brand: BRAND_TITLES[brand] ?? DEFAULT_BRAND_TITLE,
    };

    const title = formatErrorTitle(code, brand, params);
    const message = formatErrorMessage(code, brand, params);
    const retry = error.retry ?? defaultRetryHandler;

    return {
        code,
        message,
        title,
        retry,
    };
};
