import appConfig from '@/config'

const PROXY_BASE = `${appConfig.baseUrl}${appConfig.urlPrefix}/crypto/proxy`

export type CoinMeta = { name: string; icon: string; color: string }

const DEFAULT_COIN_CONFIG: Record<string, CoinMeta> = {
    BTC: { name: 'Bitcoin', icon: '₿', color: '#f7931a' },
    ETH: { name: 'Ethereum', icon: 'Ξ', color: '#627eea' },
    BNB: { name: 'BNB', icon: 'B', color: '#f3ba2f' },
    SOL: { name: 'Solana', icon: '◎', color: '#9945ff' },
    XRP: { name: 'Ripple', icon: 'X', color: '#00aae4' },
    ADA: { name: 'Cardano', icon: 'A', color: '#0d3349' },
    DOGE: { name: 'Dogecoin', icon: 'Ð', color: '#c2a633' },
    TRX: { name: 'TRON', icon: 'T', color: '#eb0029' },
    AVAX: { name: 'Avalanche', icon: 'A', color: '#e84142' },
    LINK: { name: 'Chainlink', icon: '⬡', color: '#2a5ada' },
    TON: { name: 'Toncoin', icon: 'T', color: '#0088cc' },
    SHIB: { name: 'Shiba Inu', icon: 'S', color: '#ffa409' },
    DOT: { name: 'Polkadot', icon: '●', color: '#e6007a' },
    SUI: { name: 'Sui', icon: 'S', color: '#6fbcf0' },
    NEAR: { name: 'NEAR', icon: 'N', color: '#00ec97' },
    LTC: { name: 'Litecoin', icon: 'Ł', color: '#bfbbbb' },
    APT: { name: 'Aptos', icon: 'A', color: '#4cd9c0' },
    UNI: { name: 'Uniswap', icon: 'U', color: '#ff007a' },
    PEPE: { name: 'Pepe', icon: 'P', color: '#479f53' },
    ICP: { name: 'Internet Computer', icon: 'I', color: '#29abe2' },
    FET: { name: 'Fetch.ai', icon: 'F', color: '#1b1464' },
    RENDER: { name: 'Render', icon: 'R', color: '#00e1ff' },
    ETC: { name: 'Ethereum Classic', icon: 'E', color: '#328332' },
    ATOM: { name: 'Cosmos', icon: 'A', color: '#2e3148' },
    FIL: { name: 'Filecoin', icon: 'F', color: '#0090ff' },
    ARB: { name: 'Arbitrum', icon: 'A', color: '#28a0f0' },
    OP: { name: 'Optimism', icon: 'O', color: '#ff0420' },
    IMX: { name: 'Immutable', icon: 'I', color: '#00b2ff' },
    INJ: { name: 'Injective', icon: 'I', color: '#00f2fe' },
    SEI: { name: 'Sei', icon: 'S', color: '#9b1c1c' },
    WLD: { name: 'Worldcoin', icon: 'W', color: '#000000' },
    TIA: { name: 'Celestia', icon: 'T', color: '#7b2bf9' },
    STX: { name: 'Stacks', icon: 'S', color: '#5546ff' },
    GRT: { name: 'The Graph', icon: 'G', color: '#6747ed' },
    AAVE: { name: 'Aave', icon: 'A', color: '#b6509e' },
    MKR: { name: 'Maker', icon: 'M', color: '#1aab9b' },
    ALGO: { name: 'Algorand', icon: 'A', color: '#000000' },
    SAND: { name: 'Sandbox', icon: 'S', color: '#04adef' },
    MANA: { name: 'Decentraland', icon: 'M', color: '#ff2d55' },
    AXS: { name: 'Axie Infinity', icon: 'A', color: '#0055d5' },
    THETA: { name: 'Theta', icon: 'θ', color: '#2ab8e6' },
    FTM: { name: 'Fantom', icon: 'F', color: '#1969ff' },
    VET: { name: 'VeChain', icon: 'V', color: '#15bdff' },
    EGLD: { name: 'MultiversX', icon: 'E', color: '#23f7dd' },
    FLOW: { name: 'Flow', icon: 'F', color: '#00ef8b' },
    XTZ: { name: 'Tezos', icon: 'T', color: '#2c7df7' },
    EOS: { name: 'EOS', icon: 'E', color: '#000000' },
    IOTA: { name: 'IOTA', icon: 'I', color: '#131f37' },
    NEO: { name: 'Neo', icon: 'N', color: '#00e599' },
    KAVA: { name: 'Kava', icon: 'K', color: '#ff564f' },
    CFX: { name: 'Conflux', icon: 'C', color: '#1a1a2e' },
    CAKE: { name: 'PancakeSwap', icon: 'C', color: '#d1884f' },
    CRV: { name: 'Curve', icon: 'C', color: '#f9d200' },
    SNX: { name: 'Synthetix', icon: 'S', color: '#00d1ff' },
    LDO: { name: 'Lido DAO', icon: 'L', color: '#00a3ff' },
    COMP: { name: 'Compound', icon: 'C', color: '#00d395' },
    ZIL: { name: 'Zilliqa', icon: 'Z', color: '#49c1bf' },
    ENJ: { name: 'Enjin Coin', icon: 'E', color: '#7866d5' },
    DYDX: { name: 'dYdX', icon: 'D', color: '#6966ff' },
    CHZ: { name: 'Chiliz', icon: 'C', color: '#cd0124' },
    GALA: { name: 'Gala', icon: 'G', color: '#000000' },
    APE: { name: 'ApeCoin', icon: 'A', color: '#0054f7' },
    GMT: { name: 'GMT', icon: 'G', color: '#e8d24a' },
    MASK: { name: 'Mask Network', icon: 'M', color: '#1c68f3' },
    ROSE: { name: 'Oasis', icon: 'R', color: '#0092f6' },
    ZEC: { name: 'Zcash', icon: 'Z', color: '#ecb244' },
    MINA: { name: 'Mina', icon: 'M', color: '#e39844' },
    CELO: { name: 'Celo', icon: 'C', color: '#35d07f' },
    ENS: { name: 'ENS', icon: 'E', color: '#5298ff' },
    BAT: { name: 'Basic Attention', icon: 'B', color: '#ff5000' },
    YFI: { name: 'yearn.finance', icon: 'Y', color: '#006ae3' },
    SUSHI: { name: 'SushiSwap', icon: 'S', color: '#d65aff' },
    BAL: { name: 'Balancer', icon: 'B', color: '#1e1e1e' },
    ANKR: { name: 'Ankr', icon: 'A', color: '#2e6bf6' },
    JASMY: { name: 'JasmyCoin', icon: 'J', color: '#f7931a' },
    RSR: { name: 'Reserve Rights', icon: 'R', color: '#000000' },
    LRC: { name: 'Loopring', icon: 'L', color: '#2ab6f6' },
    STORJ: { name: 'Storj', icon: 'S', color: '#2683ff' },
    ICX: { name: 'ICON', icon: 'I', color: '#1fc5c9' },
    SKL: { name: 'SKALE', icon: 'S', color: '#000000' },
    HBAR: { name: 'Hedera', icon: 'H', color: '#000000' },
    XLM: { name: 'Stellar', icon: 'X', color: '#000000' },
    BCH: { name: 'Bitcoin Cash', icon: 'B', color: '#8dc351' },
    MATIC: { name: 'Polygon', icon: 'M', color: '#8247e5' },
    TAO: { name: 'Bittensor', icon: 'T', color: '#000000' },
    JUP: { name: 'Jupiter', icon: 'J', color: '#00bfa5' },
    WIF: { name: 'dogwifhat', icon: 'W', color: '#a0522d' },
    BONK: { name: 'Bonk', icon: 'B', color: '#f9a825' },
    FLOKI: { name: 'Floki', icon: 'F', color: '#d4a843' },
    NOT: { name: 'Notcoin', icon: 'N', color: '#000000' },
    ORDI: { name: 'ORDI', icon: 'O', color: '#f7931a' },
    PENDLE: { name: 'Pendle', icon: 'P', color: '#0052ff' },
    '1000SATS': { name: '1000SATS', icon: 'S', color: '#f7931a' },
    WOO: { name: 'WOO', icon: 'W', color: '#2b2b3d' },
    BLUR: { name: 'Blur', icon: 'B', color: '#ff6b00' },
    PIXEL: { name: 'Pixels', icon: 'P', color: '#7b61ff' },
    STRK: { name: 'Starknet', icon: 'S', color: '#0c0c4f' },
    ACE: { name: 'Fusionist', icon: 'A', color: '#6c5ce7' },
    AI: { name: 'Sleepless AI', icon: 'A', color: '#00d2ff' },
    XAI: { name: 'Xai', icon: 'X', color: '#f44336' },
    MANTA: { name: 'Manta', icon: 'M', color: '#1e88e5' },
    ALT: { name: 'AltLayer', icon: 'A', color: '#000000' },
    PYTH: { name: 'Pyth Network', icon: 'P', color: '#6b4ce6' },
    JTO: { name: 'Jito', icon: 'J', color: '#59c995' },
    NTRN: { name: 'Neutron', icon: 'N', color: '#000000' },
    ONDO: { name: 'Ondo', icon: 'O', color: '#1a73e8' }
}

let activeCoinConfig: Record<string, CoinMeta> = { ...DEFAULT_COIN_CONFIG }

export function getCoinConfig() {
    return activeCoinConfig
}

export function loadCoinConfig(): Promise<void> {
    return new Promise((resolve) => {
        uni.request({
            url: `${import.meta.env.VITE_API_BASE_URL || ''}/api/crypto/coin-config`,
            method: 'GET',
            success: (res) => {
                if (res.statusCode === 200 && res.data) {
                    const data = res.data as any
                    const list = data?.data || data
                    if (list && typeof list === 'object' && !Array.isArray(list)) {
                        activeCoinConfig = list as Record<string, CoinMeta>
                    } else if (Array.isArray(list)) {
                        const map: Record<string, CoinMeta> = {}
                        list.forEach((item: any) => {
                            if (item.symbol) {
                                map[item.symbol] = {
                                    name: item.name || item.symbol,
                                    icon: item.icon || item.symbol.charAt(0),
                                    color: item.color || '#666666'
                                }
                            }
                        })
                        if (Object.keys(map).length > 0) activeCoinConfig = map
                    }
                }
                resolve()
            },
            fail: () => resolve()
        })
    })
}

export interface CoinTicker {
    symbol: string
    name: string
    icon: string
    color: string
    price: string
    priceRaw: number
    change: number
    volume: string
    mcap: string
    highPrice: string
    lowPrice: string
}

export function formatPrice(price: string | number): string {
    const p = typeof price === 'string' ? parseFloat(price) : price
    if (isNaN(p)) return '0.00'
    if (p >= 10000) return p.toLocaleString('en-US', { maximumFractionDigits: 0 })
    if (p >= 100) return p.toLocaleString('en-US', { maximumFractionDigits: 1 })
    if (p >= 1) return p.toLocaleString('en-US', { maximumFractionDigits: 2 })
    if (p >= 0.01) return p.toFixed(4)
    return p.toFixed(6)
}

export function formatVolume(vol: string | number): string {
    const v = typeof vol === 'string' ? parseFloat(vol) : vol
    if (isNaN(v)) return '$0'
    if (v >= 1e12) return '$' + (v / 1e12).toFixed(2) + 'T'
    if (v >= 1e9) return '$' + (v / 1e9).toFixed(1) + 'B'
    if (v >= 1e6) return '$' + (v / 1e6).toFixed(1) + 'M'
    if (v >= 1e3) return '$' + (v / 1e3).toFixed(1) + 'K'
    return '$' + v.toFixed(0)
}

export function parseBinanceTicker(ticker: any): CoinTicker | null {
    const rawSymbol = ticker.symbol.replace('USDT', '')
    const config = activeCoinConfig[rawSymbol]
    if (!config) return null
    return {
        symbol: rawSymbol,
        name: config.name,
        icon: config.icon,
        color: config.color,
        price: formatPrice(ticker.lastPrice),
        priceRaw: parseFloat(ticker.lastPrice),
        change: parseFloat(parseFloat(ticker.priceChangePercent).toFixed(2)),
        volume: formatVolume(ticker.quoteVolume),
        mcap: formatVolume(ticker.quoteVolume),
        highPrice: formatPrice(ticker.highPrice),
        lowPrice: formatPrice(ticker.lowPrice)
    }
}

export interface KlinePoint {
    time: number
    open: number
    high: number
    low: number
    close: number
    volume: number
}

export function getBinanceKline(
    symbol: string,
    interval = '1h',
    limit = 24
): Promise<KlinePoint[]> {
    return binanceRequest(
        `/api/v3/klines?symbol=${symbol}USDT&interval=${interval}&limit=${limit}`,
        (data) => {
            if (!Array.isArray(data)) throw new Error('Kline API error')
            return (data as any[]).map((k) => ({
                time: k[0],
                open: parseFloat(k[1]),
                high: parseFloat(k[2]),
                low: parseFloat(k[3]),
                close: parseFloat(k[4]),
                volume: parseFloat(k[5])
            }))
        }
    )
}

export function getBinanceSingleTicker(symbol: string): Promise<CoinTicker | null> {
    return binanceRequest(`/api/v3/ticker/24hr?symbol=${symbol}USDT`, (data) =>
        parseBinanceTicker(data)
    )
}

export function getBinanceTickers(): Promise<CoinTicker[]> {
    const watchSymbols = Object.keys(activeCoinConfig)
    const symbols = watchSymbols.map((s) => `"${s}USDT"`)
    return binanceRequest(`/api/v3/ticker/24hr?symbols=[${symbols.join(',')}]`, (data) => {
        if (!Array.isArray(data)) throw new Error('Binance API error')
        const parsed = (data as any[]).map(parseBinanceTicker).filter(Boolean) as CoinTicker[]
        const order = Object.keys(activeCoinConfig)
        parsed.sort((a, b) => order.indexOf(a.symbol) - order.indexOf(b.symbol))
        return parsed
    })
}

function binanceRequest<T>(apiPath: string, transform: (data: any) => T): Promise<T> {
    const idx = apiPath.indexOf('?')
    const path = idx >= 0 ? apiPath.substring(0, idx) : apiPath
    const query = idx >= 0 ? apiPath.substring(idx + 1) : ''
    const proxyUrl = `${PROXY_BASE}?path=${path}${query ? '&' + query : ''}`

    console.log('[CryptoProxy] request =>', proxyUrl)
    return new Promise((resolve, reject) => {
        uni.request({
            url: proxyUrl,
            method: 'GET',
            success: (res) => {
                console.log('[CryptoProxy] response status =>', res.statusCode)
                if (res.statusCode === 200 && res.data) {
                    try {
                        resolve(transform(res.data))
                    } catch (e) {
                        console.error('[CryptoProxy] transform error =>', e)
                        reject(e)
                    }
                } else {
                    console.error('[CryptoProxy] error status =>', res.statusCode, res.data)
                    reject(new Error('Proxy API error: ' + res.statusCode))
                }
            },
            fail: (err) => {
                console.error('[CryptoProxy] request fail =>', err)
                reject(err)
            }
        })
    })
}
