/**
 * Flag Detection Algorithm - Hybrid Approach with Dynamic Discovery
 * Handles flag generation for all asset types with intelligent fallback systems
 */

class FlagDetectionAlgorithm {
    constructor() {
        this.isReady = false;
        this.readyPromise = null;
        this.directFlagMapping = {};
        this.availableFlags = null;
        this.flagCache = new Map();
        this.readyPromise = this.initialize();
    }

    async initialize() {
        await Promise.all([
            this.loadAssetMappings(),
            this.initializeAvailableFlags()
        ]);
        return this;
    }

    async loadAssetMappings() {
        try {
            const response = await fetch('./js/asset-mapping.json');
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            const data = await response.json();
            this.assetMappings = data;
            this.directFlagMapping = {
                ...data.currencyPairs.major,
                ...data.currencyPairs.exotic,
                ...data.cryptocurrencies,
                ...data.stocks,
                ...data.indices,
                ...data.commodities
            };
        } catch (error) {
            this.assetMappings = {};
            this.directFlagMapping = {};
        }
    }

    async initializeAvailableFlags() {
        try {
            const response = await fetch('./svg/flags.svg');

            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }

            const svgText = await response.text();

            this.availableFlags = this.extractFlagIds(svgText);
            this.isReady = true;
        } catch (error) {
            this.availableFlags = new Set();
            this.isReady = true;
        }
    }

    extractFlagIds(svgText) {
        const flagIds = new Set();
        const regex = /id="flag-([^"]+)"/g;
        let match;
        let matchCount = 0;

        while ((match = regex.exec(svgText)) !== null) {
            flagIds.add(match[1]);
            matchCount++;
        }

        return flagIds;
    }

    async generateTradeFlags(assetName, className = 'trade-history-flag') {
        if (!this.isReady) {
            await this.readyPromise;
        }

        const originalAssetName = window.getOriginalAssetName ? window.getOriginalAssetName(assetName, 'cardName') : assetName;

        if (!originalAssetName) {
            return this.getDefaultFlags();
        }

        let flags = [];

        const directFlags = this.directFlagMapping[originalAssetName];

        if (directFlags) {
            flags = Array.isArray(directFlags) ? [...directFlags] : ['usd', directFlags];
        } else {
            flags = this.discoverFlags(originalAssetName);
        }

        if (flags.length === 0) {
            flags = ['usd', 'bdt'];
        }

        const flagsHtml = this.generateFlagsHtml(flags, className);
        return flagsHtml;
    }

    discoverFlags(assetName) {
        const companyFlags = this.extractCompanyFlags(assetName);
        if (companyFlags.length > 0) {
            return companyFlags;
        }

        const cryptoFlags = this.extractCryptoFlags(assetName);
        if (cryptoFlags.length > 0) {
            return cryptoFlags;
        }

        const commodityFlags = this.extractCommodityFlags(assetName);
        if (commodityFlags.length > 0) {
            return commodityFlags;
        }

        const currencyFlags = this.extractCurrencyFlags(assetName);
        return currencyFlags;
    }

    extractCompanyFlags(assetName) {
        const companyPatterns = {
            'boeing': 'ba',
            'facebook': 'fb',
            'intel': 'intc',
            'johnson': 'jnj',
            'mcdonald': 'mcd',
            'pfizer': 'pfe',
            'american express': 'axp',
            'microsoft': 'msft',
            'apple': 'aapl',
            'amazon': 'amzn',
            'google': 'googl',
            'tesla': 'tsla',
            'netflix': 'nflx',
            'meta': 'fb'
        };

        const lowerAsset = assetName.toLowerCase();

        for (const [company, symbol] of Object.entries(companyPatterns)) {
            if (lowerAsset.includes(company) || company.startsWith(lowerAsset.replace('...', ''))) {
                const result = this.validateFlags([symbol, 'usd']);
                return result;
            }
        }
        return [];
    }

    extractCryptoFlags(assetName) {
        const cryptoPatterns = {
            'bitcoin': 'btc',
            'ethereum': 'eth',
            'litecoin': 'ltc',
            'aptos': 'apt',
            'arbitrum': 'arb',
            'axie': 'axs',
            'bonk': 'bon',
            'polkadot': 'dot',
            'floki': 'flo',
            'hamster': 'hms',
            'chainlink': 'lin',
            'decentraland': 'man',
            'pepe': 'pep',
            'shiba': 'shi',
            'solana': 'sol',
            'celestia': 'tia',
            'toncoin': 'ton',
            'trump': 'tru',
            'tron': 'trx',
            'dogwifhat': 'wif',
            'ripple': 'xrp',
            'zcash': 'zec',
            'melania': 'mel',
            'binance': 'bnb',
            'avalanche': 'ava',
            'cosmos': 'ato',
            'beam': 'bea',
            'dash': 'das',
            'cardano': 'ada',
            'dogecoin': 'dog',
            'bitcoin cash': 'bch',
            'ethereum classic': 'etc'
        };

        const lowerAsset = assetName.toLowerCase();

        for (const [crypto, symbol] of Object.entries(cryptoPatterns)) {
            if (lowerAsset.includes(crypto) || crypto.startsWith(lowerAsset.replace('...', ''))) {
                const result = this.validateFlags([symbol, 'usd']);
                return result;
            }
        }
        return [];
    }

    extractCommodityFlags(assetName) {
        const lowerAsset = assetName.toLowerCase();
        const cleanAsset = lowerAsset.replace('...', '').replace(/\s+/g, '');

        if (lowerAsset.includes('us crude') || lowerAsset.includes('uscrude') || cleanAsset.includes('uscrude')) {
            const result = this.validateFlags(['uscrude', 'usd']);
            return result;
        }
        
        if (lowerAsset.includes('uk brent') || lowerAsset.includes('ukbrent') || lowerAsset.includes('brent') || cleanAsset.includes('ukbrent')) {
            const result = this.validateFlags(['ukbrent', 'usd']);
            return result;
        }
        
        if (lowerAsset.includes('gold')) {
            const result = this.validateFlags(['xau', 'usd']);
            return result;
        }
        
        if (lowerAsset.includes('silver')) {
            const result = this.validateFlags(['xag', 'usd']);
            return result;
        }
        return [];
    }

    extractCurrencyFlags(assetName) {
        const currencyMatches = assetName.match(/([A-Z]{3})/g) || [];

        const excludeList = ['OTC', 'INC', 'LLC', 'LTD', 'PLC', 'COM'];
        let currencies = currencyMatches.filter(code => !excludeList.includes(code));

        if (currencies.length === 0) {
            return [];
        }

        if (currencies.includes('USD') && currencies[0] !== 'USD') {
            currencies = ['USD', ...currencies.filter(c => c !== 'USD')];
        }

        const finalCurrencies = currencies.slice(0, 2).map(c => c.toLowerCase());

        const result = this.validateFlags(finalCurrencies);
        return result;
    }

    validateFlags(flagCodes) {
        if (!this.availableFlags) {
            return flagCodes;
        }

        const result = [];

        for (const code of flagCodes) {
            const isAvailable = this.availableFlags.has(code);
            const isUsd = code === 'usd';

            if (isAvailable || isUsd) {
                result.push(code);
            } else {
                result.push(code);
            }
        }

        if (result.length === 0) {
            return ['usd', 'bdt'];
        }

        return result;
    }

    generateSingleFlagHtml(flagId, className = 'trade-history-flag') {
        return `<svg class="flag flag-${flagId} ${className}"><use xlink:href="./svg/flags.svg#flag-${flagId}"></use></svg>`;
    }

    generateFlagsHtml(flagCodes, className = 'trade-history-flag') {
        const htmlParts = flagCodes.map((flagCode, index) => {
            const flagExists = this.availableFlags && this.availableFlags.has(flagCode);

            if (!flagExists) {
                const placeholder = `<div class="flag flag-${flagCode} ${className} flag-placeholder" title="${flagCode.toUpperCase()}">${flagCode.toUpperCase()}</div>`;
                return placeholder;
            }

            const svg = `<svg class="flag flag-${flagCode} ${className}" width="14" height="14"><use xlink:href="./svg/flags.svg#flag-${flagCode}"></use></svg>`;
            return svg;
        });

        const finalHtml = htmlParts.join('');
        return finalHtml;
    }

    getDefaultFlags() {
        return this.generateFlagsHtml(['usd', 'bdt']);
    }

    // Get market type for asset
    getMarketType(assetName) {
        if (assetName.includes('(OTC)') || assetName.includes('OTC')) {
            return 'OTC';
        }
        return 'REAL';
    }

    // Update methods for different UI contexts
    async updateAssetSectionFlags(assetName) {
        const flagContainer = document.querySelector('.asset-header .flag-container');
        if (flagContainer) {
            const flagsHtml = await this.generateTradeFlags(assetName);
            const cleanFlagsHtml = flagsHtml.replace(/trade-history-flag/g, '');
            flagContainer.innerHTML = cleanFlagsHtml;
        }
    }

    async updateAssetCardFlags() {
        // Wait for SVG to load
        if (!this.isReady) {
            await this.readyPromise;
        }

        // Target existing asset cards and add flag containers if needed
        const assetCards = document.querySelectorAll('.asset-card-tab');
        for (const assetCard of assetCards) {
            const assetName = assetCard.dataset.asset ||
                assetCard.querySelector('.asset-card-label')?.textContent;
            if (assetName) {
                // Find or create flag container
                let flagContainer = assetCard.querySelector('.asset-card-flags');
                if (!flagContainer) {
                    flagContainer = document.createElement('div');
                    flagContainer.className = 'asset-card-flags';

                    // Insert at the beginning of asset-card-container
                    const assetContainer = assetCard.querySelector('.asset-card-container');
                    if (assetContainer) {
                        assetContainer.insertBefore(flagContainer, assetContainer.firstChild);
                    }
                }

                const flagsHtml = await this.generateTradeFlags(assetName, 'asset-card-flag');
                flagContainer.innerHTML = flagsHtml;
            }
        }
    }

    updateTradeClosedAlertFlags(assetName) {
        return this.generateTradeFlags(assetName).replace(/trade-history-flag/g, '');
    }

    // Clear cache when needed
    clearCache() {
        this.flagCache.clear();
    }

    // Add new asset mapping dynamically
    addAssetMapping(assetName, flagCodes) {
        this.assetMapping[assetName] = flagCodes;
        this.flagCache.delete(assetName); // Clear cache for this asset
    }

    debugAssetFlags(assetName) {
        return this.generateTradeFlags(assetName);
    }
}

// Create global instance and ensure it's ready
window.flagDetectionAlgorithm = new FlagDetectionAlgorithm();

// Clear any existing cache to ensure new mappings take effect
if (window.flagDetectionAlgorithm) {
    window.flagDetectionAlgorithm.clearCache();
}

// Single initialization point - controlled by app.js
// DO NOT auto-initialize here to avoid race conditions

// MutationObserver for dynamically added asset cards
if (typeof MutationObserver !== 'undefined') {
    const observer = new MutationObserver((mutations) => {
        let shouldUpdate = false;
        mutations.forEach((mutation) => {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach((node) => {
                    if (node.nodeType === 1 && (node.classList?.contains('asset-card-tab') || node.querySelector?.('.asset-card-tab'))) {
                        shouldUpdate = true;
                    }
                });
            }
        });

        if (shouldUpdate && window.flagDetectionAlgorithm?.isReady) {
            window.flagDetectionAlgorithm.updateAssetCardFlags();
        }
    });

    // Start observing after DOM is ready
    document.addEventListener('DOMContentLoaded', () => {
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}

window.debugFlags = function (assetName) {
    if (window.flagDetectionAlgorithm) {
        return window.flagDetectionAlgorithm.debugAssetFlags(assetName);
    }
};

// Export for module usage
if (typeof module !== 'undefined' && module.exports) {
    module.exports = FlagDetectionAlgorithm;
}