/**
 * Product Sign-Up - React App
 * Staff page to manage customer sign-ups for new product launches.
 * All data via Cloud Functions (no direct Firestore).
 */
var { useState, useEffect, useRef, useMemo } = React;

const CONTACT_OPTIONS = ['Email', 'SMS'];

const AU_PHONE_PREFIX = '+61';
function parsePhoneForInput(phone) {
    if (!phone) return '';
    const digits = phone.replace(/\D/g, '');
    if (digits.startsWith('61')) return digits.slice(2);
    if (digits.startsWith('0')) return digits.slice(1);
    return digits;
}
function formatPhoneForStore(digitsOnly) {
    const digits = (digitsOnly || '').replace(/\D/g, '');
    if (!digits) return '';
    return AU_PHONE_PREFIX + digits;
}
function validateAusPhone(phone) {
    if (!phone || !phone.trim()) return true;
    let digits = phone.replace(/\D/g, '');
    if (digits.startsWith('61')) digits = digits.slice(2);
    if (digits.startsWith('0')) digits = digits.slice(1);
    return digits.length >= 8 && digits.length <= 9;
}

function CustomerModal({ show, editingCustomer, stores, productSeries, defaultStoreLocation, onSave, onClose }) {
    const modalRef = useRef(null);
    const modalInstanceRef = useRef(null);
    const [form, setForm] = useState({
        name: '',
        email: '',
        phoneNumber: '',
        storeLocation: '',
        preferredMethodOfContact: 'Email',
        productSeries: ''
    });
    const [saving, setSaving] = useState(false);
    const [error, setError] = useState('');

    useEffect(() => {
        if (editingCustomer) {
            setForm({
                name: editingCustomer.name || '',
                email: editingCustomer.email || '',
                phoneNumber: formatPhoneForStore(parsePhoneForInput(editingCustomer.phoneNumber || '')),
                storeLocation: editingCustomer.storeLocation || '',
                preferredMethodOfContact: editingCustomer.preferredMethodOfContact || 'Email',
                productSeries: editingCustomer.productSeries || ''
            });
        } else {
            setForm({
                name: '',
                email: '',
                phoneNumber: '',
                storeLocation: defaultStoreLocation || '',
                preferredMethodOfContact: 'Email',
                productSeries: ''
            });
        }
        setError('');
    }, [editingCustomer, defaultStoreLocation, show]);

    useEffect(() => {
        if (!modalRef.current) return;
        const el = modalRef.current;
        let modal = bootstrap.Modal.getInstance(el);
        if (!modal) {
            modal = new bootstrap.Modal(el, { backdrop: true, keyboard: true });
            modalInstanceRef.current = modal;
        }
        if (show) modal.show();
        else modal.hide();
        const handleHidden = () => onClose();
        el.addEventListener('hidden.bs.modal', handleHidden);
        return () => {
            el.removeEventListener('hidden.bs.modal', handleHidden);
        };
    }, [show, onClose]);

    useEffect(() => {
        return () => {
            if (modalRef.current && modalInstanceRef.current) {
                modalInstanceRef.current.dispose();
                modalInstanceRef.current = null;
            }
        };
    }, []);

    const handleChange = (field, value) => {
        if (field === 'phoneNumber') {
            let digits = value.replace(/\D/g, '');
            if (digits.startsWith('61')) digits = digits.slice(2);
            if (digits.startsWith('0')) digits = digits.slice(1);
            const limited = digits.length > 9 ? digits.slice(0, 9) : digits;
            setForm(prev => ({ ...prev, [field]: limited ? AU_PHONE_PREFIX + limited : '' }));
        } else {
            setForm(prev => ({ ...prev, [field]: value }));
        }
        setError('');
    };

    const handleSubmit = async (e) => {
        e.preventDefault();
        if (!form.name.trim()) {
            setError('Name is required');
            return;
        }
        if (!form.email.trim()) {
            setError('Email is required');
            return;
        }
        if (form.phoneNumber && !validateAusPhone(form.phoneNumber)) {
            setError('Phone number must be a valid Australian number (8–9 digits after +61)');
            return;
        }
        setSaving(true);
        setError('');
        try {
            await onSave(form);
            bootstrap.Modal.getInstance(modalRef.current)?.hide();
        } catch (err) {
            setError(err.message || 'Failed to save');
        } finally {
            setSaving(false);
        }
    };

    return (
        <div className="modal fade ps-modal" ref={modalRef} tabIndex="-1" aria-labelledby="customerModalLabel" aria-hidden="true">
            <div className="modal-dialog modal-dialog-centered modal-lg">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title" id="customerModalLabel">
                            {editingCustomer ? 'Edit Customer' : 'Add Customer'}
                        </h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form onSubmit={handleSubmit}>
                        <div className="modal-body">
                            {error && (
                                <div className="alert alert-danger py-2" role="alert">{error}</div>
                            )}
                            <div className="row g-3">
                                <div className="col-md-6">
                                    <label className="form-label">Name <span className="text-danger">*</span></label>
                                    <input type="text" className="form-control" value={form.name} onChange={e => handleChange('name', e.target.value)} placeholder="Customer full name" required />
                                </div>
                                <div className="col-md-6">
                                    <label className="form-label">Email <span className="text-danger">*</span></label>
                                    <input type="email" className="form-control" value={form.email} onChange={e => handleChange('email', e.target.value)} placeholder="customer@example.com" required />
                                </div>
                                <div className="col-md-6">
                                    <label className="form-label">Phone Number</label>
                                    <div className="input-group">
                                        <span className="input-group-text">+61</span>
                                        <input type="tel" className="form-control" inputMode="numeric" pattern="[0-9]*" maxLength={9} value={parsePhoneForInput(form.phoneNumber)} onChange={e => handleChange('phoneNumber', e.target.value)} placeholder="4XX XXX XXX" />
                                    </div>
                                    <small className="text-muted">8–9 digits (e.g. 400 000 000)</small>
                                </div>
                                <div className="col-md-6">
                                    <label className="form-label">Store Location</label>
                                    <select className="form-select" value={form.storeLocation} onChange={e => handleChange('storeLocation', e.target.value)}>
                                        <option value="">Select store</option>
                                        {(stores || []).map(s => (
                                            <option key={s.id} value={s.name}>{s.name}</option>
                                        ))}
                                    </select>
                                </div>
                                <div className="col-md-6">
                                    <label className="form-label">Preferred Method of Contact</label>
                                    <select className="form-select" value={form.preferredMethodOfContact} onChange={e => handleChange('preferredMethodOfContact', e.target.value)}>
                                        {CONTACT_OPTIONS.map(opt => (
                                            <option key={opt} value={opt}>{opt}</option>
                                        ))}
                                    </select>
                                </div>
                                <div className="col-md-6">
                                    <label className="form-label">Product Series</label>
                                    {productSeries && productSeries.length > 0 ? (
                                        <select className="form-select" value={form.productSeries} onChange={e => handleChange('productSeries', e.target.value)}>
                                            <option value="">Select product series</option>
                                            {productSeries.map(ps => (
                                                <option key={ps.id} value={ps.name}>{ps.name}</option>
                                            ))}
                                        </select>
                                    ) : (
                                        <input type="text" className="form-control" value={form.productSeries} onChange={e => handleChange('productSeries', e.target.value)} placeholder="Product series name" />
                                    )}
                                </div>
                            </div>
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn ps-btn ps-btn-secondary ps-modal-btn-cancel" data-bs-dismiss="modal">Cancel</button>
                            <button type="submit" className="btn ps-btn ps-modal-btn-primary" disabled={saving}>
                                {saving ? <span className="spinner-border spinner-border-sm me-1" role="status"></span> : null}
                                {editingCustomer ? 'Update' : 'Add'} Customer
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    );
}

function DeleteCustomerModal({ show, customer, onConfirm, onClose }) {
    const modalRef = useRef(null);
    const modalInstanceRef = useRef(null);
    const [deleting, setDeleting] = useState(false);

    useEffect(() => {
        if (!modalRef.current) return;
        const el = modalRef.current;
        let modal = bootstrap.Modal.getInstance(el);
        if (!modal) {
            modal = new bootstrap.Modal(el, { backdrop: true, keyboard: true });
            modalInstanceRef.current = modal;
        }
        if (show) modal.show();
        else modal.hide();
        const handleHidden = () => onClose();
        el.addEventListener('hidden.bs.modal', handleHidden);
        return () => {
            el.removeEventListener('hidden.bs.modal', handleHidden);
        };
    }, [show, onClose]);

    useEffect(() => {
        return () => {
            if (modalRef.current && modalInstanceRef.current) {
                modalInstanceRef.current.dispose();
                modalInstanceRef.current = null;
            }
        };
    }, []);

    const handleConfirm = async () => {
        if (!customer) return;
        setDeleting(true);
        try {
            await onConfirm(customer);
            bootstrap.Modal.getInstance(modalRef.current)?.hide();
        } catch (err) {
            alert(err.message || 'Failed to delete');
        } finally {
            setDeleting(false);
        }
    };

    return (
        <div className="modal fade ps-modal" ref={modalRef} tabIndex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
            <div className="modal-dialog modal-dialog-centered">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title" id="deleteModalLabel">Delete Customer</h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div className="modal-body">
                        <p className="mb-0">Are you sure you want to delete <strong>{customer?.name || 'this customer'}</strong>? This action cannot be undone.</p>
                    </div>
                    <div className="modal-footer">
                        <button type="button" className="btn ps-btn ps-btn-secondary ps-modal-btn-cancel" data-bs-dismiss="modal">Cancel</button>
                        <button type="button" className="btn ps-btn ps-modal-btn-danger" onClick={handleConfirm} disabled={deleting}>
                            {deleting ? <span className="spinner-border spinner-border-sm me-1" role="status"></span> : null}
                            Delete
                        </button>
                    </div>
                </div>
            </div>
        </div>
    );
}

function SendNotificationsModal({ show, productSeriesOptions, customers, selectedSeries, onSelectedChange, onSend, sending, onClose }) {
    const modalRef = useRef(null);
    const modalInstanceRef = useRef(null);

    const toggle = (ps) => {
        onSelectedChange(prev => prev.includes(ps) ? prev.filter(x => x !== ps) : [...prev, ps]);
    };

    const pendingCount = (productSeriesOptions || []).reduce((acc, ps) => {
        if (!selectedSeries.includes(ps)) return acc;
        const n = (customers || []).filter(c => (c.productSeries || '').trim() === ps).length;
        return acc + n;
    }, 0);

    useEffect(() => {
        if (!modalRef.current) return;
        const el = modalRef.current;
        let modal = bootstrap.Modal.getInstance(el);
        if (!modal) {
            modal = new bootstrap.Modal(el, { backdrop: true, keyboard: true });
            modalInstanceRef.current = modal;
        }
        if (show) modal.show();
        else modal.hide();
        const handleHidden = () => onClose();
        el.addEventListener('hidden.bs.modal', handleHidden);
        return () => el.removeEventListener('hidden.bs.modal', handleHidden);
    }, [show, onClose]);

    useEffect(() => {
        return () => {
            if (modalRef.current && modalInstanceRef.current) {
                modalInstanceRef.current.dispose();
                modalInstanceRef.current = null;
            }
        };
    }, []);

    const handleSend = async (e) => {
        e.preventDefault();
        if (selectedSeries.length === 0) return;
        await onSend(selectedSeries);
    };

    return (
        <div className="modal fade ps-modal" ref={modalRef} tabIndex="-1" aria-labelledby="sendNotificationsModalLabel" aria-hidden="true">
            <div className="modal-dialog modal-dialog-centered modal-lg">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title" id="sendNotificationsModalLabel">Send Notifications</h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form onSubmit={handleSend}>
                        <div className="modal-body">
                            <p className="text-muted small mb-3">Select product series to notify. Notification logic will be added later.</p>
                            <div className="border rounded p-2" style={{ maxHeight: '320px', overflowY: 'auto' }}>
                                {(productSeriesOptions || []).length === 0 ? (
                                    <p className="text-muted text-center py-3 mb-0">No product series with customers yet.</p>
                                ) : (
                                    (productSeriesOptions || []).map(ps => {
                                        const count = (customers || []).filter(c => (c.productSeries || '').trim() === ps).length;
                                        return (
                                            <div key={ps} className="form-check py-1">
                                                <input className="form-check-input" type="checkbox" id={`notif-${ps}`} checked={selectedSeries.includes(ps)} onChange={() => toggle(ps)} disabled={count === 0} />
                                                <label className="form-check-label" htmlFor={`notif-${ps}`}>
                                                    {ps}
                                                    {count > 0 && <span className="text-muted small ms-1">({count})</span>}
                                                </label>
                                            </div>
                                        );
                                    })
                                )}
                            </div>
                            {selectedSeries.length > 0 && (
                                <p className="mt-2 mb-0 small text-primary">
                                    <i className="fas fa-info-circle me-1"></i>
                                    {pendingCount} customer{pendingCount !== 1 ? 's' : ''} will be processed.
                                </p>
                            )}
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn ps-btn ps-btn-secondary ps-modal-btn-cancel" data-bs-dismiss="modal">Cancel</button>
                            <button type="submit" className="btn ps-btn ps-modal-btn-primary" disabled={sending || selectedSeries.length === 0}>
                                {sending ? <span className="spinner-border spinner-border-sm me-1" role="status"></span> : null}
                                Send
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    );
}

function AddProductModal({ show, onSave, onClose }) {
    const modalRef = useRef(null);
    const modalInstanceRef = useRef(null);
    const [form, setForm] = useState({ title: '', launchDate: '' });
    const [saving, setSaving] = useState(false);
    const [error, setError] = useState('');

    useEffect(() => {
        setForm({ title: '', launchDate: '' });
        setError('');
    }, [show]);

    useEffect(() => {
        if (!modalRef.current) return;
        const el = modalRef.current;
        let modal = bootstrap.Modal.getInstance(el);
        if (!modal) {
            modal = new bootstrap.Modal(el, { backdrop: true, keyboard: true });
            modalInstanceRef.current = modal;
        }
        if (show) modal.show();
        else modal.hide();
        const handleHidden = () => onClose();
        el.addEventListener('hidden.bs.modal', handleHidden);
        return () => el.removeEventListener('hidden.bs.modal', handleHidden);
    }, [show, onClose]);

    useEffect(() => {
        return () => {
            if (modalRef.current && modalInstanceRef.current) {
                modalInstanceRef.current.dispose();
                modalInstanceRef.current = null;
            }
        };
    }, []);

    const handleSubmit = async (e) => {
        e.preventDefault();
        if (!form.title.trim()) {
            setError('Product name is required');
            return;
        }
        setSaving(true);
        setError('');
        try {
            await onSave({ title: form.title.trim(), launchDate: form.launchDate || null });
            bootstrap.Modal.getInstance(modalRef.current)?.hide();
        } catch (err) {
            setError(err.message || 'Failed to add product');
        } finally {
            setSaving(false);
        }
    };

    return (
        <div className="modal fade ps-modal" ref={modalRef} tabIndex="-1" aria-labelledby="addProductModalLabel" aria-hidden="true">
            <div className="modal-dialog modal-dialog-centered">
                <div className="modal-content">
                    <div className="modal-header">
                        <h5 className="modal-title" id="addProductModalLabel">Add Product</h5>
                        <button type="button" className="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <form onSubmit={handleSubmit}>
                        <div className="modal-body">
                            {error && (
                                <div className="alert alert-danger py-2" role="alert">{error}</div>
                            )}
                            <div className="mb-3">
                                <label className="form-label">Product Name <span className="text-danger">*</span></label>
                                <input type="text" className="form-control" value={form.title} onChange={e => setForm(prev => ({ ...prev, title: e.target.value }))} placeholder="Product name" required />
                            </div>
                            <div className="mb-3">
                                <label className="form-label">Launch Date</label>
                                <input type="date" className="form-control" value={form.launchDate} onChange={e => setForm(prev => ({ ...prev, launchDate: e.target.value }))} />
                            </div>
                        </div>
                        <div className="modal-footer">
                            <button type="button" className="btn ps-btn ps-modal-btn-cancel" data-bs-dismiss="modal">Cancel</button>
                            <button type="submit" className="btn ps-btn ps-modal-btn-primary" disabled={saving}>
                                {saving ? <span className="spinner-border spinner-border-sm me-1" role="status"></span> : null}
                                Add Product
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    );
}

function ActiveProductsTable({ products, onDelete }) {
    function formatDate(val) {
        if (!val) return '-';
        if (val.toDate && typeof val.toDate === 'function') {
            return val.toDate().toLocaleDateString('en-AU', { year: 'numeric', month: 'short', day: 'numeric' });
        }
        const sec = val.seconds ?? val._seconds;
        if (typeof sec === 'number') {
            const d = new Date(sec * 1000);
            return isNaN(d.getTime()) ? '-' : d.toLocaleDateString('en-AU', { year: 'numeric', month: 'short', day: 'numeric' });
        }
        if (typeof val === 'string') {
            const d = new Date(val);
            return isNaN(d.getTime()) ? val : d.toLocaleDateString('en-AU', { year: 'numeric', month: 'short', day: 'numeric' });
        }
        return '-';
    }
    if (!products || products.length === 0) {
        return (
            <div className="ps-empty">
                <i className="fas fa-box-open"></i>
                <p>No active products yet. Click Add Product to get started.</p>
            </div>
        );
    }
    return (
        <div>
            <table className="table ps-table ps-table-active-products">
                <colgroup>
                    <col style={{ width: '38%' }} />
                    <col style={{ width: '26%' }} />
                    <col style={{ width: '26%' }} />
                    {onDelete && <col style={{ width: '10%' }} />}
                </colgroup>
                <thead>
                    <tr>
                        <th>Product Name</th>
                        <th>Created Date</th>
                        <th>Launch Date</th>
                        {onDelete && <th className="ps-actions-col">Actions</th>}
                    </tr>
                </thead>
                <tbody>
                    {products.map(p => (
                        <tr key={p.id}>
                            <td>{p.title || '-'}</td>
                            <td>{formatDate(p.createdAt)}</td>
                            <td>{formatDate(p.launchDate)}</td>
                            {onDelete && (
                                <td className="ps-actions-col">
                                    <button type="button" className="btn btn-sm btn-outline-danger ps-action-btn" onClick={() => onDelete(p)} title="Delete product">
                                        <i className="fas fa-trash-alt"></i>
                                    </button>
                                </td>
                            )}
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
}

function CustomerTable({ customers, onEdit, onDelete }) {
    if (!customers || customers.length === 0) {
        return (
            <div className="ps-empty">
                <i className="fas fa-users"></i>
                <p>No customers yet. Click Add Customer to get started.</p>
            </div>
        );
    }
    return (
        <div>
            <table className="table ps-table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Phone</th>
                        <th>Store</th>
                        <th>Contact</th>
                        <th>Product Series</th>
                        <th className="ps-actions-col"></th>
                    </tr>
                </thead>
                <tbody>
                    {customers.map(c => (
                        <tr key={c.id}>
                            <td>{c.name || '-'}</td>
                            <td>{c.email || '-'}</td>
                            <td>{c.phoneNumber || '-'}</td>
                            <td>{c.storeLocation || '-'}</td>
                            <td>{c.preferredMethodOfContact || '-'}</td>
                            <td>{c.productSeries || '-'}</td>
                            <td className="ps-actions-col">
                                <button type="button" className="btn btn-outline-primary ps-action-btn me-1" onClick={() => onEdit(c)} title="Edit">
                                    <i className="fas fa-edit"></i>
                                </button>
                                <button type="button" className="btn btn-outline-danger ps-action-btn" onClick={() => onDelete(c)} title="Delete">
                                    <i className="fas fa-trash-alt"></i>
                                </button>
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
}

function ProductSignupApp() {
    const [authReady, setAuthReady] = useState(false);
    const [customers, setCustomers] = useState([]);
    const [stores, setStores] = useState([]);
    const [productSeries, setProductSeries] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState('');
    const [modalOpen, setModalOpen] = useState(false);
    const [editingCustomer, setEditingCustomer] = useState(null);
    const [deleteModalOpen, setDeleteModalOpen] = useState(false);
    const [customerToDelete, setCustomerToDelete] = useState(null);
    const [searchTerm, setSearchTerm] = useState('');
    const [filterProduct, setFilterProduct] = useState('');
    const [filterStore, setFilterStore] = useState('');
    const [currentPage, setCurrentPage] = useState(1);
    const [isAdmin, setIsAdmin] = useState(false);
    const [notificationModalOpen, setNotificationModalOpen] = useState(false);
    const [notificationSending, setNotificationSending] = useState(false);
    const [notificationSelectedSeries, setNotificationSelectedSeries] = useState([]);
    const [view, setView] = useState('customers'); // 'customers' | 'products'
    const [launchProducts, setLaunchProducts] = useState([]);
    const [productsLoading, setProductsLoading] = useState(false);
    const [addProductModalOpen, setAddProductModalOpen] = useState(false);
    const [defaultStoreLocation, setDefaultStoreLocation] = useState('');

    const PAGE_SIZE = 15;

    // Auth check - wait for ensureAuthIsInitialized so userRole is in localStorage
    useEffect(() => {
        if (!window.auth) {
            setTimeout(() => setAuthReady(true), 200);
            return;
        }
        let mounted = true;
        (async () => {
            try {
                if (window.ensureAuthIsInitialized) await window.ensureAuthIsInitialized();
            } catch (e) { /* ignore */ }
            if (!mounted) return;
            const user = window.auth.currentUser;
            if (!user) {
                window.location.href = '../login.html';
                return;
            }
            const role = localStorage.getItem(`userRole_${user.uid}`) || localStorage.getItem('userRole');
            setIsAdmin(role === 'admin');
            setAuthReady(true);
        })();
        return () => { mounted = false; };
    }, []);

    // Full load (initial) - shows loading spinner
    const loadData = async () => {
        if (!window.functions || !window.httpsCallable) return;
        setLoading(true);
        setError('');
        try {
            const getCustomers = window.httpsCallable(window.functions, 'getProductSignupCustomers');
            const getOptions = window.httpsCallable(window.functions, 'getProductSignupOptions');
            const [customersRes, optionsRes] = await Promise.all([
                getCustomers({}),
                getOptions({})
            ]);
            if (customersRes.data?.success) setCustomers(customersRes.data.data || []);
            if (optionsRes.data?.success) {
                setStores(optionsRes.data.stores || []);
                setProductSeries(optionsRes.data.productSeries || []);
                setDefaultStoreLocation(optionsRes.data.defaultStoreName || '');
            }
        } catch (err) {
            console.error('Load error:', err);
            setError(err.message || 'Failed to load data');
            setCustomers([]);
        } finally {
            setLoading(false);
        }
    };

    // Light refresh after add/edit - no spinner, keeps table visible
    const refreshCustomers = async () => {
        if (!window.functions || !window.httpsCallable) return;
        try {
            const getCustomers = window.httpsCallable(window.functions, 'getProductSignupCustomers');
            const customersRes = await getCustomers({});
            if (customersRes.data?.success) setCustomers(customersRes.data.data || []);
        } catch (err) {
            console.error('Refresh error:', err);
            loadData();
        }
    };

    const loadNewLaunchProducts = async () => {
        if (!window.functions || !window.httpsCallable) return;
        setProductsLoading(true);
        try {
            const fn = window.httpsCallable(window.functions, 'getNewLaunchProducts');
            const res = await fn({});
            if (res.data?.success) setLaunchProducts(res.data.data || []);
        } catch (err) {
            console.error('Load launch products error:', err);
            setLaunchProducts([]);
        } finally {
            setProductsLoading(false);
        }
    };

    const handleAddProduct = async (form) => {
        const fn = window.httpsCallable(window.functions, 'addNewLaunchProduct');
        await fn(form);
        setAddProductModalOpen(false);
        loadNewLaunchProducts();
    };

    const handleDeleteLaunchProduct = async (product) => {
        if (!confirm(`Delete "${product.title || 'this product'}"?`)) return;
        try {
            const fn = window.httpsCallable(window.functions, 'deleteNewLaunchProduct');
            await fn({ id: product.id });
            loadNewLaunchProducts();
        } catch (err) {
            alert(err.message || 'Failed to delete product');
        }
    };

    useEffect(() => {
        if (authReady && window.functions && window.httpsCallable) {
            loadData();
        }
    }, [authReady]);

    useEffect(() => {
        if (authReady) {
            loadNewLaunchProducts();
        }
    }, [authReady]);

    const handleAdd = () => {
        setEditingCustomer(null);
        setModalOpen(true);
    };

    const handleEdit = (c) => {
        setEditingCustomer(c);
        setModalOpen(true);
    };

    const handleSave = async (form) => {
        const fn = window.httpsCallable(window.functions, editingCustomer ? 'updateProductSignupCustomer' : 'addProductSignupCustomer');
        if (editingCustomer) {
            await fn({ id: editingCustomer.id, ...form });
        } else {
            await fn(form);
        }
        setModalOpen(false);
        refreshCustomers();
    };

    const handleDeleteClick = (c) => {
        setCustomerToDelete(c);
        setDeleteModalOpen(true);
    };

    const handleDeleteConfirm = async (c) => {
        const fn = window.httpsCallable(window.functions, 'deleteProductSignupCustomer');
        await fn({ id: c.id });
        setDeleteModalOpen(false);
        setCustomerToDelete(null);
        setCustomers(prev => prev.filter(x => x.id !== c.id));
    };

    const handleDeleteModalClose = () => {
        setDeleteModalOpen(false);
        setCustomerToDelete(null);
    };

    const handleDownloadCsv = () => {
        const headers = ['Name', 'Email', 'Phone Number', 'Store Location', 'Preferred Method of Contact', 'Product Series'];
        const escape = (v) => {
            const s = String(v ?? '');
            if (s.includes(',') || s.includes('"') || s.includes('\n')) {
                return '"' + s.replace(/"/g, '""') + '"';
            }
            return s;
        };
        const rows = filteredCustomers.map(c => [
            escape(c.name),
            escape(c.email),
            escape(c.phoneNumber),
            escape(c.storeLocation),
            escape(c.preferredMethodOfContact),
            escape(c.productSeries)
        ].join(','));
        const csv = [headers.join(','), ...rows].join('\n');
        const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `product-signup-customers-${new Date().toISOString().split('T')[0]}.csv`;
        a.click();
        URL.revokeObjectURL(url);
    };

    const handleModalClose = () => {
        setModalOpen(false);
        setEditingCustomer(null);
    };

    const handleOpenSendNotifications = () => {
        setNotificationSelectedSeries([]);
        setNotificationModalOpen(true);
    };

    const handleSendNotifications = async (productSeries) => {
        if (!window.functions || !window.httpsCallable || !productSeries?.length) return;
        setNotificationSending(true);
        try {
            const fn = window.httpsCallable(window.functions, 'sendProductSignupNotifications');
            await fn({ productSeries });
            setNotificationModalOpen(false);
            setNotificationSelectedSeries([]);
            refreshCustomers();
        } catch (err) {
            alert(err.message || 'Failed to send notifications');
        } finally {
            setNotificationSending(false);
        }
    };

    const handleSendNotificationsClose = () => {
        setNotificationModalOpen(false);
        setNotificationSelectedSeries([]);
    };

    const activeProductTitles = useMemo(() => {
        return new Set((launchProducts || []).map(p => (p.title || '').trim()).filter(Boolean));
    }, [launchProducts]);

    const customersForActiveProducts = useMemo(() => {
        if (activeProductTitles.size === 0) return [];
        return (customers || []).filter(c => activeProductTitles.has((c.productSeries || '').trim()));
    }, [customers, activeProductTitles]);

    const filterProductSeriesOptions = useMemo(() => {
        const seen = new Set();
        const list = [];
        customersForActiveProducts.forEach(c => {
            const ps = (c.productSeries || '').trim();
            if (ps && !seen.has(ps)) {
                seen.add(ps);
                list.push(ps);
            }
        });
        return list.sort();
    }, [customersForActiveProducts]);

    const filteredCustomers = customersForActiveProducts.filter(c => {
        if (searchTerm.trim()) {
            const term = searchTerm.toLowerCase();
            const matchesSearch = (c.name || '').toLowerCase().includes(term) ||
                (c.email || '').toLowerCase().includes(term) ||
                (c.storeLocation || '').toLowerCase().includes(term) ||
                (c.productSeries || '').toLowerCase().includes(term);
            if (!matchesSearch) return false;
        }
        if (filterProduct && (c.productSeries || '') !== filterProduct) return false;
        if (filterStore && (c.storeLocation || '') !== filterStore) return false;
        return true;
    });

    const totalPages = filteredCustomers.length > 0 ? Math.max(1, Math.ceil(filteredCustomers.length / PAGE_SIZE)) : 0;
    const page = Math.max(1, Math.min(currentPage, totalPages || 1));
    const startIdx = (page - 1) * PAGE_SIZE;
    const paginatedCustomers = filteredCustomers.slice(startIdx, startIdx + PAGE_SIZE);

    useEffect(() => {
        setCurrentPage(1);
    }, [searchTerm, filterProduct, filterStore]);

    useEffect(() => {
        if (totalPages === 0) setCurrentPage(1);
        else if (currentPage > totalPages) setCurrentPage(totalPages);
        else if (currentPage < 1) setCurrentPage(1);
    }, [totalPages, currentPage]);

    const hasActiveFilters = filterProduct || filterStore;

    if (!authReady) {
        return (
            <div className="container-fluid py-5 text-center">
                <div className="spinner-border text-primary" role="status"></div>
                <p className="mt-2 text-muted">Loading...</p>
            </div>
        );
    }

    return (
        <div className="container content-container ps-page">
            <div className="mb-5 ps-header-row">
                <h1 className="ps-header-title">Product Sign-Up</h1>
                <p className="ps-header-subtitle">Manage customer sign-ups for new product launches</p>
            </div>

            {error && (
                <div className="alert alert-danger py-2 mb-4" role="alert">{error}</div>
            )}

            {/* Toggle: Signed up Customers | Active Products - above white section */}
            <div className="ps-nav-tabs-container mb-4">
                <ul className="nav nav-tabs border-0 ps-nav-tabs" role="tablist">
                    <li className="nav-item" role="presentation">
                        <button type="button" className={`nav-link ${view === 'customers' ? 'active' : ''}`} onClick={() => setView('customers')} role="tab">
                            <i className="fas fa-users me-1"></i>Signed up Customers
                        </button>
                    </li>
                    <li className="nav-item" role="presentation">
                        <button type="button" className={`nav-link ${view === 'products' ? 'active' : ''}`} onClick={() => setView('products')} role="tab">
                            <i className="fas fa-box-open me-1"></i>Active Products
                        </button>
                    </li>
                </ul>
            </div>

            {/* Section wrapper - white background */}
            <div className="ps-section-wrapper">
            {view === 'customers' ? (
            <>
            {/* Section header - like product catalog */}
            <div className="d-flex justify-content-between align-items-start mb-4">
                <div>
                    <h2 className="ps-section-title">Signed up customers</h2>
                    <p className="ps-section-subtitle mb-0">Manage customer sign-ups for new product launches</p>
                </div>
                <div className="d-flex gap-2 flex-wrap">
                    {isAdmin && (
                        <button type="button" className="btn btn-outline-primary btn-sm" onClick={handleOpenSendNotifications}>
                            <i className="fas fa-bell me-1"></i>Send Notifications
                        </button>
                    )}
                    <button type="button" className="btn btn-secondary btn-sm" onClick={handleDownloadCsv} disabled={!filteredCustomers.length}>
                        <i className="fas fa-download me-1"></i>Download CSV
                    </button>
                    <button type="button" className="btn btn-primary" onClick={handleAdd}>
                        <i className="fas fa-plus me-2"></i>Add Customer
                    </button>
                </div>
            </div>

            {/* Filter bar - product-filter-bar style */}
            <div className="card mb-4 ps-filter-bar border-0">
                <div className="card-body py-4 px-4">
                    <div className="row g-3 align-items-end">
                        <div className="col-12 col-md-4 col-lg-3">
                            <div className="ps-filter-label"><i className="fas fa-search me-1"></i>Search</div>
                            <div className="ps-filter-search-wrap">
                                <i className="fas fa-search"></i>
                                <input type="text" className="form-control ps-filter-search-input" placeholder="Name, email, store, or product series" value={searchTerm} onChange={e => setSearchTerm(e.target.value)} />
                            </div>
                        </div>
                        <div className="col-6 col-md-4 col-lg-2">
                            <div className="ps-filter-label">Product Series</div>
                            <select className="form-select" value={filterProduct} onChange={e => setFilterProduct(e.target.value)}>
                                <option value="">All products</option>
                                {filterProductSeriesOptions.map(ps => (
                                    <option key={ps} value={ps}>{ps}</option>
                                ))}
                            </select>
                        </div>
                        <div className="col-6 col-md-4 col-lg-2">
                            <div className="ps-filter-label">Store</div>
                            <select className="form-select" value={filterStore} onChange={e => setFilterStore(e.target.value)}>
                                <option value="">All stores</option>
                                {(stores || []).map(s => (
                                    <option key={s.id} value={s.name}>{s.name}</option>
                                ))}
                            </select>
                        </div>
                        <div className="col-12 col-md-4 col-lg-2 d-flex align-items-end gap-2">
                            {hasActiveFilters && (
                                <button type="button" className="btn btn-sm ps-filter-reset-btn" onClick={() => { setFilterProduct(''); setFilterStore(''); }} title="Reset filters">
                                    <i className="fas fa-redo-alt me-1"></i>Reset
                                </button>
                            )}
                            <span className="ps-count-badge">{filteredCustomers.length} customer{filteredCustomers.length !== 1 ? 's' : ''}</span>
                        </div>
                    </div>
                </div>
            </div>

            {/* Table card - like product catalog */}
            <div className="card ps-table-card">
                <div className="card-body p-0">
            <div className="ps-table-wrap">
                {loading ? (
                    <div className="ps-loading">
                        <div className="spinner-border text-primary" role="status"></div>
                    </div>
                ) : (
                    <>
                        <div className="ps-table-scroll">
                            <CustomerTable customers={paginatedCustomers} onEdit={handleEdit} onDelete={handleDeleteClick} />
                        </div>
                        {filteredCustomers.length > 0 && (
                            <div className="ps-pagination d-flex align-items-center justify-content-end gap-2">
                                <span className="ps-pagination-text me-2">Showing {startIdx + 1}-{Math.min(startIdx + PAGE_SIZE, filteredCustomers.length)} of {filteredCustomers.length}</span>
                                <button type="button" className="btn btn-sm ps-btn ps-pagination-btn" onClick={() => setCurrentPage(p => Math.max(1, p - 1))} disabled={page <= 1}>
                                    <i className="fas fa-chevron-left"></i>
                                </button>
                                <span className="ps-pagination-text">{page} of {totalPages}</span>
                                <button type="button" className="btn btn-sm ps-btn ps-pagination-btn" onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))} disabled={page >= totalPages}>
                                    <i className="fas fa-chevron-right"></i>
                                </button>
                            </div>
                        )}
                    </>
                )}
            </div>
                </div>
            </div>
            </>
            ) : (
            /* Active Products view */
            <>
            <div className="d-flex justify-content-between align-items-start mb-4">
                <div>
                    <h2 className="ps-section-title">Active Products</h2>
                    <p className="ps-section-subtitle mb-0">Products scheduled for launch - notifications will be sent for these</p>
                </div>
                <button type="button" className="btn btn-primary" onClick={() => setAddProductModalOpen(true)}>
                    <i className="fas fa-plus me-2"></i>Add Product
                </button>
            </div>
            <div className="card ps-table-card ps-active-products-card">
                <div className="card-body p-0">
                    <div className="ps-table-wrap">
                        {productsLoading ? (
                            <div className="ps-loading">
                                <div className="spinner-border text-primary" role="status"></div>
                            </div>
                        ) : (
                            <ActiveProductsTable products={launchProducts} onDelete={isAdmin ? handleDeleteLaunchProduct : null} />
                        )}
                    </div>
                </div>
            </div>
            </>
            )}
            </div>

            <CustomerModal
                show={modalOpen}
                editingCustomer={editingCustomer}
                stores={stores}
                productSeries={(launchProducts || []).map(p => ({ id: p.id, name: p.title || '' })).filter(p => p.name)}
                defaultStoreLocation={defaultStoreLocation}
                onSave={handleSave}
                onClose={handleModalClose}
            />
            <DeleteCustomerModal
                show={deleteModalOpen}
                customer={customerToDelete}
                onConfirm={handleDeleteConfirm}
                onClose={handleDeleteModalClose}
            />
            <AddProductModal
                show={addProductModalOpen}
                onSave={handleAddProduct}
                onClose={() => setAddProductModalOpen(false)}
            />
            {isAdmin && (
                <SendNotificationsModal
                        show={notificationModalOpen}
                        productSeriesOptions={filterProductSeriesOptions}
                        customers={customersForActiveProducts}
                        selectedSeries={notificationSelectedSeries}
                        onSelectedChange={setNotificationSelectedSeries}
                        onSend={handleSendNotifications}
                        sending={notificationSending}
                        onClose={handleSendNotificationsClose}
                    />
            )}
        </div>
    );
}

function mountApp() {
    var appEl = document.getElementById('app');
    if (appEl && window.ReactDOM) {
        var root = ReactDOM.createRoot(appEl);
        root.render(<ProductSignupApp />);
    }
}

function waitForAuthThenMount() {
    if (window.functions && window.httpsCallable) {
        mountApp();
        return;
    }
    var attempts = 0;
    var maxAttempts = 50; // 5 seconds max
    var interval = setInterval(function () {
        attempts++;
        if (window.functions && window.httpsCallable) {
            clearInterval(interval);
            mountApp();
        } else if (attempts >= maxAttempts) {
            clearInterval(interval);
            console.error('Product Sign-Up: auth.js did not load in time. Ensure ../auth.js is loaded.');
            var appEl = document.getElementById('app');
            if (appEl) appEl.innerHTML = '<div class="container py-5 text-center text-danger">Failed to load. Please refresh the page.</div>';
        }
    }, 100);
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', waitForAuthThenMount);
} else {
    waitForAuthThenMount();
}
