import React, { createContext, useContext, useState, useCallback, useMemo } from 'react';
import { useAuth } from '../auth/AuthProvider';
import { submitRegistration } from '../services/api';

/**
 * Registration Wizard Context
 *
 * Manages multi-step form state and orchestrates submission to the
 * Registration Function. The wizard collects data across steps then
 * submits everything in a single authenticated POST to /api/registration/register.
 *
 * entraSubjectId is NOT included in the submission payload — the server
 * extracts it from the validated Bearer token so it cannot be spoofed.
 *
 * Steps:
 *   0 — Sign In        (handled by AuthProvider)
 *   1 — Contact Info   (contactName, contactEmail, contactPhone)
 *   2 — Business Info  (businessName, websiteUrl, businessCategory, businessDescription, clientCategory)
 *   3 — Review & Submit
 *   4 — Confirmation
 */

export const STEPS = [
    { key: 'signin',   label: 'Sign In',  icon: '🔐' },
    { key: 'contact',  label: 'Contact',  icon: '👤' },
    { key: 'business', label: 'Business', icon: '🏢' },
    { key: 'review',   label: 'Review',   icon: '📋' },
    { key: 'confirm',  label: 'Complete', icon: '✓'  },
];


// ─── Context ───────────────────────────────────────────────────────────────

const RegistrationContext = createContext(null);

export function useRegistration() {
    const ctx = useContext(RegistrationContext);
    if (!ctx) throw new Error('useRegistration must be used within <RegistrationProvider>');
    return ctx;
}


// ─── Provider ──────────────────────────────────────────────────────────────

export function RegistrationProvider({ children }) {
    const { user, getAccessToken } = useAuth();

    // Wizard navigation
    const [currentStep, setCurrentStep] = useState(0);
    const [loading,     setLoading]     = useState(false);
    const [error,       setError]       = useState(null);
    const [registrationId, setRegistrationId] = useState(null);

    // Form data — maps to RegisterRequest model fields (minus entraSubjectId)
    const [contactData, setContactData] = useState({
        contactName:  '',
        contactEmail: '',
        contactPhone: '',
    });

    const [businessData, setBusinessData] = useState({
        businessName:        '',
        websiteUrl:          '',
        businessCategory:    '',
        businessDescription: '',
        clientCategory:      'General',   // General | Franchisee | Franchisor
    });

    // ─── Navigation ─────────────────────────────────────────────────────

    const goNext = useCallback(() => {
        setCurrentStep(s => Math.min(s + 1, STEPS.length - 1));
        setError(null);
    }, []);

    const goBack = useCallback(() => {
        setCurrentStep(s => Math.max(s - 1, 1)); // Can't go back past sign-in
        setError(null);
    }, []);

    const clearError = useCallback(() => setError(null), []);

    // ─── Validation ─────────────────────────────────────────────────────

    const validateContact = useCallback(() => {
        if (!contactData.contactName.trim())  return 'Contact name is required';
        if (!contactData.contactEmail.trim()) return 'Email is required';
        return null;
    }, [contactData]);

    const validateBusiness = useCallback(() => {
        if (!businessData.businessName.trim()) return 'Business name is required';
        return null;
    }, [businessData]);

    // ─── Step handlers ───────────────────────────────────────────────────

    const onSignInComplete = useCallback(() => setCurrentStep(1), []);

    const saveContact = useCallback(() => {
        const err = validateContact();
        if (err) { setError(err); return; }
        goNext();
    }, [validateContact, goNext]);

    const saveBusiness = useCallback(() => {
        const err = validateBusiness();
        if (err) { setError(err); return; }
        goNext();
    }, [validateBusiness, goNext]);

    // ─── Submit registration ─────────────────────────────────────────────

    const submitApplication = useCallback(async () => {
        if (!user) { setError('Not signed in'); return; }

        setLoading(true);
        setError(null);

        try {
            // Acquire a fresh token — the Function validates this and extracts
            // the user's entraSubjectId from the OID claim server-side.
            let token;
            try {
                token = await getAccessToken();
            } catch (tokenErr) {
                throw new Error(tokenErr.message || 'Could not get authentication token. Please sign in again.');
            }

            // Build the payload — entraSubjectId is intentionally excluded;
            // the server stamps it from the validated JWT.
            const request = {
                ...contactData,
                ...businessData,
            };

            // Pre-fill email from auth if the user left it blank
            if (!request.contactEmail && user.email) {
                request.contactEmail = user.email;
            }

            console.log('[Registration] Submitting for entra user:', user.entraSubjectId);
            const result = await submitRegistration(request, token);

            if (!result.ok) {
                throw new Error(result.error || 'Registration failed');
            }

            setRegistrationId(result.registrationId);
            setCurrentStep(4); // Confirmation step
        } catch (err) {
            console.error('[Registration] Submit error:', err);
            setError(err.message || 'Submission failed. Please try again.');
        } finally {
            setLoading(false);
        }
    }, [user, getAccessToken, contactData, businessData]);


    // ─── Context value ───────────────────────────────────────────────────

    const value = useMemo(() => ({
        currentStep,
        loading,
        error,
        clearError,
        contactData,
        setContactData,
        businessData,
        setBusinessData,
        onSignInComplete,
        saveContact,
        saveBusiness,
        submitApplication,
        goBack,
        registrationId,
    }), [
        currentStep, loading, error, clearError,
        contactData, businessData,
        onSignInComplete, saveContact, saveBusiness, submitApplication, goBack,
        registrationId,
    ]);

    return (
        <RegistrationContext.Provider value={value}>
            {children}
        </RegistrationContext.Provider>
    );
}
