import React, { useState, useEffect, useMemo } from 'react';
import { useGame } from '../../contexts/GameContext';
import { GAME_API_URL } from '../../config';
import { GameModal } from './GameModal';
import { GameButton } from '../common/GameButton';
import { GameItemCard } from '../common/GameItemCard';
import { getTranslatedText } from '../../utils/i18nUtils';
import { useTranslation } from 'react-i18next';
import './TradeModal.css';

interface TradeItem {
    item_id: string;
    name: string; // This might be a translatable object or string
    emoji?: string;
    quantity: number;
    value: number;
    unique_item_id?: number;
    is_infinite?: boolean;
    description?: string;
    item_type?: string;
    stats?: any;
    unique_stats?: any;
    image_path?: string;
    tier?: number;
    effects?: any;
    weight?: number;
    volume?: number;
    hp_restore?: number;
    stamina_restore?: number;
    equippable?: boolean;
    consumable?: boolean;
    slot?: string;
    is_equipped?: boolean;
}

interface Selection {
    item_id: string;
    quantity: number;
    value: number;
    unique_item_id?: number;
    name: string;
    emoji?: string;
    image_path?: string;
    tier?: number;
}

interface TradeModalProps {
    npcId: string;
    onClose: () => void;
}

export const TradeModal: React.FC<TradeModalProps> = ({ npcId, onClose }) => {
    const { token, inventory: playerInv } = useGame();
    const { t } = useTranslation();

    const [npcStock, setNpcStock] = useState<TradeItem[]>([]);
    const [playerItems, setPlayerItems] = useState<TradeItem[]>([]);

    const [buying, setBuying] = useState<Selection[]>([]); // Items selected from NPC
    const [selling, setSelling] = useState<Selection[]>([]); // Items selected from Player

    const [tradeConfig, setTradeConfig] = useState<any>({});

    // Filters
    const [npcSearch, setNpcSearch] = useState('');
    const [playerSearch, setPlayerSearch] = useState('');

    const categories = [
        { id: 'all', label: t('categories.all'), icon: '🎒' },
        { id: 'weapon', label: t('categories.weapon'), icon: '⚔️' },
        { id: 'armor', label: t('categories.armor'), icon: '🛡️' },
        { id: 'clothing', label: t('categories.clothing'), icon: '👕' },
        { id: 'backpack', label: t('categories.backpack'), icon: '🎒' },
        { id: 'tool', label: t('categories.tool'), icon: '🛠️' },
        { id: 'consumable', label: t('categories.consumable'), icon: '🍖' },
        { id: 'resource', label: t('categories.resource'), icon: '📦' },
        { id: 'quest', label: t('categories.quest'), icon: '📜' },
        { id: 'misc', label: t('categories.misc'), icon: '📦' }
    ];

    // Selection logic
    const [selectedItem, setSelectedItem] = useState<TradeItem | null>(null);
    const [showQtyModal, setShowQtyModal] = useState(false);
    const [qtyInput, setQtyInput] = useState(1);
    const [selectionSource, setSelectionSource] = useState<'npc' | 'player'>('npc');

    useEffect(() => {
        // Determine player items from context inventory
        if (!playerInv) return;
        const mappedPlayerItems = playerInv.map((i: any) => ({
            ...i,
            // Backend now sends flat structure, but we keep falbacks just in case
            value: i.value || i.item_def?.value || 10,
            name: i.name || (i.item_def ? i.item_def.name : i.item_id),
            emoji: i.emoji || i.item_def?.emoji || '📦',
            description: i.description || (i.item_def ? i.item_def.description : ''),
            item_type: i.type || i.item_type || i.item_def?.item_type, // 'type' from backend, 'item_type' variable
            stats: i.stats || i.item_def?.stats,
            unique_stats: i.unique_stats,
            image_path: i.image_path || i.item_def?.image_path,
            tier: i.tier || i.item_def?.tier,
            effects: i.effects || i.item_def?.effects,
            weight: i.weight || i.item_def?.weight || 0,
            volume: i.volume || i.item_def?.volume || 0,
            hp_restore: i.hp_restore || i.item_def?.hp_restore,
            stamina_restore: i.stamina_restore || i.item_def?.stamina_restore,
            equippable: i.equippable || i.item_def?.equippable,
            consumable: i.consumable || i.item_def?.consumable
        }));
        setPlayerItems(mappedPlayerItems);
    }, [playerInv]);

    useEffect(() => {
        const fetchStock = async () => {
            try {
                const res = await fetch(`${GAME_API_URL}/trade/${npcId}`, {
                    headers: { 'Authorization': `Bearer ${token}` }
                });
                const data = await res.json();

                // Map NPC stock similarly
                // Note: The backend returns item details mixed in usually, but let's verify if we need to map via item_def logic on frontend or if backend sends it all.
                // Looking at trade.py, it sends 'name', 'emoji', 'quantity', 'value', 'unique_item_id'.
                // If we want stats, we might need more data from backend or map it if we have a global items list. 
                // Currently only name/emoji/value are strictly returned. 
                // Ideally backend should send full item_def or we need to access ItemsManager context if available.
                // For now, we work with what we have, or assume backend trade endpoint includes simplified data.
                // Wait, trade.py returns: "name": item_def.name, "emoji": item_def.emoji... it doesn't return generic stats.
                // We'll stick to what we have but if backend is updated we'd use it. 
                // *Crucial*: To show stats, we'd need them in the API response. I will assume for now we might miss detailed stats for NPC items unless I update backend.
                // BUT, for Player items we have full access via context.

                setNpcStock(data.stock);
                setTradeConfig(data.config);
            } catch (e) {
                console.error(e);
            }
        };
        if (token) fetchStock();
    }, [npcId, token]);

    // Computed Lists (Virtual Inventory with Subtraction)
    const availableNpcStock = useMemo(() => {
        return npcStock.map(item => {
            // Find how many are currently in 'buying' list
            const inCart = buying.find(b => b.item_id === item.item_id && b.unique_item_id === item.unique_item_id);
            const qtyInCart = inCart ? inCart.quantity : 0;
            const remaining = item.is_infinite ? 999 : Math.max(0, item.quantity - qtyInCart);

            return { ...item, _displayQuantity: remaining };
        }).filter(item => {
            // Filter by search
            const n = getTranslatedText(item.name).toLowerCase();
            return n.includes(npcSearch.toLowerCase());
        }).sort((a: any, b: any) => {
            // High tier first, then name
            if ((a.tier || 0) !== (b.tier || 0)) return (b.tier || 0) - (a.tier || 0);
            return (getTranslatedText(a.name) || '').localeCompare(getTranslatedText(b.name) || '');
        });
    }, [npcStock, npcSearch, buying]);

    const availablePlayerInv = useMemo(() => {
        return playerItems.map(item => {
            // Find how many are currently in 'selling' list
            const inCart = selling.find(s => s.item_id === item.item_id && s.unique_item_id === item.unique_item_id);
            const qtyInCart = inCart ? inCart.quantity : 0;
            const remaining = Math.max(0, item.quantity - qtyInCart);

            return { ...item, _displayQuantity: remaining };
        }).filter(item => {
            const n = getTranslatedText(item.name).toLowerCase();
            if (!n.includes(playerSearch.toLowerCase())) return false;
            // Hide items with 0 quantity remaining?
            if (item._displayQuantity <= 0) return false;
            if (item.is_equipped) return false; // Usually can't sell equipped items directly
            return true;
        }).sort((a: any, b: any) => {
            // High tier first, then name
            if ((a.tier || 0) !== (b.tier || 0)) return (b.tier || 0) - (a.tier || 0);
            return (getTranslatedText(a.name) || '').localeCompare(getTranslatedText(b.name) || '');
        });
    }, [playerItems, playerSearch, selling]);

    // Calculations
    const buyTotal = buying.reduce((sum, item) => sum + (item.value * (tradeConfig.buy_markup || 1) * item.quantity), 0);
    const sellTotal = selling.reduce((sum, item) => sum + (item.value * (tradeConfig.sell_markdown || 1) * item.quantity), 0);

    // Validity checking
    const isValid = sellTotal >= buyTotal && (buying.length > 0 || selling.length > 0);

    const handleItemClick = (item: TradeItem, source: 'npc' | 'player') => {
        // Use the displayed quantity which already accounts for cart
        // But we need the *original* item to check is_infinite etc. 
        // Actually, we can just use the mapped item's _displayQuantity as the max available to add *more*.

        const maxAvailable = (item as any)._displayQuantity;

        if (maxAvailable <= 0) return;

        setSelectedItem(item);
        setSelectionSource(source);
        setQtyInput(1);
        setShowQtyModal(true);
    };

    const confirmSelection = () => {
        if (!selectedItem) return;

        const list = selectionSource === 'npc' ? buying : selling;
        const setList = selectionSource === 'npc' ? setBuying : setSelling;

        // Max available to add is displayed quantity
        const maxAvailable = (selectedItem as any)._displayQuantity;

        let finalQty = qtyInput;
        if (finalQty > maxAvailable) finalQty = maxAvailable;

        if (finalQty <= 0) {
            setShowQtyModal(false);
            setSelectedItem(null);
            return;
        }

        const existingIdx = list.findIndex(i => i.item_id === selectedItem.item_id && i.unique_item_id === selectedItem.unique_item_id);

        if (existingIdx >= 0) {
            // Update quantity
            const newList = [...list];
            newList[existingIdx].quantity += finalQty;
            setList(newList);
        } else {
            // Add new
            setList([...list, {
                item_id: selectedItem.item_id,
                quantity: finalQty,
                value: selectedItem.value,
                unique_item_id: selectedItem.unique_item_id,
                name: selectedItem.name,
                emoji: selectedItem.emoji,
                image_path: selectedItem.image_path,
                tier: selectedItem.tier
            }]);
        }

        setShowQtyModal(false);
        setSelectedItem(null);
    };

    const executeTrade = async () => {
        try {
            const res = await fetch(`${GAME_API_URL}/trade/${npcId}/execute`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    buying: buying,
                    selling: selling
                })
            });

            const result = await res.json();
            if (res.ok) {
                alert("Trade Successful!");
                onClose();
                // Should trigger inventory refresh
                window.location.reload();
            } else {
                alert("Trade Failed: " + result.detail);
            }
        } catch (e) {
            console.error(e);
            alert("Trade Error");
        }
    };

    // Drag and Drop Logic
    const [dragOverZone, setDragOverZone] = useState<'buy' | 'sell' | null>(null);

    const handleDragStart = (e: React.DragEvent, item: TradeItem, source: 'npc' | 'player') => {
        e.dataTransfer.setData('application/json', JSON.stringify({ item, source }));
        e.dataTransfer.effectAllowed = 'copy';
    };

    const handleDragOver = (e: React.DragEvent, zone: 'buy' | 'sell') => {
        e.preventDefault();
        if (dragOverZone !== zone) setDragOverZone(zone);
    };

    const handleDragLeave = () => {
        setDragOverZone(null);
    };

    const handleDrop = (e: React.DragEvent, zone: 'buy' | 'sell') => {
        e.preventDefault();
        setDragOverZone(null);

        try {
            const data = JSON.parse(e.dataTransfer.getData('application/json'));
            const { item, source } = data;

            if (zone === 'buy' && source === 'npc') {
                handleItemClick(item, 'npc');
            } else if (zone === 'sell' && source === 'player') {
                handleItemClick(item, 'player');
            }
        } catch (err) {
            console.error('Failed to parse drag data', err);
        }
    };

    if (!npcStock || !tradeConfig) return <div className="loading-text">Loading trade data...</div>;

    return (
        <GameModal
            title={t('trade.title')}
            onClose={onClose}
            className="trade-modal"
        >
            <div className="trade-container">
                <div className="trade-content">
                    {/* LEFT: NPC STOCK */}
                    <div className="trade-column">
                        <h3 className="column-header">{t('trade.merchantStock')} {tradeConfig.buy_markup && <small>(x{tradeConfig.buy_markup})</small>}</h3>
                        <div className="game-search-container" style={{ marginBottom: '0.5rem' }}>
                            <span className="game-search-icon">🔍</span>
                            <input
                                type="text"
                                className="search-bar"
                                placeholder="Filter..."
                                value={npcSearch}
                                onChange={(e) => setNpcSearch(e.target.value)}
                            />
                        </div>
                        <div className="trade-inventory-grid">
                            {categories.filter(cat => cat.id !== 'all').map(cat => {
                                const categoryItems = availableNpcStock.filter((item: any) => item.item_type === cat.id);
                                if (categoryItems.length === 0) return null;
                                return (
                                    <React.Fragment key={cat.id}>
                                        <div className="category-header" style={{ gridColumn: '1 / -1', marginTop: '10px' }}>
                                            <span className="subcat-icon">{cat.icon}</span>
                                            <span className="subcat-label">{cat.label}</span>
                                        </div>
                                        {categoryItems.map((item, idx) => (
                                            <GameItemCard
                                                key={idx}
                                                item={item}
                                                onClick={() => handleItemClick(item, 'npc')}
                                                draggable={true}
                                                onDragStart={(e) => handleDragStart(e, item, 'npc')}
                                                showValue={true}
                                                valueDisplayType="unit"
                                                tradeMarkup={tradeConfig.buy_markup || 1}
                                            />
                                        ))}
                                    </React.Fragment>
                                );
                            })}
                        </div>
                    </div>

                    {/* CENTER: CART */}
                    <div className="trade-center-column">
                        <div
                            className={`trade-cart-section ${dragOverZone === 'buy' ? 'drag-over' : ''}`}
                            onDragOver={(e) => handleDragOver(e, 'buy')}
                            onDragLeave={handleDragLeave}
                            onDrop={(e) => handleDrop(e, 'buy')}
                        >
                            <div className="trade-list-header">
                                <span>{t('trade.buying')}</span>
                                <span style={{ color: '#ff9800' }}>{Math.round(buyTotal)}</span>
                            </div>
                            <div className="cart-grid">
                                {buying.length === 0 && <div style={{ color: '#666', gridColumn: '1 / -1', textAlign: 'center', padding: '10px' }}>{t('trade.empty')}</div>}
                                {buying.map((b, i) => (
                                    <GameItemCard
                                        key={i}
                                        item={b}
                                        onClick={() => {
                                            const n = [...buying]; n.splice(i, 1); setBuying(n);
                                        }}
                                        showValue={true}
                                        valueDisplayType="total"
                                        tradeMarkup={tradeConfig.buy_markup || 1}
                                        actionHint={t('trade.clickToRemove')}
                                    />
                                ))}
                            </div>
                        </div>

                        {/* BALANCE INDICATOR MOVED TO CENTER DIVIDER */}
                        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '10px 0', borderTop: '1px solid #444', borderBottom: '1px solid #444', background: 'rgba(0,0,0,0.3)' }}>
                            <div className="trade-summary" style={{ flexDirection: 'row', gap: '15px' }}>
                                <span>{t('trade.balance')}:</span>
                                <span className={`trade-total ${sellTotal >= buyTotal ? 'text-green' : 'text-red'}`}>
                                    {Math.round(sellTotal - buyTotal)} {sellTotal >= buyTotal ? '▲' : '▼'}
                                </span>
                            </div>
                        </div>

                        <div
                            className={`trade-cart-section ${dragOverZone === 'sell' ? 'drag-over' : ''}`}
                            onDragOver={(e) => handleDragOver(e, 'sell')}
                            onDragLeave={handleDragLeave}
                            onDrop={(e) => handleDrop(e, 'sell')}
                        >
                            <div className="trade-list-header">
                                <span>{t('trade.selling')}</span>
                                <span style={{ color: '#4caf50' }}>{Math.round(sellTotal)}</span>
                            </div>
                            <div className="cart-grid">
                                {selling.length === 0 && <div style={{ color: '#666', gridColumn: '1 / -1', textAlign: 'center', padding: '10px' }}>{t('trade.empty')}</div>}
                                {selling.map((b, i) => (
                                    <GameItemCard
                                        key={i}
                                        item={b}
                                        onClick={() => {
                                            const n = [...selling]; n.splice(i, 1); setSelling(n);
                                        }}
                                        showValue={true}
                                        valueDisplayType="total"
                                        tradeMarkup={tradeConfig.sell_markdown || 1}
                                        actionHint={t('trade.clickToRemove')}
                                    />
                                ))}
                            </div>
                        </div>
                    </div>

                    {/* RIGHT: PLAYER INVENTORY */}
                    <div className="trade-column">
                        <h3 className="column-header">{t('trade.inventory')} {tradeConfig.sell_markdown && <small>(x{tradeConfig.sell_markdown})</small>}</h3>
                        <div className="game-search-container" style={{ marginBottom: '0.5rem' }}>
                            <span className="game-search-icon">🔍</span>
                            <input
                                type="text"
                                className="search-bar"
                                placeholder="Filter..."
                                value={playerSearch}
                                onChange={(e) => setPlayerSearch(e.target.value)}
                            />
                        </div>
                        <div className="trade-inventory-grid">
                            {categories.filter(cat => cat.id !== 'all').map(cat => {
                                const categoryItems = availablePlayerInv.filter((item: any) => item.item_type === cat.id);
                                if (categoryItems.length === 0) return null;
                                return (
                                    <React.Fragment key={cat.id}>
                                        <div className="category-header" style={{ gridColumn: '1 / -1', marginTop: '10px' }}>
                                            <span className="subcat-icon">{cat.icon}</span>
                                            <span className="subcat-label">{cat.label}</span>
                                        </div>
                                        {categoryItems.map((item, idx) => (
                                            <GameItemCard
                                                key={idx}
                                                item={item}
                                                onClick={() => handleItemClick(item, 'player')}
                                                draggable={true}
                                                onDragStart={(e) => handleDragStart(e, item, 'player')}
                                                showValue={true}
                                                valueDisplayType="unit"
                                                tradeMarkup={tradeConfig.sell_markdown || 1}
                                            />
                                        ))}
                                    </React.Fragment>
                                );
                            })}
                        </div>
                    </div>
                </div>

                <div className="trade-footer">
                    <button className="trade-action-btn" onClick={executeTrade} disabled={!isValid}>
                        {isValid ? t('trade.confirmTrade') : t('trade.invalidOffer')}
                    </button>
                    <div style={{ width: '60px' }}></div> {/* Spacer */}
                </div>

                {showQtyModal && selectedItem && (() => {
                    const maxAvailable = (selectedItem as any)._displayQuantity || 1;
                    return (
                        <div className="dialog-modal-overlay" style={{ zIndex: 1101 }}>
                            <div className="quantity-modal">
                                <h4>{t('trade.howMany', { item: getTranslatedText(selectedItem.name) })}</h4>
                                <div style={{ display: 'flex', justifyContent: 'center', marginBottom: '10px' }}>
                                    <GameItemCard item={selectedItem} showTooltip={false} showQuantity={false} />
                                </div>
                                <div className="qty-controls">
                                    <GameButton size="sm" onClick={() => setQtyInput(Math.max(1, qtyInput - 1))} disabled={qtyInput <= 1}>-</GameButton>
                                    <input
                                        className="qty-input"
                                        type="number"
                                        value={qtyInput}
                                        onChange={e => {
                                            const val = parseInt(e.target.value);
                                            if (isNaN(val)) {
                                                setQtyInput(1);
                                            } else {
                                                setQtyInput(Math.min(Math.max(1, val), maxAvailable));
                                            }
                                        }}
                                        min="1"
                                        max={maxAvailable}
                                    />
                                    <GameButton size="sm" onClick={() => setQtyInput(Math.min(maxAvailable, qtyInput + 1))} disabled={qtyInput >= maxAvailable}>+</GameButton>
                                    <GameButton size="sm" onClick={() => setQtyInput(maxAvailable)}>Max</GameButton>
                                </div>
                                <div style={{ display: 'flex', gap: '10px' }}>
                                    <GameButton variant="primary" onClick={confirmSelection}>Confirm</GameButton>
                                    <GameButton variant="secondary" onClick={() => setShowQtyModal(false)}>Cancel</GameButton>
                                </div>
                            </div>
                        </div>
                    );
                })()}
            </div>
        </GameModal>
    );
};
