import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import { showNotification } from '@mantine/notifications';
import { jwtDecode } from 'jwt-decode';
import Cookies from 'js-cookie';
import { Box } from '@mantine/core';
import { __ } from '@wordpress/i18n';

import { setUser } from '../../store/auth/userSlice';
import { linkedinSignIn, getLinkedinAuthUrl } from '../../services/AuthService';
import { onSignInSuccess, setLoggedInUser, setToken, setXWpNonce } from '../../store/auth/sessionSlice';
import appConfig from '../../configs/app.config';

const POPUP_WIDTH = 600;
const POPUP_HEIGHT = 700;
const MESSAGE_TYPE = 'lazytask-linkedin-oauth';

const LoginWithLinkedIn = () => {
    const dispatch = useDispatch();
    const navigate = useNavigate();
    const socialLoginConfiguration = useSelector((state) => state.settings.setting.socialLoginConfiguration);
    const [isLoading, setIsLoading] = useState(false);
    const popupRef = useRef(null);
    const expectedStateRef = useRef(null);
    const redirectUriRef = useRef(null);

    const clientId = socialLoginConfiguration?.linkedin?.client_id || '';
    const redirectUri = `${appConfig.liveApiUrl}/linkedin/callback`;

    const completeLogin = async (code, state) => {
        const result = await linkedinSignIn({
            code,
            redirect_uri: redirectUriRef.current || redirectUri,
            state,
        });

        if (!result || result.status !== 200 || result.code !== 'is_valid' || !result.token) {
            const errorMsg = result?.message || result?.error || __('Something went wrong', 'lazytasks-project-task-management');
            showNotification({
                title: __('Login Failed', 'lazytasks-project-task-management'),
                message: errorMsg,
                color: 'red',
            });
            return;
        }

        const { token, nonce } = result;
        if (token) {
            dispatch(onSignInSuccess(token));
            dispatch(setToken(token));
            dispatch(setXWpNonce(nonce));
            const decode_token = jwtDecode(token);
            if (decode_token.iss === appConfig.liveSiteUrl) {
                const userData = decode_token.data;

                const user = {
                    "authority": userData.roles,
                    "loggedUserId": userData.user_id,
                    "name": userData.name,
                    "email": userData.email,
                    "roles": userData.roles,
                    "llc_roles": userData.llc_roles,
                    "llc_permissions": userData.llc_permissions,
                    "avatar": userData.avatar,
                    "is_superadmin": userData.is_superadmin ?? false,
                    "project_roles": userData.project_roles || []
                };
                dispatch(setLoggedInUser(user || {}));
                Cookies.set('user_id', userData.user_id);
                dispatch(
                    setUser(
                        user || {
                            avatar: '',
                            loggedUserId: '',
                            name: '',
                            authority: [],
                            email: '',
                            roles: [],
                            llc_roles: [],
                            llc_permissions: [],
                        }
                    )
                );
                navigate(appConfig.authenticatedEntryPath);
                return result;
            }
        }
    };

    useEffect(() => {
        const handleMessage = (event) => {
            // Only accept messages from our own origin (the popup callback page is same-origin).
            if (event.origin !== appConfig.liveSiteUrl) {
                return;
            }
            const data = event.data || {};
            if (data.type !== MESSAGE_TYPE) {
                return;
            }

            if (data.error) {
                showNotification({
                    title: __('Login Failed', 'lazytasks-project-task-management'),
                    message: data.error_description || data.error,
                    color: 'red',
                });
                setIsLoading(false);
                return;
            }

            const { code, state } = data;
            if (!code || !state) {
                showNotification({
                    title: __('Login Failed', 'lazytasks-project-task-management'),
                    message: __('LinkedIn did not return an authorization code.', 'lazytasks-project-task-management'),
                    color: 'red',
                });
                setIsLoading(false);
                return;
            }

            // Reject any state value that doesn't match the one we initiated this flow with.
            if (expectedStateRef.current && state !== expectedStateRef.current) {
                showNotification({
                    title: __('Login Failed', 'lazytasks-project-task-management'),
                    message: __('Invalid state parameter — possible CSRF attempt.', 'lazytasks-project-task-management'),
                    color: 'red',
                });
                setIsLoading(false);
                return;
            }

            setIsLoading(false);
            completeLogin(code, state);
        };

        window.addEventListener('message', handleMessage);
        return () => window.removeEventListener('message', handleMessage);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    const handleClick = async () => {
        if (isLoading) return;
        setIsLoading(true);

        const authResp = await getLinkedinAuthUrl(redirectUri);
        if (!authResp || authResp.status !== 200 || !authResp.auth_url) {
            showNotification({
                title: __('Login Failed', 'lazytasks-project-task-management'),
                message: authResp?.message || __('Could not start LinkedIn login.', 'lazytasks-project-task-management'),
                color: 'red',
            });
            setIsLoading(false);
            return;
        }

        expectedStateRef.current = authResp.state;
        redirectUriRef.current = redirectUri;

        const left = window.screenX + (window.outerWidth - POPUP_WIDTH) / 2;
        const top = window.screenY + (window.outerHeight - POPUP_HEIGHT) / 2;
        popupRef.current = window.open(
            authResp.auth_url,
            'lazytask-linkedin-oauth',
            `width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top}`
        );

        if (!popupRef.current) {
            showNotification({
                title: __('Popup Blocked', 'lazytasks-project-task-management'),
                message: __('Please allow popups for this site to log in with LinkedIn.', 'lazytasks-project-task-management'),
                color: 'red',
            });
            setIsLoading(false);
        }
    };

    if (!clientId) {
        return null;
    }

    return (
        <Box
            style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                width: '100%',
            }}
        >
            <button
                type="button"
                onClick={handleClick}
                disabled={isLoading}
                style={{
                    backgroundColor: '#0A66C2',
                    color: '#fff',
                    fontSize: '14px',
                    fontWeight: 500,
                    padding: '10px 16px',
                    border: 'none',
                    borderRadius: '4px',
                    cursor: isLoading ? 'wait' : 'pointer',
                    width: '100%',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    gap: '8px',
                    opacity: isLoading ? 0.7 : 1,
                }}
            >
                <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
                    <path d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.86 0-2.14 1.45-2.14 2.95v5.66H9.34V9h3.41v1.56h.05c.48-.9 1.64-1.85 3.38-1.85 3.61 0 4.28 2.38 4.28 5.47v6.27ZM5.34 7.43a2.06 2.06 0 1 1 0-4.13 2.06 2.06 0 0 1 0 4.13Zm1.78 13.02H3.55V9h3.57v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0Z" />
                </svg>
                {isLoading ? __('Connecting…', 'lazytasks-project-task-management') : __('Continue with LinkedIn', 'lazytasks-project-task-management')}
            </button>
        </Box>
    );
};

export default LoginWithLinkedIn;
