const { useState, useEffect, useCallback, useRef } = React;

const App = () => {
    const [loading, setLoading] = useState(true);
    const [user, setUser] = useState(null);
    const [products, setProducts] = useState([]);
    const [metalPrices, setMetalPrices] = useState(null);
    const [cart, setCart] = useState(() => {
        const saved = localStorage.getItem('cart');
        return saved ? JSON.parse(saved) : [];
    });
    const [currentPage, setCurrentPage] = useState('products');
    const [toast, setToast] = useState(null);
    const [completedOrder, setCompletedOrder] = useState(null);
    const [authReady, setAuthReady] = useState(false);
    const [announcement, setAnnouncement] = useState(null);

    const logout = useCallback(async () => {
        try {
            await api.logout();
        } catch (e) {
            console.error('Logout error:', e);
        }
        setUser(null);
        setAuthReady(false);
        setTimeout(() => setAuthReady(true), 0);
    }, []);

    useEffect(() => {
        const init = async () => {
            try {
                const config = await api.getConfig();

                let authenticated = false;
                try {
                    const me = await api.getMe();
                    setUser({
                        displayName: me.name,
                        role: me.role,
                        _ref: me.sid,
                        _authenticated: true
                    });
                    authenticated = true;
                } catch (e) {}

                if (!authenticated && config.liffId) {
                    await liffService.init(config.liffId);
                    if (liffService.isLoggedIn) {
                        try {
                            const liffAccessToken = liff.getAccessToken();
                            if (liffAccessToken) {
                                const authResult = await api.authLiff(liffAccessToken);
                                const u = authResult.user;
                                setUser({
                                    displayName: u.name,
                                    role: u.role,
                                    _ref: u.sid,
                                    _authenticated: true
                                });
                            }
                        } catch (e) {
                            console.error('LIFF auth error:', e);
                            if (liffService.profile) {
                                setUser(liffService.profile);
                            }
                        }
                    }
                }

                setAuthReady(true);

                const productsData = await api.getProducts();
                setProducts(productsData);

                const productMap = {};
                productsData.forEach(p => { productMap[p.id] = p; });
                setCart(prev => prev.map(item => {
                    const latest = productMap[item.id];
                    if (latest && latest.image_url !== item.image_url) {
                        return { ...item, image_url: latest.image_url };
                    }
                    return item;
                }));

                try {
                    const prices = await api.getMetalPrices();
                    setMetalPrices(prices);
                } catch (e) {
                    console.log('Metal prices not available');
                }

                try {
                    const announcementData = await api.getAnnouncement();
                    if (announcementData.enabled && announcementData.content) {
                        if (announcementData.display_mode === 'always') {
                            setAnnouncement(announcementData);
                        } else {
                            const readVersion = localStorage.getItem('shop_announcement_read_version');
                            if (readVersion !== announcementData.version) {
                                setAnnouncement(announcementData);
                            }
                        }
                    }
                } catch (e) {
                    console.log('Announcement not available');
                }

            } catch (error) {
                console.error('Init error:', error);
            } finally {
                setLoading(false);
            }
        };

        init();
    }, []);

    useEffect(() => {
        let ws;
        let reconnectTimer;
        const connect = () => {
            const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
            ws = new WebSocket(`${protocol}//${location.host}/ws/prices`);
            ws.onmessage = async (evt) => {
                try {
                    const data = JSON.parse(evt.data);
                    if (data.event === 'price-updated') {
                        const [productsData, pricesData] = await Promise.all([
                            api.getProducts(),
                            api.getMetalPrices(),
                        ]);
                        setProducts(productsData);
                        setMetalPrices(pricesData);
                    } else if (data.event === 'stock-updated') {
                        const productsData = await api.getProducts();
                        setProducts(productsData);
                    }
                } catch (e) {}
            };
            ws.onclose = () => {
                reconnectTimer = setTimeout(connect, 5000);
            };
        };
        connect();
        return () => {
            clearTimeout(reconnectTimer);
            if (ws) ws.close();
        };
    }, []);

    useEffect(() => {
        localStorage.setItem('cart', JSON.stringify(cart));
    }, [cart]);

    const productsRef = useRef(products);
    productsRef.current = products;
    const cartRef = useRef(cart);
    cartRef.current = cart;

    const showToast = useCallback((message) => {
        setToast(message);
    }, []);

    const addToCart = useCallback((product) => {
        const latestProduct = productsRef.current.find(p => p.id === product.id);
        const maxStock = latestProduct?.stock_quantity || 0;
        const currentInCart = cartRef.current.find(item => item.id === product.id)?.quantity || 0;

        if (currentInCart >= maxStock) {
            showToast(`已達庫存上限（購物車 ${currentInCart} 件／庫存 ${maxStock} 件）`);
            return false;
        }

        setCart(prev => {
            const existing = prev.find(item => item.id === product.id);
            if (existing) {
                return prev.map(item =>
                    item.id === product.id
                        ? { ...item, quantity: Math.min(item.quantity + 1, maxStock) }
                        : item
                );
            }
            return [...prev, { ...product, quantity: 1 }];
        });
        return true;
    }, [showToast]);

    const updateCartQuantity = useCallback((productId, quantity) => {
        if (quantity <= 0) {
            setCart(prev => prev.filter(item => item.id !== productId));
        } else {
            const latestProduct = productsRef.current.find(p => p.id === productId);
            const maxStock = latestProduct?.stock_quantity ?? 0;
            const cappedQty = maxStock > 0 ? Math.min(quantity, maxStock) : 1;
            setCart(prev => prev.map(item =>
                item.id === productId ? { ...item, quantity: cappedQty } : item
            ));
        }
    }, []);

    const removeFromCart = useCallback((productId) => {
        setCart(prev => prev.filter(item => item.id !== productId));
    }, []);

    const clearCart = useCallback(() => {
        setCart([]);
    }, []);

    const cartCount = cart.reduce((sum, item) => sum + item.quantity, 0);

    const handleLogin = useCallback(() => {
        if (liffService.liff && liffService.liff.isInClient()) {
            liffService.login();
        } else {
            window.location.href = '/api/auth/line';
        }
    }, []);

    const contextValue = {
        user,
        products,
        metalPrices,
        cart,
        addToCart,
        updateCartQuantity,
        removeFromCart,
        clearCart,
        showToast,
        handleLogin,
        logout,
        authReady,
    };

    if (loading) {
        return (
            <div className="app">
                <Loading message="載入中" />
            </div>
        );
    }

    const renderPage = () => {
        if (completedOrder) {
            return (
                <OrderSuccessPage
                    order={completedOrder}
                    onContinue={() => {
                        setCompletedOrder(null);
                        setCurrentPage('products');
                    }}
                />
            );
        }

        switch (currentPage) {
            case 'products':
                return <ProductList />;
            case 'cart':
                return <CartPage onCheckout={() => setCurrentPage('checkout')} />;
            case 'checkout':
                return (
                    <CheckoutPage
                        onBack={() => setCurrentPage('cart')}
                        onSuccess={(order) => setCompletedOrder(order)}
                    />
                );
            case 'profile':
                return <ProfilePage />;
            default:
                return <ProductList />;
        }
    };

    return (
        <AppContext.Provider value={contextValue}>
            <div className="app">
                <nav className="nav-tabs">
                    <button
                        className={`nav-tab ${currentPage === 'products' ? 'active' : ''}`}
                        onClick={() => { setCurrentPage('products'); setCompletedOrder(null); }}
                    >
                        商品
                    </button>
                    <button
                        className={`nav-tab cart-badge ${currentPage === 'cart' ? 'active' : ''}`}
                        onClick={() => { setCurrentPage('cart'); setCompletedOrder(null); }}
                    >
                        購物車
                        {cartCount > 0 && <span className="cart-count">{cartCount}</span>}
                    </button>
                    <button
                        className={`nav-tab ${currentPage === 'profile' ? 'active' : ''}`}
                        onClick={() => { setCurrentPage('profile'); setCompletedOrder(null); }}
                    >
                        我的
                    </button>
                </nav>

                {renderPage()}

                {toast && <Toast message={toast} onClose={() => setToast(null)} />}
                {announcement && (
                    <AnnouncementModal
                        announcement={announcement}
                        onClose={() => setAnnouncement(null)}
                    />
                )}
            </div>
        </AppContext.Provider>
    );
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
