import React, { useEffect, useState } from 'react';
import Header from './header';
import Footer from './footer';
import './common.css';
import { useMediaQuery } from 'react-responsive';

type PageStep = 'otp' | 'qr' | 'success';

type CredentialOfferingState = {
    uri: string;
    preAuthCode: string;
    attemptsLeft: number;
    error?: string;
};

type CredentialOfferingError = {
    message: string;
    error: string;
    statusCode: number;
}

const acceptInvitation = async (iid: string, otp: string): Promise<CredentialOfferingState> => {
    if (!iid || iid.trim().length === 0) {
        return {
            uri: '',
            preAuthCode: '',
            attemptsLeft: -1,
            error: 'No invitation ID provided',
        }
    }

    const headers = new Headers();
    headers.append("Content-Type", "application/json");

    const body = JSON.stringify({ iid, otp });
    const options: RequestInit = {
        method: 'POST',
        headers,
        body,
        redirect: 'follow'
    };

    try {
        const url = `${import.meta.env.MODE === 'production' ? '__VITE_CLAIM_API__' : import.meta.env.VITE_CLAIM_API}`;
        console.log('Calling the credential issuance service: ' + url);
        const response: Response = await fetch(url, options);
        if (response.status === 201) {
            const state: CredentialOfferingState = await response.json();
            if (state.attemptsLeft >= 0) {
                state.error = `Invalid OTP, attempts left ${state?.attemptsLeft}`;
            }
            return state;
        } else {
            const error: CredentialOfferingError = await response.json();
            return {
                uri: '',
                preAuthCode: '',
                attemptsLeft: -1,
                error: error.message,
            }
        }
    } catch (error: any) {
        console.log('Error calling the credential issuance service: ' + JSON.stringify(error));
        return {
            uri: '',
            preAuthCode: '',
            attemptsLeft: -1,
            error: 'Error calling the credential issuance service',
        }
    }
}

const checkOfferingStatus = async (offeringId: string) => {
    const headers = new Headers();
    headers.append("Content-Type", "application/json");

    const body = JSON.stringify({ id: offeringId });
    const options: RequestInit = {
        method: 'POST',
        headers,
        body,
        redirect: 'follow'
    };

    const response: Response = await fetch(import.meta.env.MODE === 'production' ? '__VITE_STATUS_API__' : import.meta.env.VITE_STATUS_API, options);
    return await response.json();
};

const QRCodeComponent: React.FC<{ data: string }> = ({ data }) => {
    const size = 250;
    const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(data)}`;
    return <img src={qrUrl} alt="QR Code" width={size} height={size} />;
};

const OnboardingPage: React.FC = () => {
    const [pageStep, setPageStep] = useState<PageStep>('otp');
    const [iid, setIid] = useState<string>("");
    const [otp, setOtp] = useState("");
    const [otpValid, setOtpValid] = useState<boolean | null>(null);
    const [otpFeedback, setOtpFeedback] = useState<string>("");
    const [offeringState, setOfferingState] = useState<CredentialOfferingState | null>(null);
    const [showConfirmModal, setShowConfirmModal] = useState<boolean>(false);
    const isTabletOrMobile = useMediaQuery({ query: "(max-width: 767px)" });

    // Extract "iid" parameter on mount.
    useEffect(() => {
        const params = new URLSearchParams(window.location.search);
        const iidParam = params.get("iid");
        if (iidParam) {
            setIid(iidParam);
        }
    }, []);

    // Handle OTP input changes, enforcing only digits and a max of 5 characters.
    const handleOtpChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        const value = e.target.value;
        // Allow only digits.
        if (!/^\d*$/.test(value)) return;
        // Enforce a max length of 5.
        if (value.length > 5) return;
        setOtp(value);
    };

    // Adjust the regex if you need to allow OTPs with a leading zero.
    const isValidOtp = /^[1-9]\d{4}$/.test(otp);

    // Keep track of OTP validity.
    useEffect(() => {
        setOtpValid(isValidOtp);
    }, [otp, isValidOtp]);

    // When the user clicks "Claim!", show confirmation modal if OTP is valid
    const handleClaim = () => {
        if (!isValidOtp) {
            setOtpFeedback("Invalid OTP. Please enter a valid 5-digit positive integer.");
            return;
        }
        setOtpFeedback(""); // clear old feedback
        setShowConfirmModal(true);
    };

    // Handle confirmation modal actions
    const handleConfirmClaim = () => {
        setShowConfirmModal(false);
        verify();
    };

    const handleCancelClaim = () => {
        setShowConfirmModal(false);
    };

    // Verify OTP and, if valid, proceed to the QR step.
    const verify = async () => {
        const state: CredentialOfferingState = await acceptInvitation(iid, otp);
        setOfferingState(state);
        if (state.error) {
            setOtpValid(false);
        } else {
            setOtpValid(true);
            setPageStep('qr');
        }
    };

    // Poll for credential issuance status during the QR step.
    useEffect(() => {
        if (pageStep !== 'qr' || !offeringState) return;
        const intervalId = setInterval(async () => {
            try {
                const status: any = await checkOfferingStatus(offeringState.preAuthCode);
                if (status.status === "CREDENTIAL_ISSUED") {
                    clearInterval(intervalId);
                    setPageStep('success');
                } else if (status.status === "ERROR") {
                    clearInterval(intervalId);
                    alert("Error calling credential issuance service: " + status.error);
                }
            } catch (error: any) {
                clearInterval(intervalId);
                alert("Error polling credential issuance service: " + error.message);
            }
        }, 1000);
        return () => clearInterval(intervalId);
    }, [pageStep, offeringState]);

    if (pageStep === 'otp') {
        return (
            <>
                <Header />
                <div className="main-container">
                    {/* TOP CONTENT */}
                    <div className="top-content">
                        <h1 className="full-width-center-text" style={{ marginBottom: "8px" }}>
                            Claim your FAME Onboarding Credential *
                        </h1>
                        <p className="full-width-center-text" style={{ marginBottom: "20px" }}>
                            A one-time-password (OTP) has been sent to you.
                            To submit your claim, please insert your OTP in the field below:
                        </p>

                        <div className="form-container">
                            <input
                                type="text"
                                placeholder="Enter OTP"
                                value={otp}
                                onChange={handleOtpChange}
                                className="enabled"
                                maxLength={5}
                            />
                            <button className="claim-button" onClick={handleClaim}>
                                Claim!
                            </button>
                            <p className="invalid-otp-message">
                                {otpFeedback || (otpValid === false && offeringState?.error)}
                            </p>
                        </div>

                        {/* Confirmation Modal */}
                        {showConfirmModal && (
                            <div className="modal-overlay">
                                <div className="modal-content">
                                    <h3>Confirm Credential Claim</h3>
                                    <p>
                                        You are about to claim your FAME Onboarding Credential.<br></br>
                                        <b>To complete the process, you need to have the FAME Identity Wallet app running on your personal device.</b><br></br>
                                        Please confirm that you want to proceed further: once started, the process must be completed within a few minutes.<br></br>
                                        <i>Failure to do so will result in the invitation expiring and you will have to request a new one!</i>
                                    </p>
                                    <div className="modal-buttons">
                                        <button className="cancel-button" onClick={handleCancelClaim}>
                                            Not now
                                        </button>
                                        <button className="confirm-button" onClick={handleConfirmClaim}>
                                            Lets go!
                                        </button>
                                    </div>
                                </div>
                            </div>
                        )}

                        <p className="resend-otp">
                            Your invitation has expired? Need a new OTP? Contact the{" "}
                            <a href="mailto:support@fame-horizon.eu" style={{ color: "#051523" }}>
                                FAME Support Team
                            </a>{" "}
                            to get a new invitation.
                        </p>
                    </div>

                    {/* BOTTOM CONTENT */}
                    <div className="bottom-content">
                        <p className="footnote">
                            <strong>* Important!</strong> To proceed further, you need the
                            <strong>FAME Identity Wallet</strong> app to be already installed
                            on your <u>Android</u> device - iOS is not supported yet, sorry.<br />
                            The FAME Identity Wallet is used to securely store and manage your
                            FAME Onboarding Credential. The app cannot be installed from the
                            Google Play Store: instead, you need to download the APK file
                            and install it manually, and also disable any future automated uodates.
                            The full procedure is explained in detail on the{" "}
                            <a href="https://marketplace.fame-horizon.eu/about-us" target="_blank">FAME Marketplace website</a>,
                            under the "Onboard Organization & Users" section. Read those instructions
                            carefully, because there  are some critical steps to be followed.
                        </p>
                    </div>
                </div>
                <Footer />
            </>
        );
    } else if (pageStep === 'qr' && offeringState) {
        return (
            <>
                <Header />
                <div className="main-container">
                    <h1 className="full-width-center-text" style={{ marginBottom: "12px" }}>
                        Activate your FAME Identity Wallet
                    </h1>
                    <p className="full-width-center-text" style={{ marginBottom: "30px" }}>
                        Scan the QR Code below with your FAME Identity Wallet app.
                    </p>
                    <div className="form-container">
                        {isTabletOrMobile ? (
                            <>
                                <QRCodeComponent data={offeringState.uri} />
                                <p style={{ marginTop: "20px" }}>
                                    Tap the button below to open your wallet:
                                </p>
                                <button
                                    className="claim-button"
                                    onClick={() => window.open(offeringState.uri, '_blank')}
                                >
                                    Open Wallet
                                </button>
                            </>
                        ) : (
                            <QRCodeComponent data={offeringState.uri} />
                        )}
                    </div>
                    <p className="footnote">
                        Please wait while we verify that your credential has been issued...
                    </p>
                </div>
                <Footer />
            </>
        );
    } else if (pageStep === 'success') {
        return (
            <>
                <Header />
                <div className="main-container-success">
                    <h1 className="full-width-center-text">
                        Success!
                    </h1>
                    <p className="full-width-center-text">
                        Your FAME Onboarding Credential has been issued to your wallet.
                        You can now access members-only content on the{" "}
                        <a
                            href="https://marketplace.fame-horizon.eu/login"
                            style={{ color: "#051523" }}
                        >
                            FAME Marketplace
                        </a>.
                    </p>
                    <img
                        className="fame-screenshot"
                        src={`${import.meta.env.BASE_URL}/fame_home.png`}
                        alt="The FAME Marketplace"
                    />
                </div>
                <Footer />
            </>
        );
    } else {
        return null;
    }
};

export default OnboardingPage;
