import { action, observable, runInAction } from 'mobx';
import ReactNativeBlobUtil from 'react-native-blob-util';
import BigNumber from 'bignumber.js';

import SettingsStore from './SettingsStore';
import {
    SATS_PER_BTC,
    numberWithCommas,
    numberWithDecimals
} from '../utils/UnitsUtils';

interface CurrencyDisplayRules {
    symbol: string;
    space: boolean;
    rtl: boolean;
    separatorSwap: boolean;
    decimalPlaces?: number;
}
export default class FiatStore {
    @observable public fiatRates:
        | {
              name?: string;
              cryptoCode: string;
              currencyPair: string;
              code: string;
              rate: number;
          }[]
        | undefined;
    @observable public loading = false;
    @observable public error = false;

    private sourceOfCurrentFiatRates: string | undefined;

    getFiatRatesToken: any;

    settingsStore: SettingsStore;

    constructor(settingsStore: SettingsStore) {
        this.settingsStore = settingsStore;
        this.getFiatRates();
    }

    // Resource below may be helpful for formatting
    // https://fastspring.com/blog/how-to-format-30-currencies-from-countries-all-over-the-world/
    @observable public symbolLookup = (
        symbol: string
    ): CurrencyDisplayRules => {
        const symbolPairs: any = {
            AED: {
                symbol: 'د.إ',
                space: false,
                rtl: true,
                separatorSwap: false
            },
            ALL: {
                symbol: 'L',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            ANG: {
                symbol: 'f',
                space: false,
                rtl: false,
                separatorSwap: true
            },
            AOA: {
                symbol: 'Kz',
                space: true,
                rtl: false,
                separatorSwap: true
            },
            ARS: {
                symbol: '$',
                space: true,
                rtl: false,
                separatorSwap: true
            },
            AUD: {
                symbol: '$',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            BDT: {
                symbol: '৳',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            BGN: {
                symbol: 'лв',
                space: true,
                rtl: false,
                separatorSwap: true
            },
            BHD: {
                symbol: 'BD',
                space: true,
                rtl: false,
                separatorSwap: true,
                decimalPlaces: 3
            },
            BIF: {
                symbol: 'FBu',
                space: true,
                rtl: true,
                separatorSwap: true,
                decimalPlaces: 0
            },
            BMD: {
                symbol: 'BD$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            BOB: {
                symbol: 'Bs',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            BRL: {
                symbol: 'R$',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            BWP: {
                symbol: 'P',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            BZD: {
                symbol: 'BZ$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            CAD: { symbol: '$', space: true, rtl: false, separatorSwap: false },
            CDF: {
                symbol: 'FC',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            CHF: {
                symbol: 'fr.',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            CLP: {
                symbol: '$',
                space: true,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 0
            },
            CNY: { symbol: '¥', space: true, rtl: false, separatorSwap: false },
            COP: { symbol: '$', space: true, rtl: false, separatorSwap: false },
            CRC: {
                symbol: '₡',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            CUP: {
                symbol: '$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            CZK: {
                symbol: 'Kč',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            DJF: {
                symbol: 'Fdj',
                space: true,
                rtl: true,
                separatorSwap: true,
                decimalPlaces: 0
            },
            DKK: {
                symbol: 'kr.',
                space: true,
                rtl: false,
                separatorSwap: true
            },
            DOP: {
                symbol: 'RD$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            DZD: {
                symbol: 'دج',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            EGP: {
                symbol: '.ج.م',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            ETB: {
                symbol: 'Br',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            EUR: {
                symbol: '€',
                space: false,
                rtl: false,
                separatorSwap: true
            },
            GBP: {
                symbol: '£',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            GEL: {
                symbol: '₾',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            GHS: {
                symbol: 'GH₵',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            GNF: {
                symbol: 'FG',
                space: true,
                rtl: true,
                separatorSwap: true,
                decimalPlaces: 0
            },
            GTQ: {
                symbol: 'Q',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            HKD: {
                symbol: 'HK$',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            HNL: {
                symbol: 'L',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            HUF: {
                symbol: 'Ft',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            IDR: {
                symbol: 'Rp',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            ILS: { symbol: '₪', space: true, rtl: false, separatorSwap: false },
            INR: { symbol: '₹', space: true, rtl: false, separatorSwap: false },
            IRR: {
                symbol: '﷼',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            ISK: {
                symbol: 'kr',
                space: true,
                rtl: true,
                separatorSwap: true,
                decimalPlaces: 0
            },
            JMD: {
                symbol: '$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            JOD: {
                symbol: 'JD',
                space: false,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 3
            },
            JPY: {
                symbol: '¥',
                space: true,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 0
            },
            KES: {
                symbol: '/=',
                space: false,
                rtl: true,
                separatorSwap: false
            },
            KGS: {
                symbol: 'сом',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            KRW: {
                symbol: '₩',
                space: true,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 0
            },
            // KWD: { symbol: 'د.ك', space: true, rtl: true, separatorSwap: false, decimalPlaces: 3 },
            KZT: {
                symbol: '₸',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            LBP: {
                symbol: 'LL',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            LKR: {
                symbol: 'Rs',
                space: false,
                rtl: true,
                separatorSwap: false
            },
            LSL: {
                symbol: 'L',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            MAD: {
                symbol: 'DH',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            MGA: {
                symbol: 'Ar',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            MRU: {
                symbol: 'UM',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            MWK: {
                symbol: 'MK',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            MXN: { symbol: '$', space: true, rtl: false, separatorSwap: false },
            MYR: {
                symbol: 'RM',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            NAD: {
                symbol: 'N$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            NGN: {
                symbol: '₦',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            NIO: {
                symbol: 'C$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            NOK: {
                symbol: 'kr',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            NPR: {
                symbol: 'रु',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            NZD: { symbol: '$', space: true, rtl: false, separatorSwap: false },
            OMR: {
                symbol: '﷼',
                space: true,
                rtl: true,
                separatorSwap: false,
                decimalPlaces: 3
            },
            PAB: {
                symbol: 'B/',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            PEN: {
                symbol: 'S/',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            PHP: { symbol: '₱', space: true, rtl: false, separatorSwap: false },
            PKR: {
                symbol: 'Rs',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            PLN: { symbol: 'zł', space: true, rtl: true, separatorSwap: false },
            PYG: {
                symbol: '₲',
                space: false,
                rtl: false,
                separatorSwap: true,
                decimalPlaces: 0
            },
            QAR: {
                symbol: 'QR',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            RON: {
                symbol: 'lei',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            RSD: {
                symbol: 'дин',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            RUB: {
                symbol: 'p.',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            RWF: {
                symbol: 'FRw',
                space: true,
                rtl: true,
                separatorSwap: false,
                decimalPlaces: 0
            },
            SAR: { symbol: '﷼', space: true, rtl: true, separatorSwap: false },
            SEK: {
                symbol: 'kr',
                space: true,
                rtl: true,
                separatorSwap: true
            },
            SGD: {
                symbol: '$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            SZL: {
                symbol: 'E',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            THB: { symbol: '฿', space: true, rtl: true, separatorSwap: false },
            TND: {
                symbol: 'د.ت',
                space: false,
                rtl: true,
                separatorSwap: false,
                decimalPlaces: 3
            },
            TRY: { symbol: '₺', space: true, rtl: true, separatorSwap: false },
            TTD: {
                symbol: 'TT$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            TWD: {
                symbol: '元',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            TZS: {
                symbol: '/=',
                space: false,
                rtl: true,
                separatorSwap: false
            },
            UAH: { symbol: '₴', space: false, rtl: false, separatorSwap: true },
            UGX: {
                symbol: '/=',
                space: false,
                rtl: true,
                separatorSwap: false,
                decimalPlaces: 0
            },
            USD: {
                symbol: '$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            UYU: {
                symbol: 'U$',
                space: false,
                rtl: false,
                separatorSwap: false
            },
            UZS: {
                symbol: 'soʻm',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            VES: {
                symbol: 'Bs.',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            VND: {
                symbol: '₫',
                space: true,
                rtl: true,
                separatorSwap: true,
                decimalPlaces: 0
            },
            XAF: {
                symbol: 'F.CFA',
                space: true,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 0
            },
            XAG: {
                symbol: 'Ag oz',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            XAU: {
                symbol: 'Au oz',
                space: true,
                rtl: true,
                separatorSwap: false
            },
            XOF: {
                symbol: 'F.CFA',
                space: true,
                rtl: false,
                separatorSwap: false,
                decimalPlaces: 0
            },
            ZAR: {
                symbol: 'R',
                space: true,
                rtl: false,
                separatorSwap: false
            },
            ZMW: {
                symbol: 'K',
                space: false,
                rtl: false,
                separatorSwap: false
            }
        };

        if (symbol in symbolPairs) {
            return symbolPairs[symbol];
        } else {
            return {
                symbol: symbol || 'N/A',
                space: true,
                rtl: false,
                separatorSwap: false
            };
        }
    };

    public getSymbol = () => {
        const { settings } = this.settingsStore;
        const { fiat } = settings;
        if (fiat) {
            return this.symbolLookup(fiat);
        } else {
            return {
                symbol: fiat,
                space: true,
                rtl: true,
                separatorSwap: false,
                decimalPlaces: 2
            };
        }
    };

    public getRate = (sats: boolean = false) => {
        const { settings } = this.settingsStore;
        const { fiat } = settings;

        if (fiat && this.fiatRates) {
            const fiatEntry = this.fiatRates.filter(
                (entry) => entry.code === fiat
            )[0];
            const rate = (fiatEntry && fiatEntry.rate) || 0;
            const { symbol, space, rtl, separatorSwap } = this.symbolLookup(
                fiatEntry && fiatEntry.code
            );

            const moscowTime = new BigNumber(1)
                .div(rate)
                .multipliedBy(SATS_PER_BTC)
                .toFixed(0);

            const formattedRate = separatorSwap
                ? numberWithDecimals(rate)
                : numberWithCommas(rate);

            const formattedMoscow = separatorSwap
                ? numberWithDecimals(moscowTime)
                : numberWithCommas(moscowTime);

            if (sats) {
                return `${formattedMoscow} sats = 1 ${fiat}`;
            }

            if (rtl) {
                return `${formattedRate}${
                    space ? ' ' : ''
                }${symbol} BTC/${fiat}`;
            } else {
                return `${symbol}${
                    space ? ' ' : ''
                }${formattedRate} BTC/${fiat}`;
            }
        }
        return '$N/A';
    };

    // as of December 8, 2025
    // BTCPAY rates string:
    // BTC_USD,BTC_AUD,BTC_BRL,BTC_CAD,BTC_CHF,BTC_CLP,BTC_CNY,BTC_CZK,BTC_DKK,BTC_EUR,BTC_GBP,BTC_HKD,BTC_HUF,BTC_INR,BTC_ISK,BTC_JPY,BTC_KRW,BTC_NZD,BTC_PLN,BTC_RON,BTC_RUB,BTC_SEK,BTC_SGD,BTC_THB,BTC_TRY,BTC_TWD,BTC_ILS,BTC_ARS,BTC_NGN,BTC_LBP,BTC_MYR,BTC_UAH,BTC_JMD,BTC_COP,BTC_MXN,BTC_VES,BTC_TZS,BTC_QAR,BTC_TND,BTC_NOK,BTC_AED,BTC_TTD,BTC_PHP,BTC_CDF,BTC_XAF,BTC_KES,BTC_UGX,BTC_ZAR,BTC_CUP,BTC_DOP,BTC_BZD,BTC_BOB,BTC_CRC,BTC_GTQ,BTC_NIO,BTC_PYG,BTC_UYU,BTC_MRU,BTC_ALL,BTC_ANG,BTC_AOA,BTC_BDT,BTC_BGN,BTC_BHD,BTC_BIF,BTC_BMD,BTC_BWP,BTC_DJF,BTC_DZD,BTC_EGP,BTC_ETB,BTC_GEL,BTC_GHS,BTC_GNF,BTC_HNL,BTC_IRR,BTC_JOD,BTC_KGS,BTC_KZT,BTC_LKR,BTC_MAD,BTC_MGA,BTC_NAD,BTC_NPR,BTC_PAB,BTC_PEN,BTC_PKR,BTC_RSD,BTC_RWF,BTC_UZS,BTC_VND,BTC_XAG,BTC_XAU,BTC_ZMW,BTC_SAR,BTC_OMR,BTC_XOF,BTC_MWK,BTC_LSL,BTC_SZL
    @action
    public getFiatRates = async () => {
        // try not to slam endpoint
        if (this.loading) return;
        this.loading = true;

        try {
            const settings = await this.settingsStore.getSettings();

            if (
                this.fiatRates != null &&
                this.sourceOfCurrentFiatRates != settings.fiatRatesSource
            ) {
                // clear rates to display loading indicator after rates source switch
                this.fiatRates = undefined;
            }

            if (settings.fiatRatesSource.toLowerCase() === 'zeus') {
                this.fiatRates = await this.getFiatRatesFromZeus();
            } else if (settings.fiat != null) {
                const rate = await this.getSelectedFiatRateFromYadio(
                    settings.fiat
                );

                runInAction(() => {
                    if (this.fiatRates) {
                        this.fiatRates = this.fiatRates.filter(
                            (r) => r.code !== settings.fiat
                        );
                        if (rate != null) {
                            this.fiatRates = this.fiatRates.concat([rate]);
                        }
                    } else if (rate) {
                        this.fiatRates = [rate];
                    }
                });
            }

            this.sourceOfCurrentFiatRates = settings.fiatRatesSource;
        } finally {
            this.loading = false;
        }
    };

    public formatAmountForDisplay = (input: string | number) => {
        const { symbol, space, rtl, separatorSwap } = this.getSymbol();
        const amount = separatorSwap
            ? numberWithDecimals(input)
            : numberWithCommas(input);

        if (rtl) return `${amount}${space ? ' ' : ''}${symbol}`;
        return `${symbol}${space ? ' ' : ''}${amount}`;
    };

    private getSelectedFiatRateFromYadio = async (code: string) => {
        try {
            const response = await ReactNativeBlobUtil.fetch(
                'GET',
                `https://api.yadio.io/rate/${code}/BTC`
            );
            const status = response.info().status;
            if (status == 200) {
                return {
                    cryptoCode: 'BTC',
                    code,
                    rate: response.json().rate,
                    currencyPair: `BTC_${code}`
                };
            }
        } catch (error) {
            console.error('Error fetching fiat rates from yadio', error);
        }

        return undefined;
    };

    private getFiatRatesFromZeus = async () => {
        try {
            const response = await ReactNativeBlobUtil.fetch(
                'GET',
                'https://pay.zeusln.app/api/rates?storeId=Fjt7gLnGpg4UeBMFccLquy3GTTEz4cHU4PZMU63zqMBo'
            );
            const status = response.info().status;
            if (status == 200) {
                return response.json();
            }
        } catch (error) {
            console.error('Error fetching fiat rates from zeus', error);
        }

        return undefined;
    };
}
