/**
 * 貴金屬線上訂購系統 - LINE LIFF React App
 * Design: Liquid Gold Luxury - Editorial jewelry boutique aesthetic
 */

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

// ==================== Context ====================
const AppContext = createContext();

const useApp = () => useContext(AppContext);

// ==================== API ====================
const API_BASE = '/api';

const api = {
    async getConfig() {
        const res = await fetch(`${API_BASE}/config`);
        return res.json();
    },
    async getProducts(params = {}) {
        const query = new URLSearchParams(params).toString();
        const headers = {};
        const token = localStorage.getItem('jwt_token');
        if (token) headers['Authorization'] = `Bearer ${token}`;
        const res = await fetch(`${API_BASE}/products${query ? '?' + query : ''}`, { headers });
        return res.json();
    },
    async getCategories() {
        const res = await fetch(`${API_BASE}/categories`);
        return res.json();
    },
    async getMetalPrices() {
        const res = await fetch(`${API_BASE}/shop-prices`);
        return res.json();
    },
    async createOrder(data) {
        const res = await fetch(`${API_BASE}/orders`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
        });
        return res.json();
    },
    async getOrders(token) {
        const res = await fetch(`${API_BASE}/orders`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!res.ok) throw new Error('Failed to get orders');
        return res.json();
    },
    async authLiff(accessToken) {
        const res = await fetch(`${API_BASE}/auth/liff`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ access_token: accessToken })
        });
        if (!res.ok) throw new Error('Auth failed');
        return res.json();
    },
    async getMe(token) {
        const res = await fetch(`${API_BASE}/auth/me`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!res.ok) throw new Error('Unauthorized');
        return res.json();
    },
    async getProfile(token) {
        const res = await fetch(`${API_BASE}/profile`, {
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!res.ok) throw new Error('Failed to get profile');
        return res.json();
    },
    async updateProfile(token, data) {
        const res = await fetch(`${API_BASE}/profile`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify(data)
        });
        if (!res.ok) throw new Error('Failed to update profile');
        return res.json();
    },
    async cancelOrder(token, orderNumber) {
        const res = await fetch(`${API_BASE}/orders/${orderNumber}/cancel`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!res.ok) {
            const err = await res.json().catch(() => ({}));
            throw new Error(err.detail || '取消失敗');
        }
        return res.json();
    },
    async confirmReceived(token, orderNumber) {
        const res = await fetch(`${API_BASE}/orders/${orderNumber}/confirm-received`, {
            method: 'POST',
            headers: { 'Authorization': `Bearer ${token}` }
        });
        if (!res.ok) {
            const err = await res.json().catch(() => ({}));
            throw new Error(err.detail || '確認收貨失敗');
        }
        return res.json();
    }
};

// ==================== LIFF Service ====================
const liffService = {
    liff: null,
    isLoggedIn: false,
    profile: null,

    async init(liffId) {
        if (!liffId) {
            console.warn('LIFF ID not configured');
            return false;
        }
        try {
            await liff.init({ liffId });
            this.liff = liff;
            this.isLoggedIn = liff.isLoggedIn();
            if (this.isLoggedIn) {
                this.profile = await liff.getProfile();
            }
            return true;
        } catch (error) {
            console.error('LIFF init error:', error);
            return false;
        }
    },

    login() {
        if (this.liff && !this.isLoggedIn) {
            this.liff.login();
        }
    },

    async getProfile() {
        if (this.liff && this.isLoggedIn) {
            return await this.liff.getProfile();
        }
        return null;
    },

    sendMessage(message) {
        if (this.liff && this.liff.isInClient()) {
            return this.liff.sendMessages([{ type: 'text', text: message }]);
        }
    },

    closeWindow() {
        if (this.liff && this.liff.isInClient()) {
            this.liff.closeWindow();
        }
    }
};

// ==================== Utility Hooks ====================
const useAnimatedNumber = (value, duration = 500) => {
    const [displayValue, setDisplayValue] = useState(value);
    const prevValue = useRef(value);

    useEffect(() => {
        const startValue = prevValue.current;
        const endValue = value;
        const startTime = Date.now();

        const animate = () => {
            const elapsed = Date.now() - startTime;
            const progress = Math.min(elapsed / duration, 1);
            const eased = 1 - Math.pow(1 - progress, 3);
            const current = startValue + (endValue - startValue) * eased;
            setDisplayValue(Math.round(current));

            if (progress < 1) {
                requestAnimationFrame(animate);
            }
        };

        animate();
        prevValue.current = value;
    }, [value, duration]);

    return displayValue;
};

// ==================== Components ====================

// Toast 通知
const Toast = ({ message, onClose }) => {
    useEffect(() => {
        const timer = setTimeout(onClose, 2500);
        return () => clearTimeout(timer);
    }, [onClose]);

    return (
        <div className="toast">
            <span className="toast-icon">+</span>
            {message}
        </div>
    );
};

// Loading
const Loading = ({ message = '載入中' }) => (
    <div className="loading">
        <div className="spinner"></div>
        <span>{message}</span>
    </div>
);

// 金屬價格橫幅（讀取 shop_prices 表）
const PriceBanner = ({ prices }) => {
    const { user, handleLogin, authReady } = useApp();
    if (!prices?.has_prices) return null;

    const formatPrice = (price) => price ? `$${Math.round(price).toLocaleString()}` : '—';
    const p = prices.prices || {};

    if (!user) {
        return (
            <div className="price-banner price-banner-locked" onClick={authReady ? handleLogin : undefined}>
                <div className="price-banner-lock-msg">
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                        <rect x="3" y="7" width="10" height="7" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/>
                        <path d="M5 7V5a3 3 0 0 1 6 0v2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" fill="none"/>
                    </svg>
                    <span>登入查看即時報價</span>
                </div>
            </div>
        );
    }

    return (
        <div className="price-banner">
            <div className="price-item">
                <div className="price-label">黃金 / {p.Au?.display_unit || '錢'}</div>
                <div className="price-value gold">{formatPrice(p.Au?.sell_price)}</div>
            </div>
            <div className="price-item">
                <div className="price-label">白銀 / {p.Ag?.display_unit || '公斤'}</div>
                <div className="price-value silver">{formatPrice(p.Ag?.sell_price)}</div>
            </div>
            <div className="price-item">
                <div className="price-label">白金 / {p.Pt?.display_unit || '錢'}</div>
                <div className="price-value platinum">{formatPrice(p.Pt?.sell_price)}</div>
            </div>
        </div>
    );
};

// 金屬圖標
const MetalIcon = ({ type, size = 'md' }) => {
    const sizes = { sm: 24, md: 40, lg: 56 };
    const s = sizes[size] || sizes.md;

    const colors = {
        gold: ['#d4a853', '#b8923f'],
        silver: ['#c9c9c9', '#a0a0a0'],
        platinum: ['#d8d4cf', '#b5b0a8'],
        palladium: ['#e0e0e0', '#c0c0c0']
    };

    const [c1, c2] = colors[type] || colors.gold;

    return (
        <svg width={s} height={s} viewBox="0 0 40 40" fill="none">
            <defs>
                <linearGradient id={`grad-${type}`} x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stopColor={c1} />
                    <stop offset="100%" stopColor={c2} />
                </linearGradient>
            </defs>
            <circle cx="20" cy="20" r="18" fill={`url(#grad-${type})`} />
            <circle cx="20" cy="20" r="12" fill="none" stroke="rgba(255,255,255,0.3)" strokeWidth="0.5" />
            <circle cx="14" cy="14" r="4" fill="rgba(255,255,255,0.2)" />
        </svg>
    );
};

// 商品卡片
const ProductCard = ({ product, onAddToCart, onClick, index = 0 }) => {
    const { user, cart } = useApp();
    const [isAdding, setIsAdding] = useState(false);

    const currentInCart = cart.find(item => item.id === product.id)?.quantity || 0;
    const atStockLimit = product.stock_quantity > 0 && currentInCart >= product.stock_quantity;

    const handleAdd = (e) => {
        e.stopPropagation();
        setIsAdding(true);
        onAddToCart(product);
        setTimeout(() => setIsAdding(false), 300);
    };

    const buttonDisabled = product.stock_quantity <= 0 || !user || atStockLimit;
    const buttonText = !user ? '登入購買'
        : product.stock_quantity <= 0 ? '補貨中'
        : atStockLimit ? '已達庫存上限'
        : '加入購物車';

    return (
        <div
            className="product-card product-card-clickable"
            style={{ animationDelay: `${index * 0.05}s` }}
            onClick={() => onClick && onClick(product)}
        >
            {product.image_url ? (
                <img src={product.image_url} alt={product.name} className="product-image" />
            ) : (
                <div className={`product-placeholder product-image ${product.metal_type}`}>
                    <MetalIcon type={product.metal_type} size="lg" />
                </div>
            )}
            <div className="product-info">
                <div className="product-name">{product.name}</div>
                {product.weight_grams && (
                    <div className="product-weight">
                        {product.weight_grams}g · {(product.purity * 100).toFixed(2)}%
                    </div>
                )}
                {user ? (
                    <div className="product-price">NT$ {product.price?.toLocaleString()}</div>
                ) : (
                    <div className="product-price price-hidden">登入查看</div>
                )}
                <div className={`product-stock ${product.stock_quantity <= 0 ? 'out-of-stock' : ''}`}>
                    {product.stock_quantity > 0 ? `庫存 ${product.stock_quantity}` : '已售完'}
                </div>
                <button
                    className={`add-to-cart-btn ${isAdding ? 'adding' : ''}`}
                    onClick={handleAdd}
                    disabled={buttonDisabled}
                >
                    <span>{buttonText}</span>
                </button>
            </div>
        </div>
    );
};

// 金屬類型中文標籤
const metalTypeLabel = (type) => {
    const labels = { gold: '黃金', silver: '白銀', platinum: '白金', palladium: '鈀金' };
    return labels[type] || type || '—';
};

// 商品詳情彈窗
const ProductDetailModal = ({ product, onClose, onAddToCart }) => {
    const { user, cart } = useApp();
    const currentInCart = cart.find(item => item.id === product.id)?.quantity || 0;
    const atStockLimit = product.stock_quantity > 0 && currentInCart >= product.stock_quantity;
    const overlayRef = useRef(null);
    const contentRef = useRef(null);
    const closingRef = useRef(false);

    const animateClose = useCallback(() => {
        if (closingRef.current) return;
        closingRef.current = true;

        const content = contentRef.current;
        const overlay = overlayRef.current;
        if (!content || !overlay) { onClose(); return; }

        Motion.animate(content, { opacity: 0, transform: 'translateY(60px)' }, { duration: 0.2, easing: 'ease-in' })
            .then(() => Motion.animate(overlay, { opacity: 0 }, { duration: 0.1 }))
            .then(() => onClose());
    }, [onClose]);

    useEffect(() => {
        const overlay = overlayRef.current;
        const content = contentRef.current;
        if (!overlay || !content) return;

        Motion.animate(overlay, { opacity: [0, 1] }, { duration: 0.15 });
        Motion.animate(content,
            { opacity: [0, 1], transform: ['translateY(60px) scale(0.97)', 'translateY(0px) scale(1)'] },
            { duration: 0.35, easing: [0.22, 1, 0.36, 1] }
        );

        // ESC 鍵關閉
        const handleKey = (e) => { if (e.key === 'Escape') animateClose(); };
        document.addEventListener('keydown', handleKey);
        // 鎖定 body 滾動
        document.body.style.overflow = 'hidden';
        return () => {
            document.removeEventListener('keydown', handleKey);
            document.body.style.overflow = '';
        };
    }, [animateClose]);

    const handleBackdropClick = (e) => {
        if (e.target === overlayRef.current) animateClose();
    };

    const handleAddToCart = () => {
        if (onAddToCart(product) !== false) {
            animateClose();
        }
    };

    return (
        <div className="product-modal-overlay" ref={overlayRef} onClick={handleBackdropClick}>
            <div className="product-modal-content" ref={contentRef}>
                <div className={`product-modal-image ${product.metal_type || ''}`}>
                    {product.image_url ? (
                        <img src={product.image_url} alt={product.name} />
                    ) : (
                        <div className="modal-placeholder">
                            <MetalIcon type={product.metal_type} size="lg" />
                        </div>
                    )}
                    <button className="product-modal-close" onClick={animateClose} aria-label="關閉">
                        <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                            <path d="M4 4L12 12M12 4L4 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
                        </svg>
                    </button>
                </div>

                <div className="product-modal-body">
                    <div className="product-modal-name">{product.name}</div>
                    {product.description && (
                        <div className="product-modal-desc">{product.description}</div>
                    )}

                    <div className="product-modal-specs">
                        <div className="product-modal-spec">
                            <div className="product-modal-spec-label">材質</div>
                            <div className="product-modal-spec-value">{metalTypeLabel(product.metal_type)}</div>
                        </div>
                        <div className="product-modal-spec">
                            <div className="product-modal-spec-label">重量</div>
                            <div className="product-modal-spec-value">{product.weight_grams ? `${product.weight_grams}g` : '—'}</div>
                        </div>
                        <div className="product-modal-spec">
                            <div className="product-modal-spec-label">純度</div>
                            <div className="product-modal-spec-value">{product.purity ? `${(product.purity * 100).toFixed(2)}%` : '—'}</div>
                        </div>
                        <div className="product-modal-spec">
                            <div className="product-modal-spec-label">分類</div>
                            <div className="product-modal-spec-value">{product.category || '—'}</div>
                        </div>
                    </div>
                </div>

                <div className="product-modal-footer">
                    <div className="product-modal-price-block">
                        {user ? (
                            <div className="product-modal-price">NT$ {product.price?.toLocaleString()}</div>
                        ) : (
                            <div className="product-modal-price price-hidden">登入查看價格</div>
                        )}
                        <div className={`product-modal-stock ${product.stock_quantity <= 0 ? 'out-of-stock' : ''}`}>
                            {product.stock_quantity > 0 ? `庫存 ${product.stock_quantity} 件` : '已售完'}
                        </div>
                    </div>
                    <button
                        className="product-modal-cart-btn"
                        onClick={handleAddToCart}
                        disabled={product.stock_quantity <= 0 || !user || atStockLimit}
                    >
                        {!user ? '登入購買' : product.stock_quantity <= 0 ? '補貨中' : atStockLimit ? '已達庫存上限' : '加入購物車'}
                    </button>
                </div>
            </div>
        </div>
    );
};

// 商品列表頁
const ProductList = () => {
    const { products, cart, addToCart, showToast, metalPrices } = useApp();
    const [selectedCategory, setSelectedCategory] = useState('all');
    const [selectedProduct, setSelectedProduct] = useState(null);

    const categories = [...new Set(products.map(p => p.category).filter(Boolean))];

    const filteredProducts = selectedCategory === 'all'
        ? products
        : products.filter(p => p.category === selectedCategory);

    const groupedProducts = filteredProducts.reduce((acc, product) => {
        const category = product.category || '其他';
        if (!acc[category]) acc[category] = [];
        acc[category].push(product);
        return acc;
    }, {});

    const handleAddToCart = (product) => {
        if (addToCart(product)) {
            const newQty = (cart.find(item => item.id === product.id)?.quantity || 0) + 1;
            const maxStock = product.stock_quantity || 0;
            showToast(`已加入: ${product.name}（${newQty}/${maxStock}）`);
            return true;
        }
        return false;
    };

    return (
        <div className="product-list">
            <PriceBanner prices={metalPrices} />

            {categories.length > 0 && (
                <div className="nav-tabs" style={{ marginBottom: 16 }}>
                    <button
                        className={`nav-tab ${selectedCategory === 'all' ? 'active' : ''}`}
                        onClick={() => setSelectedCategory('all')}
                    >
                        全部
                    </button>
                    {categories.map(cat => (
                        <button
                            key={cat}
                            className={`nav-tab ${selectedCategory === cat ? 'active' : ''}`}
                            onClick={() => setSelectedCategory(cat)}
                        >
                            {cat}
                        </button>
                    ))}
                </div>
            )}

            {Object.entries(groupedProducts).map(([category, items]) => (
                <div key={category} className="category-section">
                    <h2 className="category-title">{category}</h2>
                    <div className="product-grid">
                        {items.map((product, idx) => (
                            <ProductCard
                                key={product.id}
                                product={product}
                                onAddToCart={handleAddToCart}
                                onClick={setSelectedProduct}
                                index={idx}
                            />
                        ))}
                    </div>
                </div>
            ))}

            {products.length === 0 && (
                <div className="cart-empty">
                    <div className="cart-empty-icon">
                        <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
                            <rect x="8" y="16" width="48" height="40" rx="4" stroke="currentColor" strokeWidth="2" fill="none"/>
                            <path d="M24 16V12C24 7.58172 27.5817 4 32 4C36.4183 4 40 7.58172 40 12V16" stroke="currentColor" strokeWidth="2"/>
                        </svg>
                    </div>
                    <p>暫無商品</p>
                </div>
            )}

            {selectedProduct && (
                <ProductDetailModal
                    product={selectedProduct}
                    onClose={() => setSelectedProduct(null)}
                    onAddToCart={handleAddToCart}
                />
            )}
        </div>
    );
};

// 購物車項目
const CartItem = ({ item, onUpdateQuantity, onRemove }) => {
    const { products } = useApp();
    const stockQuantity = products.find(p => p.id === item.id)?.stock_quantity || 0;
    const atLimit = item.quantity >= stockQuantity;

    return (
        <div className="cart-item">
            <div className="cart-item-image">
                {item.image_url ? (
                    <img src={item.image_url} alt={item.name} className="cart-item-img" />
                ) : (
                    <MetalIcon type={item.metal_type} size="md" />
                )}
            </div>
            <div className="cart-item-details">
                <div className="cart-item-name">{item.name}</div>
                <div className="cart-item-price">NT$ {item.price?.toLocaleString()}</div>
                <div className="cart-item-quantity">
                    <button
                        className="qty-btn"
                        onClick={() => onUpdateQuantity(item.id, item.quantity - 1)}
                        aria-label="減少數量"
                    >
                        <svg width="12" height="2" viewBox="0 0 12 2" fill="currentColor">
                            <rect width="12" height="2" rx="1"/>
                        </svg>
                    </button>
                    <span className="qty-value">{item.quantity}</span>
                    <button
                        className="qty-btn"
                        onClick={() => onUpdateQuantity(item.id, item.quantity + 1)}
                        disabled={atLimit}
                        aria-label="增加數量"
                    >
                        <svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor">
                            <rect y="5" width="12" height="2" rx="1"/>
                            <rect x="5" width="2" height="12" rx="1"/>
                        </svg>
                    </button>
                    <button className="remove-btn" onClick={() => onRemove(item.id)}>
                        移除
                    </button>
                </div>
                {atLimit && (
                    <div style={{ color: '#d4a853', fontSize: '0.75rem', marginTop: 4 }}>
                        已達庫存上限（最多可購買 {stockQuantity} 件）
                    </div>
                )}
            </div>
        </div>
    );
};

// 購物車頁面
const CartPage = ({ onCheckout }) => {
    const { cart, updateCartQuantity, removeFromCart } = useApp();

    const subtotal = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
    const shippingFee = subtotal >= 50000 ? 0 : 150;
    const total = subtotal + shippingFee;

    const animatedTotal = useAnimatedNumber(total);

    if (cart.length === 0) {
        return (
            <div className="cart-page">
                <div className="cart-empty">
                    <div className="cart-empty-icon">
                        <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
                            <circle cx="32" cy="32" r="28" stroke="currentColor" strokeWidth="2" fill="none"/>
                            <path d="M20 28H44M20 36H36" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
                        </svg>
                    </div>
                    <p>購物車是空的</p>
                    <p>去看看有什麼好物吧</p>
                </div>
            </div>
        );
    }

    return (
        <div className="cart-page">
            {cart.map((item, index) => (
                <CartItem
                    key={item.id}
                    item={item}
                    onUpdateQuantity={updateCartQuantity}
                    onRemove={removeFromCart}
                />
            ))}

            <div className="cart-summary">
                <div className="summary-row">
                    <span>小計</span>
                    <span>NT$ {subtotal.toLocaleString()}</span>
                </div>
                <div className="summary-row">
                    <span>運費 {subtotal >= 50000 && <small>(滿5萬免運)</small>}</span>
                    <span>NT$ {shippingFee}</span>
                </div>
                <div className="summary-row total">
                    <span>總計</span>
                    <span className="amount">NT$ {animatedTotal.toLocaleString()}</span>
                </div>
            </div>

            <button className="checkout-btn" onClick={onCheckout}>
                前往結帳
            </button>
        </div>
    );
};

// 結帳頁面
const PICKUP_STORES = [
    { id: 'taoyuan', name: '桃園店', address: '中壢九合一街36號' },
    { id: 'yunlin',  name: '雲林店', address: '斗六斗工六路45號' },
];

const PAYMENT_LABELS = {
    transfer: '銀行轉帳',
    cash_on_delivery: '貨到付款',
    store_pickup: '門市取貨付款',
};

const CheckoutPage = ({ onBack, onSuccess }) => {
    const { cart, user, clearCart } = useApp();
    const [loading, setLoading] = useState(false);
    const [form, setForm] = useState({
        customer_name: user?.displayName || '',
        customer_phone: '',
        customer_email: '',
        shipping_address: '',
        payment_method: 'transfer',
        pickup_store: '',
        notes: ''
    });

    // 自動帶入用戶 profile 資料（手機、地址、姓名）
    useEffect(() => {
        const token = localStorage.getItem('jwt_token');
        if (!token || !user) return;
        api.getProfile(token).then(profile => {
            if (!profile) return;
            setForm(prev => ({
                ...prev,
                customer_name: prev.customer_name || profile.name || '',
                customer_phone: prev.customer_phone || profile.mobile || profile.phone || '',
                shipping_address: prev.shipping_address || profile.address || '',
            }));
        }).catch(() => {});
    }, [user]);

    const isStorePickup = form.payment_method === 'store_pickup';
    const subtotal = cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
    const shippingFee = isStorePickup ? 0 : (subtotal >= 50000 ? 0 : 150);
    const total = subtotal + shippingFee;

    const handleChange = (e) => {
        const { name, value } = e.target;
        if (name === 'payment_method') {
            if (value === 'store_pickup') {
                setForm(prev => ({ ...prev, payment_method: value, pickup_store: '', shipping_address: '' }));
            } else {
                setForm(prev => ({
                    ...prev,
                    payment_method: value,
                    pickup_store: '',
                    shipping_address: prev.payment_method === 'store_pickup' ? '' : prev.shipping_address,
                }));
            }
            return;
        }
        if (name === 'pickup_store') {
            const store = PICKUP_STORES.find(s => s.id === value);
            setForm(prev => ({
                ...prev,
                pickup_store: value,
                shipping_address: store ? `【${store.name}】${store.address}` : ''
            }));
            return;
        }
        setForm({ ...form, [name]: value });
    };

    const handleSubmit = async (e) => {
        e.preventDefault();

        if (!form.customer_name || !form.customer_phone) {
            alert('請填寫必填欄位');
            return;
        }
        if (isStorePickup && !form.pickup_store) {
            alert('請選擇取貨門市');
            return;
        }
        if (!isStorePickup && !form.shipping_address) {
            alert('請填寫收件地址');
            return;
        }

        setLoading(true);

        try {
            const { pickup_store, ...formData } = form;
            const orderData = {
                ...formData,
                line_user_id: user?.userId || 'guest',
                line_display_name: user?.displayName,
                line_picture_url: user?.pictureUrl,
                items: cart.map(item => ({
                    product_id: item.id,
                    quantity: item.quantity
                })),
                shipping_fee: shippingFee
            };

            const result = await api.createOrder(orderData);

            if (result.success) {
                clearCart();
                onSuccess(result.order);

                if (liffService.liff?.isInClient()) {
                    liffService.sendMessage(
                        `訂單已送出\n訂單編號: ${result.order.order_number}\n總金額: NT$ ${total.toLocaleString()}`
                    );
                }
            } else {
                alert(result.error || '訂單建立失敗');
            }
        } catch (error) {
            console.error('Order error:', error);
            alert('訂單建立失敗，請稍後再試');
        } finally {
            setLoading(false);
        }
    };

    return (
        <div className="checkout-page">
            <button className="back-btn" onClick={onBack}>
                <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
                    <path d="M10 12L6 8L10 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
                </svg>
                返回購物車
            </button>

            <form onSubmit={handleSubmit}>
                <div className="form-section">
                    <h3>收件資訊</h3>
                    <div className="form-group">
                        <label>姓名 *</label>
                        <input
                            type="text"
                            name="customer_name"
                            value={form.customer_name}
                            onChange={handleChange}
                            required
                        />
                    </div>
                    <div className="form-group">
                        <label>手機 *</label>
                        <input
                            type="tel"
                            name="customer_phone"
                            value={form.customer_phone}
                            onChange={handleChange}
                            placeholder="0912345678"
                            required
                        />
                    </div>
                    <div className="form-group">
                        <label>Email</label>
                        <input
                            type="email"
                            name="customer_email"
                            value={form.customer_email}
                            onChange={handleChange}
                        />
                    </div>
                    {!isStorePickup && (
                        <div className="form-group">
                            <label>收件地址 *</label>
                            <textarea
                                name="shipping_address"
                                value={form.shipping_address}
                                onChange={handleChange}
                                placeholder="請輸入完整收件地址"
                                required
                            />
                        </div>
                    )}
                </div>

                <div className="form-section">
                    <h3>付款方式</h3>
                    <div className="form-group">
                        <select name="payment_method" value={form.payment_method} onChange={handleChange}>
                            <option value="transfer">銀行轉帳</option>
                            <option value="cash_on_delivery">貨到付款</option>
                            <option value="store_pickup">門市取貨付款</option>
                        </select>
                    </div>
                    {isStorePickup && (
                        <div className="form-group">
                            <label>取貨門市 *</label>
                            <div className="store-picker">
                                {PICKUP_STORES.map(store => (
                                    <label key={store.id} className={`store-option${form.pickup_store === store.id ? ' selected' : ''}`}>
                                        <input
                                            type="radio"
                                            name="pickup_store"
                                            value={store.id}
                                            checked={form.pickup_store === store.id}
                                            onChange={handleChange}
                                        />
                                        <div className="store-option-content">
                                            <span className="store-option-name">{store.name}</span>
                                            <span className="store-option-address">{store.address}</span>
                                        </div>
                                    </label>
                                ))}
                            </div>
                        </div>
                    )}
                </div>

                <div className="form-section">
                    <h3>訂單備註</h3>
                    <div className="form-group">
                        <textarea
                            name="notes"
                            value={form.notes}
                            onChange={handleChange}
                            placeholder="如有特殊需求請在此備註"
                        />
                    </div>
                </div>

                <div className="cart-summary">
                    <div className="summary-row">
                        <span>商品數量</span>
                        <span>{cart.reduce((sum, item) => sum + item.quantity, 0)} 件</span>
                    </div>
                    <div className="summary-row">
                        <span>小計</span>
                        <span>NT$ {subtotal.toLocaleString()}</span>
                    </div>
                    <div className="summary-row">
                        <span>運費</span>
                        <span>NT$ {shippingFee}</span>
                    </div>
                    <div className="summary-row total">
                        <span>應付金額</span>
                        <span className="amount">NT$ {total.toLocaleString()}</span>
                    </div>
                </div>

                <button type="submit" className="checkout-btn" disabled={loading}>
                    {loading ? '處理中...' : '確認送出訂單'}
                </button>
            </form>
        </div>
    );
};

// 訂單成功頁
const OrderSuccessPage = ({ order, onContinue }) => (
    <div className="order-success">
        <div className="success-icon">
            <svg width="80" height="80" viewBox="0 0 80 80" fill="none">
                <circle cx="40" cy="40" r="36" stroke="#4a9d6e" strokeWidth="3" fill="none"/>
                <path d="M24 40L34 50L56 28" stroke="#4a9d6e" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
            </svg>
        </div>
        <h2 className="success-title">訂單已送出</h2>
        <p className="order-number">訂單編號: {order.order_number}</p>
        <p style={{ color: '#a0a0a0', marginBottom: 24 }}>
            總金額: NT$ {order.total_amount?.toLocaleString()}
        </p>
        <p style={{ color: '#6b6b6b', fontSize: '0.875rem', marginBottom: 32, lineHeight: 1.6 }}>
            我們會盡快處理您的訂單<br/>請留意 LINE 訊息通知
        </p>
        <button className="checkout-btn" onClick={onContinue}>
            繼續購物
        </button>
    </div>
);

// 訂單記錄頁
const OrdersPage = () => {
    const { user, showToast, handleLogin, authReady } = useApp();
    const [orders, setOrders] = useState([]);
    const [loading, setLoading] = useState(true);
    const [confirmingOrder, setConfirmingOrder] = useState(null);

    const fetchOrders = async () => {
        const token = localStorage.getItem('jwt_token');
        if (user?.userId && token) {
            try {
                const data = await api.getOrders(token);
                setOrders(data);
            } catch (error) {
                console.error('Fetch orders error:', error);
            }
        }
        setLoading(false);
    };

    useEffect(() => { fetchOrders(); }, [user]);

    const handleConfirmReceived = async (orderNumber) => {
        const token = localStorage.getItem('jwt_token');
        if (!token) return;
        setConfirmingOrder(orderNumber);
        try {
            const result = await api.confirmReceived(token, orderNumber);
            setOrders(prev => prev.map(o =>
                o.order_number === orderNumber ? result.order : o
            ));
            showToast('已確認收貨');
        } catch (error) {
            showToast(error.message || '確認收貨失敗');
        }
        setConfirmingOrder(null);
    };

    const statusText = {
        pending: '待確認',
        pending_payment: '待付款',
        paid: '已付款',
        confirmed: '已確認',
        shipped: '已出貨',
        ready_pickup: '待取貨',
        completed: '已完成',
        cancelled: '已取消',
        rejected: '已拒絕'
    };

    const receivableStatuses = new Set(['shipped', 'ready_pickup']);

    if (loading) return <Loading message="載入訂單" />;

    if (!user) {
        return (
            <div className="orders-page">
                <div className="cart-empty">
                    <div className="cart-empty-icon">
                        <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
                            <circle cx="32" cy="28" r="12" stroke="currentColor" strokeWidth="2" fill="none"/>
                            <path d="M16 52C16 43.1634 23.1634 36 32 36C40.8366 36 48 43.1634 48 52" stroke="currentColor" strokeWidth="2" strokeLinecap="round" fill="none"/>
                        </svg>
                    </div>
                    <p>請先登入查看訂單</p>
                    {authReady && (
                        <button className="login-btn" onClick={handleLogin} style={{ marginTop: 16 }}>
                            LINE 登入
                        </button>
                    )}
                </div>
            </div>
        );
    }

    if (orders.length === 0) {
        return (
            <div className="orders-page">
                <div className="cart-empty">
                    <div className="cart-empty-icon">
                        <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
                            <rect x="12" y="8" width="40" height="48" rx="4" stroke="currentColor" strokeWidth="2" fill="none"/>
                            <path d="M20 20H44M20 28H44M20 36H32" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
                        </svg>
                    </div>
                    <p>尚無訂單記錄</p>
                </div>
            </div>
        );
    }

    return (
        <div className="orders-page">
            {orders.map((order, index) => (
                <div key={order.id} className="order-card" style={{ animationDelay: `${index * 0.05}s` }}>
                    <div className="order-header">
                        <span className="order-number-label">{order.order_number}</span>
                        <span className={`order-status ${order.status}`}>
                            {statusText[order.status] || order.status}
                        </span>
                    </div>
                    <div className="order-items-preview">
                        {order.items?.slice(0, 2).map(item => item.product_name).join(', ')}
                        {order.items?.length > 2 && ` 等 ${order.items.length} 件商品`}
                    </div>
                    <div className="order-meta">
                        <span>{PAYMENT_LABELS[order.payment_method] || order.payment_method}</span>
                        {order.payment_method === 'store_pickup' && order.shipping_address && (
                            <span className="order-store-tag">{order.shipping_address}</span>
                        )}
                    </div>
                    <div className="order-total">NT$ {order.total_amount?.toLocaleString()}</div>
                    <div className="order-footer">
                        <span className="order-date">
                            {new Date(order.created_at).toLocaleString('zh-TW')}
                        </span>
                        {receivableStatuses.has(order.status) && (
                            <button
                                className="order-confirm-btn"
                                onClick={() => handleConfirmReceived(order.order_number)}
                                disabled={confirmingOrder === order.order_number}
                            >
                                {confirmingOrder === order.order_number ? '處理中...' : '確認收貨'}
                            </button>
                        )}
                    </div>
                </div>
            ))}
        </div>
    );
};

// 個人資料編輯彈窗
const ProfileEditModal = ({ profile, onClose, onSaved }) => {
    const { showToast } = useApp();
    const overlayRef = useRef(null);
    const contentRef = useRef(null);
    const closingRef = useRef(false);
    const [saving, setSaving] = useState(false);
    const [form, setForm] = useState({
        name: profile?.name || '',
        company: profile?.company || '',
        tax_id: profile?.tax_id || '',
        contact_person: profile?.contact_person || '',
        mobile: profile?.mobile || '',
        phone: profile?.phone || '',
        address: profile?.address || '',
    });

    const fieldLabels = [
        { key: 'name', label: '姓名' },
        { key: 'company', label: '公司' },
        { key: 'tax_id', label: '統一編號' },
        { key: 'contact_person', label: '聯絡人' },
        { key: 'mobile', label: '手機' },
        { key: 'phone', label: '電話' },
        { key: 'address', label: '地址' },
    ];

    const animateClose = useCallback(() => {
        if (closingRef.current) return;
        closingRef.current = true;
        const content = contentRef.current;
        const overlay = overlayRef.current;
        if (!content || !overlay) { onClose(); return; }
        Motion.animate(content, { opacity: 0, transform: 'translateY(60px)' }, { duration: 0.2, easing: 'ease-in' })
            .then(() => Motion.animate(overlay, { opacity: 0 }, { duration: 0.1 }))
            .then(() => onClose());
    }, [onClose]);

    useEffect(() => {
        const overlay = overlayRef.current;
        const content = contentRef.current;
        if (!overlay || !content) return;
        Motion.animate(overlay, { opacity: [0, 1] }, { duration: 0.15 });
        Motion.animate(content,
            { opacity: [0, 1], transform: ['translateY(60px) scale(0.97)', 'translateY(0px) scale(1)'] },
            { duration: 0.35, easing: [0.22, 1, 0.36, 1] }
        );
        const handleKey = (e) => { if (e.key === 'Escape') animateClose(); };
        document.addEventListener('keydown', handleKey);
        document.body.style.overflow = 'hidden';
        return () => {
            document.removeEventListener('keydown', handleKey);
            document.body.style.overflow = '';
        };
    }, [animateClose]);

    const handleBackdropClick = (e) => {
        if (e.target === overlayRef.current) animateClose();
    };

    const handleChange = (e) => {
        setForm({ ...form, [e.target.name]: e.target.value });
    };

    const handleSave = async () => {
        const token = localStorage.getItem('jwt_token');
        if (!token) return;
        setSaving(true);
        try {
            const updated = await api.updateProfile(token, form);
            showToast('資料已更新');
            onSaved(updated);
            onClose();
        } catch (error) {
            console.error('Profile update error:', error);
            showToast('更新失敗，請稍後再試');
            setSaving(false);
        }
    };

    return (
        <div className="product-modal-overlay" ref={overlayRef} onClick={handleBackdropClick}>
            <div className="profile-modal-content" ref={contentRef}>
                <div className="profile-modal-header">
                    <h3>編輯個人資料</h3>
                    <button className="product-modal-close" onClick={animateClose} aria-label="關閉" style={{ position: 'static', background: 'var(--bg-tertiary)', color: 'var(--text-secondary)' }}>
                        <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                            <path d="M4 4L12 12M12 4L4 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
                        </svg>
                    </button>
                </div>
                <div className="profile-modal-body">
                    {fieldLabels.map(({ key, label }) => (
                        <div key={key} className="form-group">
                            <label>{label}</label>
                            {key === 'address' ? (
                                <textarea
                                    name={key}
                                    value={form[key]}
                                    onChange={handleChange}
                                    placeholder={`請輸入${label}`}
                                />
                            ) : (
                                <input
                                    type="text"
                                    name={key}
                                    value={form[key]}
                                    onChange={handleChange}
                                    placeholder={`請輸入${label}`}
                                />
                            )}
                        </div>
                    ))}
                </div>
                <div className="profile-modal-footer">
                    <button className="profile-cancel-btn" onClick={animateClose}>取消</button>
                    <button className="profile-save-btn" onClick={handleSave} disabled={saving}>
                        {saving ? '儲存中...' : '儲存'}
                    </button>
                </div>
            </div>
        </div>
    );
};

// 個人資料頁
const ProfilePage = () => {
    const { user, handleLogin, logout, authReady, showToast } = useApp();
    const [profile, setProfile] = useState(null);
    const [orders, setOrders] = useState([]);
    const [loading, setLoading] = useState(true);
    const [showEditModal, setShowEditModal] = useState(false);
    const [cancellingOrder, setCancellingOrder] = useState(null);
    const [confirmingOrder, setConfirmingOrder] = useState(null);

    useEffect(() => {
        const fetchData = async () => {
            const token = localStorage.getItem('jwt_token');
            if (!token || !user) {
                setLoading(false);
                return;
            }
            try {
                const [profileData, ordersData] = await Promise.all([
                    api.getProfile(token),
                    api.getOrders(token)
                ]);
                setProfile(profileData);
                setOrders(ordersData);
            } catch (error) {
                console.error('Profile fetch error:', error);
            }
            setLoading(false);
        };
        fetchData();
    }, [user]);

    const handleCancelOrder = async (orderNumber) => {
        if (!confirm('確定要取消此訂單嗎？')) return;
        const token = localStorage.getItem('jwt_token');
        if (!token) return;
        setCancellingOrder(orderNumber);
        try {
            const result = await api.cancelOrder(token, orderNumber);
            setOrders(prev => prev.map(o =>
                o.order_number === orderNumber ? result.order : o
            ));
            showToast('訂單已取消');
        } catch (error) {
            showToast(error.message || '取消失敗');
        }
        setCancellingOrder(null);
    };

    const handleConfirmReceived = async (orderNumber) => {
        if (!confirm('確認已收到商品嗎？')) return;
        const token = localStorage.getItem('jwt_token');
        if (!token) return;
        setConfirmingOrder(orderNumber);
        try {
            const result = await api.confirmReceived(token, orderNumber);
            setOrders(prev => prev.map(o =>
                o.order_number === orderNumber ? result.order : o
            ));
            showToast('已確認收貨');
        } catch (error) {
            showToast(error.message || '確認收貨失敗');
        }
        setConfirmingOrder(null);
    };

    const statusText = {
        pending: '待確認', pending_payment: '待付款', paid: '已付款',
        confirmed: '已確認', shipped: '已出貨', ready_pickup: '待取貨',
        completed: '已完成', cancelled: '已取消', rejected: '已拒絕'
    };

    const cancellableStatuses = new Set(['pending', 'pending_payment', 'confirmed']);
    const receivableStatuses = new Set(['shipped', 'ready_pickup']);

    const roleBadgeLabel = { customer: '一般客戶', jeweler: '銀樓', admin: '管理員' };

    if (loading) return <Loading message="載入個人資料" />;

    if (!user) {
        return (
            <div className="profile-page">
                <div className="cart-empty">
                    <div className="cart-empty-icon">
                        <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
                            <circle cx="32" cy="28" r="12" stroke="currentColor" strokeWidth="2" fill="none"/>
                            <path d="M16 52C16 43.1634 23.1634 36 32 36C40.8366 36 48 43.1634 48 52" stroke="currentColor" strokeWidth="2" strokeLinecap="round" fill="none"/>
                        </svg>
                    </div>
                    <p>請先登入</p>
                    {authReady && (
                        <button className="login-btn" onClick={handleLogin} style={{ marginTop: 16 }}>
                            LINE 登入
                        </button>
                    )}
                </div>
            </div>
        );
    }

    return (
        <div className="profile-page">
            {/* 金屬卡片 */}
            <div className="profile-card">
                <div className="profile-card-content">
                    {user.pictureUrl ? (
                        <img src={user.pictureUrl} alt="" className="profile-avatar" />
                    ) : (
                        <div className="profile-avatar-placeholder">
                            <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                                <circle cx="12" cy="8" r="4" stroke="currentColor" strokeWidth="1.5" fill="none"/>
                                <path d="M4 20c0-4.418 3.582-8 8-8s8 3.582 8 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" fill="none"/>
                            </svg>
                        </div>
                    )}
                    <div className="profile-card-info">
                        <div className="profile-card-name">{profile?.name || user.displayName}</div>
                        {profile?.company && <div className="profile-card-company">{profile.company}</div>}
                        <span className={`profile-role-badge ${profile?.role || user.role || 'customer'}`}>
                            {roleBadgeLabel[profile?.role || user.role] || '一般客戶'}
                        </span>
                    </div>
                    <button className="profile-card-edit-btn" onClick={() => setShowEditModal(true)} aria-label="編輯個人資料">
                        <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
                            <path d="M11.5 1.5L14.5 4.5L5 14H2V11L11.5 1.5Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
                        </svg>
                    </button>
                </div>
            </div>

            {/* 登出 */}
            <button className="profile-logout-btn" onClick={logout}>登出</button>

            {/* 歷史訂單 */}
            {orders.length > 0 && (
                <div className="profile-section">
                    <div className="profile-section-header">
                        <h3>歷史訂單</h3>
                    </div>
                    {orders.map((order, index) => (
                        <div key={order.id} className="order-card" style={{ animationDelay: `${index * 0.05}s` }}>
                            <div className="order-header">
                                <span className="order-number-label">{order.order_number}</span>
                                <span className={`order-status ${order.status}`}>
                                    {statusText[order.status] || order.status}
                                </span>
                            </div>
                            <div className="order-items-detail">
                                {order.items?.map((item, i) => (
                                    <div key={i} className="order-item-row">
                                        <span className="order-item-name">{item.product_name}</span>
                                        <span className="order-item-qty">x{item.quantity}</span>
                                        <span className="order-item-price">NT$ {item.subtotal?.toLocaleString()}</span>
                                    </div>
                                ))}
                            </div>
                            <div className="order-meta">
                                <span>{PAYMENT_LABELS[order.payment_method] || order.payment_method}</span>
                                {order.payment_method === 'store_pickup' && order.shipping_address && (
                                    <span className="order-store-tag">{order.shipping_address}</span>
                                )}
                            </div>
                            <div className="order-total">NT$ {order.total_amount?.toLocaleString()}</div>
                            <div className="order-footer">
                                <span className="order-date">
                                    {new Date(order.created_at).toLocaleString('zh-TW')}
                                </span>
                                {receivableStatuses.has(order.status) && (
                                    <button
                                        className="order-confirm-btn"
                                        onClick={() => handleConfirmReceived(order.order_number)}
                                        disabled={confirmingOrder === order.order_number}
                                    >
                                        {confirmingOrder === order.order_number ? '處理中...' : '確認收貨'}
                                    </button>
                                )}
                                {cancellableStatuses.has(order.status) && (
                                    <button
                                        className="order-cancel-btn"
                                        onClick={() => handleCancelOrder(order.order_number)}
                                        disabled={cancellingOrder === order.order_number}
                                    >
                                        {cancellingOrder === order.order_number ? '取消中...' : '取消訂單'}
                                    </button>
                                )}
                            </div>
                        </div>
                    ))}
                </div>
            )}

            {/* 編輯彈窗 */}
            {showEditModal && (
                <ProfileEditModal
                    profile={profile}
                    onClose={() => setShowEditModal(false)}
                    onSaved={(updated) => setProfile(updated)}
                />
            )}
        </div>
    );
};

// ==================== Main App ====================
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 logout = useCallback(() => {
        localStorage.removeItem('jwt_token');
        setUser(null);
        setAuthReady(false);
        setTimeout(() => setAuthReady(true), 0);
    }, []);

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

                // --- JWT 認證流程 ---
                // 1) 檢查 URL hash fragment #token=（OAuth callback 回來的 JWT）
                const hash = window.location.hash;
                if (hash.startsWith('#token=')) {
                    const urlToken = hash.substring(7);
                    localStorage.setItem('jwt_token', urlToken);
                    // 清除 hash
                    window.history.replaceState({}, '', window.location.pathname);
                }

                const storedToken = localStorage.getItem('jwt_token');

                // 2) 嘗試從 localStorage 還原 session
                if (storedToken) {
                    try {
                        const me = await api.getMe(storedToken);
                        setUser({
                            userId: me.line_uid,
                            displayName: me.name,
                            pictureUrl: me.picture_url,
                            role: me.role,
                            _authenticated: true
                        });
                    } catch (e) {
                        // JWT 過期或無效 → 清除
                        localStorage.removeItem('jwt_token');
                    }
                }

                // 3) 若無 JWT 但有 LIFF → 用 LIFF access token 換 JWT
                if (!localStorage.getItem('jwt_token') && config.liffId) {
                    await liffService.init(config.liffId);
                    if (liffService.isLoggedIn) {
                        try {
                            const liffAccessToken = liff.getAccessToken();
                            if (liffAccessToken) {
                                const authResult = await api.authLiff(liffAccessToken);
                                localStorage.setItem('jwt_token', authResult.token);
                                const u = authResult.user;
                                setUser({
                                    userId: u.line_uid,
                                    displayName: u.name,
                                    pictureUrl: u.picture_url,
                                    role: u.role,
                                    _authenticated: true
                                });
                            }
                        } catch (e) {
                            console.error('LIFF auth error:', e);
                            // 降級：僅用 LIFF profile（未驗證）
                            if (liffService.profile) {
                                setUser(liffService.profile);
                            }
                        }
                    }
                    // LIFF 已初始化但未登入 → 之後由 UI 觸發登入
                }

                setAuthReady(true);

                // --- 載入商品 ---
                const productsData = await api.getProducts();
                setProducts(productsData);

                // 同步購物車中的商品圖片（localStorage 可能有舊資料）
                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');
                }

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

        init();
    }, []);

    // WebSocket：即時接收價格/庫存更新事件，自動刷新商品和價格
    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) { /* ignore */ }
            };
            ws.onclose = () => {
                reconnectTimer = setTimeout(connect, 5000);
            };
        };
        connect();
        return () => {
            clearTimeout(reconnectTimer);
            if (ws) ws.close();
        };
    }, []);

    // 儲存購物車到 localStorage
    useEffect(() => {
        localStorage.setItem('cart', JSON.stringify(cart));
    }, [cart]);

    // 購物車操作
    const productsRef = useRef(products);
    productsRef.current = products;
    const cartRef = useRef(cart);
    cartRef.current = cart;

    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 showToast = useCallback((message) => {
        setToast(message);
    }, []);

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

    // 登入處理
    const handleLogin = useCallback(() => {
        if (liffService.liff && liffService.liff.isInClient()) {
            // LIFF 內：呼叫 liff.login()
            liffService.login();
        } else {
            // 一般瀏覽器：導向 OAuth 流程
            window.location.href = '/api/auth/line';
        }
    }, []);

    // Context value
    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">
                <header className="header">
                    <h1>貴金屬訂購</h1>
                </header>

                <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)} />}
            </div>
        </AppContext.Provider>
    );
};

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