import React, { useCallback, useEffect } from "react";
import { Dimensions } from "react-native";
import { WebView } from "react-native-webview";

import { InlineWidget } from "./components/InlineWidget";
import { ModalWidget } from "./components/ModalWidget";
import { OverlayWidget } from "./components/OverlayWidget";
import { WEB_VIEW_MESSAGE_LISTENER } from "./constants/Constants";
import type { SoluCXKey, WidgetCallbacks, WidgetData, WidgetOptions, WidgetType } from "./domain";
import { useWidget } from "./hooks/useWidget";
import { useWidgetBootstrap } from "./hooks/useWidgetBootstrap";
import { useWidgetServices } from "./hooks/useWidgetServices";

interface SoluCXWidgetProps {
    soluCXKey: SoluCXKey;
    type: WidgetType;
    data: WidgetData;
    options?: WidgetOptions;
    callbacks?: WidgetCallbacks;
}

const isWidgetType = (value?: string): value is WidgetType => {
    return value === "modal" || value === "inline" || value === "top" || value === "bottom";
};

export const SoluCXWidgetView: React.FC<SoluCXWidgetProps> = ({ soluCXKey, type, data, options, callbacks }) => {
    const { width } = Dimensions.get("window");

    const { widgetHeight, isWidgetVisible, resize, open, hide, userId, stateManager } = useWidget(soluCXKey, data, options);

    const { validationService, handleWebViewMessage } = useWidgetServices({
        hide,
        resize,
        userId,
        callbacks,
        data,
        stateManager,
    });

    const { widgetUri, widgetOptions, bootstrap } = useWidgetBootstrap({
        soluCXKey,
        data,
        userId,
        options,
        callbacks,
        open,
        hide,
        validationService,
        stateManager,
    });

    const resolvedType: WidgetType = isWidgetType(widgetOptions?.type) ? widgetOptions.type : type;
    const resolvedHeight = typeof widgetOptions?.height === "number" ? widgetOptions.height : widgetHeight;

    useEffect(() => {
        bootstrap();
    }, []);

    const handleClose = useCallback(async () => {
            hide();
            try {
                await stateManager.updateTimestamp("lastDismiss");
            } catch (error) {
                console.error("[SoluCXWidgetView] Error saving lastDismiss:", error);
            }
            callbacks?.onClosed?.();
        }, [hide, callbacks, stateManager]);

    if (!data) {
        callbacks?.onError?.("Widget data is required but was not provided");
        return null;
    }

    if (!widgetUri) {
        return null;
    }

    const webView = (
        <WebView
            style={[{ height: resolvedHeight }, { width }]}
            source={{ uri: widgetUri }}
            injectedJavaScript={WEB_VIEW_MESSAGE_LISTENER}
            onMessage={event => handleWebViewMessage(event.nativeEvent.data)}
            originWhitelist={["*"]}
        />
    );

    if (resolvedType === "modal") {
        return (
            <ModalWidget visible={isWidgetVisible} height={resolvedHeight} onClose={handleClose}>
                {webView}
            </ModalWidget>
        );
    }

    if (resolvedType === "inline") {
        return (
            <InlineWidget visible={isWidgetVisible} height={resolvedHeight} onClose={handleClose}>
                {webView}
            </InlineWidget>
        );
    }

    return (
        <OverlayWidget visible={isWidgetVisible} width={width} height={resolvedHeight} position={resolvedType} onClose={handleClose}>
            {webView}
        </OverlayWidget>
    );
};
