import { useEffect, useState } from "react";
import { useSnackbarController } from "@firecms/core";
import { BuildIcon, Button, LoadingButton, Typography } from "@firecms/ui";
import { FireCMSBackend } from "../types";
import { useFireCMSBackend } from "../hooks";
import { useNavigate } from "react-router-dom";

export type CloudError = {
    code?: string,
    message: string,
    projectId?: string,
    data?: {
        missingPermissions?: string[],
        errorDetails?: object
    }
};

export function CloudErrorView({
                                   error,
                                   fireCMSBackend,
                                   onFixed,
                                   onRetry,
                                   allowServiceAccountBypass = false
                                }: {
    error: CloudError,
    fireCMSBackend?: FireCMSBackend,
    onFixed?: () => void,
    onRetry?: () => void,
    allowServiceAccountBypass?: boolean;
}) {
    const navigate = useNavigate();
    const {
        code,
        message,
        projectId
    } = error;

    if (code === "service-account-missing" && projectId && fireCMSBackend) {
        return <CloudMissingServiceAccountErrorView projectId={projectId}
                                                    fireCMSBackend={fireCMSBackend}
                                                    message={"Service account missing for this project. You need to link your project to a service account to use this feature."}
                                                    onFixed={onFixed}/>;
    } else if (code === "service-account-corrupt" && projectId && fireCMSBackend) {
        return <CloudMissingServiceAccountErrorView projectId={projectId}
                                                    fireCMSBackend={fireCMSBackend}
                                                    message={"The service account linked to this project is invalid. You need to link your project to a valid service account to use this feature. The user fixing the issue must have the appropriate permissions."}
                                                    onFixed={onFixed}/>;
    } else if (code === "user-has-to-accept-googles-terms-of-service" && projectId) {
        return <CloudNeedsToAcceptTermsErrorView projectId={projectId}
                                                 onFixed={onFixed}/>;
    } else if (code === "user-has-no-previous-firebase-projects" && projectId) {
        return <CloudNoPreviousFirebaseProjectsErrorView projectId={projectId}
                                                         onFixed={onFixed}/>;
    } else if (code === "firecms-user-not-found") {
        return <div className="flex flex-col space-y-2 py-4">
            <Typography>
                The user trying to log in is not registered in the client project.
            </Typography>
            <Typography>
                Make sure the user exists in the client project and try again.
                If the problem persists, reach us at <a className="text-primary dark:text-primary-light underline" href="mailto:hello@firecms.co?subject=FireCMS%20login%20error"
                                                        rel="noopener noreferrer"
                                                        target="_blank">
                hello@firecms.co </a>, or in our <a
                className="text-primary dark:text-primary-light underline"
                rel="noopener noreferrer"
                target="_blank"
                href={"https://discord.gg/fxy7xsQm3m"}>Discord channel</a>.
            </Typography>
        </div>;
    } else if ((code === "service-account-missing-permissions" || code === "user-missing-permissions") && allowServiceAccountBypass) {
        return (
            <div className="flex flex-col space-y-4 p-6 border border-surface-200 dark:border-surface-700 rounded-xl bg-surface-50 dark:bg-surface-900">
                <Typography variant="h6" className="text-red-600 dark:text-red-400">
                    Missing Permissions
                </Typography>
                {error.data?.missingPermissions && <>
                    <Typography variant={"body2"} color={"secondary"}>
                        Your Google Cloud account is missing the following permissions on this project:
                    </Typography>
                    <Typography variant={"caption"} component={"ul"}>
                        {error.data.missingPermissions.map((permission) => <li key={permission}>
                            <code>{permission}</code>
                        </li>)}
                    </Typography>
                </>}
                <Typography variant="body2" className="font-semibold text-surface-900 dark:text-white">
                    💡 Recovery Option: You can bypass Google OAuth permissions entirely by using a Firebase Service Account JSON key.
                </Typography>
                <div className="flex flex-col sm:flex-row gap-3 pt-2">
                    <Button
                        variant="filled"
                        onClick={() => {
                            navigate("/new/sa");
                        }}
                    >
                        Connect via Service Account Key
                    </Button>
                    {onRetry && (
                        <Button
                            variant="text"
                            onClick={() => onRetry()}
                        >
                            Retry Setup
                        </Button>
                    )}
                </div>
            </div>
        );
    } else if (code === "service-account-missing-permissions" || code === "user-missing-permissions") {
        return <ServiceAccountMissingPermissions missingPermissions={error.data?.missingPermissions}/>;
    }


    const isPermissionError =
        (code === "permission-denied" ||
        code === "permission_denied" ||
        (message && message.toLowerCase().includes("permission")) ||
        (message && message.toLowerCase().includes("caller does not have"))) && allowServiceAccountBypass;
    if (isPermissionError) {
        return (
            <div className="flex flex-col space-y-4 p-6 border border-surface-200 dark:border-surface-700 rounded-xl bg-surface-50 dark:bg-surface-900">
                <Typography variant="h6" className="text-red-600 dark:text-red-400">
                    Google Cloud Permission Error
                </Typography>
                <Typography variant="body2" color="secondary">
                    {message}
                </Typography>
                <Typography variant="body2" color="secondary">
                    This error usually occurs because your Google Cloud account does not have sufficient permissions (like Owner or IAM Admin roles) to enable services or automatically generate a service account.
                </Typography>
                <Typography variant="body2" className="font-semibold text-surface-900 dark:text-white">
                    💡 Recovery Option: You can bypass Google OAuth permissions entirely by using a Firebase Service Account JSON key.
                </Typography>
                <div className="flex flex-col sm:flex-row gap-3 pt-2">
                    <Button
                        variant="filled"
                        onClick={() => {
                            navigate("/new/sa");
                        }}
                    >
                        Connect via Service Account Key
                    </Button>
                    {onRetry && (
                        <Button
                            variant="text"
                            onClick={() => onRetry()}
                        >
                            Retry Setup
                        </Button>
                    )}
                </div>
            </div>
        );
    }

    return (<div className="flex flex-col space-y-2">
            <Typography className="text-red-600 dark:text-red-400">
                {message}
            </Typography>

            {error.data && Object.keys(error.data).length > 0 && <pre className="text-xs text-gray-500 dark:text-gray-400 p-4 bg-gray-50 dark:bg-surface-800 rounded-lg">
                {JSON.stringify(error.data, null, 2)}
            </pre>}

            {onRetry && <Button

                color="error"
                onClick={() => onRetry()}
            >
                Retry
            </Button>}
        </div>
    );
}

function CloudMissingServiceAccountErrorView({
                                                 fireCMSBackend,
                                                 projectId,
                                                 onFixed,
                                                 message
                                             }: {
    fireCMSBackend: FireCMSBackend,
    projectId: string,
    onFixed?: () => void,
    message: string
}) {

    const { projectsApi } = useFireCMSBackend();

    const snackbarController = useSnackbarController();

    const [isSubmitting, setIsSubmitting] = useState(false);
    const [pendingLogin, setPendingLogin] = useState(false);

    const doCreateServiceAccount = async () => {
        if (!fireCMSBackend.googleCredential?.accessToken) {
            throw new Error("SassMissingServiceAccountErrorView: No access token found");
        }
        setIsSubmitting(true);
        return projectsApi.createServiceAccount(fireCMSBackend.googleCredential.accessToken, projectId, true)
            .finally(() => setIsSubmitting(false))
    };

    useEffect(() => {
        if (pendingLogin && fireCMSBackend.googleCredential?.accessToken) {
            doCreateServiceAccount().then(() => {
                snackbarController.open({
                    type: "success",
                    message: "Service account created successfully"
                });
                if (onFixed)
                    onFixed();
            }).catch(e => {
                snackbarController.open({
                    type: "error",
                    message: "Service account creation error: " + e.message
                });
            });
            setPendingLogin(false);
        }
    }, [pendingLogin, fireCMSBackend.googleCredential?.accessToken]);

    const onClick = async () => {
        const accessToken = fireCMSBackend.googleCredential?.accessToken;
        if (!accessToken) {
            setPendingLogin(true);
            fireCMSBackend.googleLogin(true);
        } else {
            await doCreateServiceAccount();
        }
    };
    return <div
        className="flex flex-col space-y-2 py-4">
        <Typography color={"error"}>
            {message}
        </Typography>
        <LoadingButton

            color="error"
            onClick={onClick}
            loading={isSubmitting}
            startIcon={<BuildIcon/>}
        >
            Fix
        </LoadingButton>
    </div>
}

function CloudNeedsToAcceptTermsErrorView({
                                              projectId,
                                              onFixed
                                          }: {
    projectId: string,
    onFixed?: () => void,
}) {

    return <div
        className="flex flex-col space-y-2 py-4">
        <Typography color={"error"}>
            You need to accept Google&apos;s terms of service
            before you can use this service.
        </Typography>

        <Typography color={"error"}>
            You can do so by visiting the following link:
            <a
                className="text-primary dark:text-primary-light underline"
                rel="noopener noreferrer"
                target="_blank"
                href={"https://console.cloud.google.com/welcome?project=" + projectId}>
                {`https://console.cloud.google.com/welcome?project=${projectId}`}
            </a>
        </Typography>
        <Button

            color="error"
            onClick={onFixed}
            startIcon={<BuildIcon/>}
        >
            I have accepted the terms
        </Button>
    </div>
}

function CloudNoPreviousFirebaseProjectsErrorView({
                                                      projectId,
                                                      onFixed
                                                  }: {
    projectId: string,
    onFixed?: () => void,
}) {

    return <div
        className="flex flex-col space-y-2 py-4">
        <Typography color={"error"}>
            You need to accept Firebase&apos;s terms of service
            before you can use this service.
        </Typography>

        <Typography color={"error"}>
            You can do so by visiting the following link:
            <a
                className="text-primary dark:text-primary-light underline"
                rel="noopener noreferrer"
                target="_blank"
                href={"https://console.firebase.google.com/"}>
                {"https://console.firebase.google.com/"}
            </a>
        </Typography>

        <Button

            color="error"
            onClick={onFixed}
            startIcon={<BuildIcon/>}
        >
            I have accepted the terms
        </Button>
    </div>
}

function ServiceAccountMissingPermissions(props: {
    missingPermissions: string[] | undefined,
}) {

    return <div
        className="flex flex-col space-y-2 py-4">

        <Typography color={"error"}>
            Missing permissions
        </Typography>

        {props.missingPermissions && <>
            <Typography variant={"body2"}>
                This service account is missing the following permissions:
            </Typography>

            <Typography variant={"caption"} component={"ul"}>
                {props.missingPermissions.map((permission) => <li key={permission}>
                    <code>{permission}</code>
                </li>)}
            </Typography>
        </>}

    </div>;
}
