import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import { APP_SETTINGS, BRAND_DOMAINS, ENV_PROD } from '@theorchard/constants';
import { AUTH_ERROR_CODES } from '@theorchard/suite-auth';
import { Button } from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-i18n';
import { Illustration } from '@theorchard/suite-icons';
import { type Application } from '@theorchard/suite-identity';
import { Page } from '../../components/page';
import { clearAppStorage } from '../../utils';
import { getErrorInfo, reloadApp } from '../../utils/error';
import { CLASSNAME } from './constants';
import { ResetPasswordForm } from './resetPasswordForm';
import { VerifyEmailButton } from './verifyEmailButton';
import type { SuiteError } from '../../types';
import type { AuthClient } from '@theorchard/suite-auth';
import type { SuiteAppConfig } from '@theorchard/suite-config';
import { ImpersonationBanner } from '../../components/bannersContainer/impersonationBanner';

interface FatalErrorPageProps {
    error: SuiteError;
    authClient?: AuthClient;
    config: SuiteAppConfig;
}

const getSettingsApp = (brand: string, environment: string): Application | undefined => {
    const domain = BRAND_DOMAINS[brand]?.[environment];

    if (!domain) return undefined;

    const url = domain.startsWith('localhost')
        ? `http://${domain}/overview`
        : `https://settings.${domain}/overview`;

    return {
        id: APP_SETTINGS,
        name: 'Settings',
        url,
    };
};

const getAutomaticRedirectApp = (error: SuiteError, brand: string, environment: string) => {
    const allApplications = error.identity?.applications ?? [];

    if (!allApplications.length) return undefined;

    const appsExceptSettings = allApplications?.filter((app) => app.id !== APP_SETTINGS) ?? [];

    if (!appsExceptSettings.length) return undefined;

    return appsExceptSettings.length === 1
        ? appsExceptSettings[0]
        : getSettingsApp(brand, environment);
};

const AutomaticRedirectToApp = ({ app }: { app: Application }) => {
    const [countdown, setCountdown] = useState(5);

    useEffect(() => {
        if (countdown <= 0) {
            window.location.assign(app.url);
            return;
        }

        setTimeout(() => {
            setCountdown(countdown - 1);
        }, 1000);
    });

    return (
        <div className={`${CLASSNAME}-automatic-redirect`}>
            {formatMessage('error_redirecting_to_app', {
                app: app.name,
                countdown,
            })}
        </div>
    );
};

export const FatalErrorPage: FC<FatalErrorPageProps> = ({ error, authClient, config }) => {
    useEffect(() => {
        if (config.environment !== ENV_PROD) console.error(error);
    }, [error, config.environment]);

    const handleLogout = () => {
        clearAppStorage();
        if (authClient) void authClient.logout();
        else reloadApp();
    };

    const { appName, appTitle, brand, environment } = config;

    const { title, message, code, retry } = getErrorInfo(error, brand, appTitle || appName);

    const automaticRedirectTo =
        code === AUTH_ERROR_CODES.NO_ACCESS && getAutomaticRedirectApp(error, brand, environment);

    return (
        <>
            {error.identity?.impersonatedBy && <ImpersonationBanner identity={error.identity} />}
            <Page className={CLASSNAME} testId={CLASSNAME}>
                <Page.Body className={`${CLASSNAME}-body`}>
                    <Illustration name="fatalError" />
                    <h1>{title}</h1>
                    <div className={`${CLASSNAME}-content`}>
                        <p className={`${CLASSNAME}-message`}>{message}</p>

                        {automaticRedirectTo && (
                            <AutomaticRedirectToApp app={automaticRedirectTo} />
                        )}

                        {code === AUTH_ERROR_CODES.PASSWORD_EXPIRED && <ResetPasswordForm />}

                        <div className={`${CLASSNAME}-actions`}>
                            {retry && (
                                <Button
                                    onClick={() => {
                                        retry();
                                    }}
                                >
                                    {formatMessage('error_retry')}
                                </Button>
                            )}
                            {code === AUTH_ERROR_CODES.UNVERIFIED_EMAIL && (
                                <VerifyEmailButton environment={config.environment} error={error} />
                            )}
                        </div>
                        <Button
                            onClick={handleLogout}
                            variant="quartenary"
                            className={`${CLASSNAME}-back-button`}
                        >
                            {formatMessage('error_backToLogin')}
                        </Button>
                    </div>
                </Page.Body>
            </Page>
        </>
    );
};
