package com.dspread.pos.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

import androidx.databinding.ObservableField;

import com.dspread.pos.data.local.PreferencesManager;
import com.dspread.pos_android_app.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PosParameters {
    private static final String TAG = "PosParams";

    // Preference keys
    private static final String PREF_MAIN_LOGO = "main_logo";
    private static final String PREF_FOOTER_LOGO = "footer_logo";
    private static final String PREF_FOOTER_LOGO_VISIBILITY = "footer_logo_visibility";
    private static final String PREF_FOOTER_GREETING_TEXT = "footer_greeting_text";
    private static final String PREF_FOOTER_TEXT = "footer_text";
    private static final String PREF_PRIMARY_COLOR = "primary_color";
    private static final String PREF_RAW_JSON = "raw_json";
    private static final String PREF_NAV_ITEMS = "nav_items";

    // Navigation constants
    public static final int NAV_HOME = R.id.nav_home;
    public static final int NAV_SCAN = R.id.nav_scan;
    public static final int NAV_PRINTER = R.id.nav_printer;
    public static final int NAV_SETTINGS = R.id.nav_setting;

    // Default values
    private static final int DEFAULT_MAIN_LOGO = R.drawable.am_mulberry_logo_wide_color;
    private static final int DEFAULT_FOOTER_LOGO = R.drawable.am_mulberry_logo_wide_color;
    private static final boolean DEFAULT_FOOTER_LOGO_VISIBILITY = true;
    private static final String DEFAULT_FOOTER_GREETING_TEXT = "Hello";
    private static final String DEFAULT_FOOTER_TEXT = "Mulberry ©2025 www.mulberrypos.com";
    private static final String DEFAULT_PRIMARY_COLOR = "#3d3d3d";

    // Observable fields
    public static final ObservableField<Integer> mainLogo = new ObservableField<>(DEFAULT_MAIN_LOGO);
    public static final ObservableField<Integer> footerLogo = new ObservableField<>(DEFAULT_FOOTER_LOGO);
    public static final ObservableField<Boolean> footerLogoVisibility = new ObservableField<>(DEFAULT_FOOTER_LOGO_VISIBILITY);
    public static final ObservableField<Boolean> footerTextVisibility = new ObservableField<>(false);
    public static final ObservableField<String> footerGreetingText = new ObservableField<>(DEFAULT_FOOTER_GREETING_TEXT);
    public static final ObservableField<String> footerText = new ObservableField<>(DEFAULT_FOOTER_TEXT);
    public static final ObservableField<String> primaryColor = new ObservableField<>(DEFAULT_PRIMARY_COLOR);

    // Navigation items storage
    public static final Map<Integer, List<NavItem>> NAV_ITEMS = new HashMap<>();

    // Static mappings
    private static final Map<String, Integer> NAV_PAGE_MAP = createNavPageMap();
    private static final Map<String, Integer> ICON_RES_MAP = createIconResourceMap();

    public static class NavItem {
        public final int navPage;
        public String name;
        public Object iconSource; // Can be Integer(resId) or String(filePath)
        public int position;
        public boolean enabled;

        public NavItem(int navPage, String name, Object iconSource, int position, boolean enabled) {
            this.navPage = navPage;
            this.name = name;
            this.iconSource = iconSource;
            this.position = position;
            this.enabled = enabled;
            Log.d(TAG, "Created NavItem: \n"
                    + "   | name: " + name + " \n"
                    + "   | iconSource: " + iconSource + " \n"
                    + "   | navPage: " + navPage + " \n"
                    + "   | position: " + position + " \n"
                    + "   | enabled: " + enabled
            );
        }
    }

    /* Initialization */
    public static void initialize(Context context) {
        Log.d(TAG, "Initializing PosParameters");
        PreferencesManager prefs = PreferencesManager.getInstance(context);
        initializeNavItems();

        if (prefs.hasConfiguration()) {

        } else {
            Log.d(TAG, "Loading default values");

        }
    }

    private static void initializeNavItems() {
        NAV_ITEMS.clear();
        NAV_ITEMS.put(NAV_HOME, new ArrayList<>());
        NAV_ITEMS.put(NAV_SCAN, new ArrayList<>());
        NAV_ITEMS.put(NAV_PRINTER, new ArrayList<>());
        NAV_ITEMS.put(NAV_SETTINGS, new ArrayList<>());
        Log.d(TAG, "Initialized empty NAV_ITEMS");
    }

    /* JSON Processing */
    public static void updateFromJson(String json, Context context) {
        Log.d(TAG, "Processing JSON update");
        try {
            JSONObject config = new JSONObject(json);
            PreferencesManager prefs = PreferencesManager.getInstance(context);
            prefs.saveString(PREF_RAW_JSON, json);

            String type = config.optString("type", "");
            switch (type) {
                case "configuration":
                    Log.d(TAG, "Processing configuration update");
                    updateConfiguration(config, context, prefs);
                    break;
                case "payment":
                    Log.d(TAG, "Processing payment update");
                    updatePaymentResults(config, prefs);
                    break;
                default:
                    Log.w(TAG, "Unknown JSON type: " + type);
            }
        } catch (JSONException | IOException e) {
            Log.e(TAG, "Error parsing JSON", e);
        }
    }

    private static void updateConfiguration(JSONObject config, Context context, PreferencesManager prefs)
            throws JSONException, IOException {
        if (config.has("navItems")) {
            Log.d(TAG, "Updating navigation items");
            updateNavigationItems(config.getJSONArray("navItems"), context, prefs);
        }

        Log.d(TAG, "Updating main config");
        updateMainConfig(config, context, prefs);

        Log.d(TAG, "Saving config to prefs");
        saveCurrentConfigToPrefs(prefs);
    }

    private static void updateNavigationItems(JSONArray navItemsArray, Context context, PreferencesManager prefs)
            throws JSONException, IOException {
        initializeNavItems();
        Log.d(TAG, "Processing " + navItemsArray.length() + " nav items");

        for (int i = 0; i < navItemsArray.length(); i++) {
            JSONObject itemJson = navItemsArray.getJSONObject(i);
            String navPageStr = itemJson.getString("navPage");
            Integer navPage = NAV_PAGE_MAP.get(navPageStr);

            if (navPage != null) {
                JSONObject iconConfig = itemJson.getJSONObject("icon");
                Object iconSource = processIcon(iconConfig, context);

                NavItem item = new NavItem(
                        navPage,
                        itemJson.optString("navName"),
                        iconSource,
                        itemJson.optInt("position", 0),
                        itemJson.optBoolean("enabled", true)
                );

                NAV_ITEMS.get(navPage).add(item);
                Log.d(TAG, "Added nav item: " + item.name);
            }
        }
        saveNavItemsToPrefs(prefs);
    }

    private static Object processIcon(JSONObject iconConfig, Context context) throws JSONException, IOException {
        String type = iconConfig.getString("type");
        String value = iconConfig.getString("value");
        Log.d(TAG, "Processing icon type: " + type);

        switch (type) {
            case "resource":
                Integer resId = ICON_RES_MAP.get(value);
                if (resId != null) {
                    Log.d(TAG, "Using resource ID: " + resId);
                    return resId;
                }
                break;

            case "base64":
                Log.d(TAG, "Decoding Base64 image");
                Bitmap bitmap = ImageUtils.decodeFromBase64(value);
                if (bitmap != null) {
                    String filename = "icon_" + System.currentTimeMillis() + ".png";
                    String path = ImageUtils.saveBitmapToFile(context, bitmap, filename);
                    Log.d(TAG, "Saved image to: " + path);
                    return path;
                }
                break;
        }

        Log.w(TAG, "Falling back to default icon");
        return R.drawable.am_mulberry_logo_wide_color;
    }

    private static void updateMainConfig(JSONObject config, Context context, PreferencesManager prefs) throws JSONException, IOException {
        // Logos
        // Main Logo
        if (config.has("mainLogo")) {
            JSONObject logoConfig = config.getJSONObject("mainLogo");
            Object logoSource = processIcon(logoConfig, context);

            if (logoSource instanceof Integer) {
                mainLogo.set((Integer) logoSource);
                prefs.saveInt("main_logo", (Integer) logoSource);
                prefs.remove("main_logo_path"); // Clear old path if exists
            } else if (logoSource instanceof String) {
                mainLogo.set(-1);
                prefs.saveInt("main_logo", -1);
                prefs.saveString("main_logo_path", (String) logoSource);
            }
        }

        // Footer Logo (same pattern)
        if (config.has("footerLogo")) {
            JSONObject logoConfig = config.getJSONObject("footerLogo");
            Object logoSource = processIcon(logoConfig, context);

            if (logoSource instanceof Integer) {
                footerLogo.set((Integer) logoSource);
                prefs.saveInt("footer_logo", (Integer) logoSource);
                prefs.remove("footer_logo_path");
            } else if (logoSource instanceof String) {
                footerLogo.set(-1);
                prefs.saveInt("footer_logo", -1);
                prefs.saveString("footer_logo_path", (String) logoSource);
            }
        }

        // Visibility
        boolean logoVisible = config.optBoolean("footerLogoVisibility", DEFAULT_FOOTER_LOGO_VISIBILITY);
        footerLogoVisibility.set(logoVisible);
        footerTextVisibility.set(!logoVisible);

        // Texts
        footerGreetingText.set(config.optString("footerGreetingText", DEFAULT_FOOTER_GREETING_TEXT));
        footerText.set(config.optString("footerText", DEFAULT_FOOTER_TEXT));
        primaryColor.set(config.optString("primaryColor", DEFAULT_PRIMARY_COLOR));

        Log.d(TAG, "Main config updated");
    }

    /* Helper Methods */
    private static Map<String, Integer> createNavPageMap() {
        Map<String, Integer> map = new HashMap<>();
        map.put("NAV_HOME", NAV_HOME);
        map.put("NAV_SCAN", NAV_SCAN);
        map.put("NAV_PRINTER", NAV_PRINTER);
        map.put("NAV_SETTINGS", NAV_SETTINGS);
        return map;
    }

    private static Map<String, Integer> createIconResourceMap() {
        Map<String, Integer> map = new HashMap<>();
        map.put("home", R.drawable.am_card_pay_black);
        map.put("scan", R.drawable.am_barcode_black);
        map.put("printer", R.drawable.am_receipt_cart_black);
        map.put("settings", R.drawable.am_settings_black);
        map.put("mulberry", R.drawable.am_mulberry_logo_wide_color);
        map.put("overtec", R.drawable.am_overtec_logo_wide_color);
        map.put("datexpay", R.drawable.am_datexpay_logo_wide_color);
        map.put("citibank", R.drawable.am_bank_citibank_wide_color);
        map.put("nbubank", R.drawable.am_bank_nbubank_wide_color);
        return map;
    }

    private static void saveCurrentConfigToPrefs(PreferencesManager prefs) {
        prefs.saveInt(PREF_MAIN_LOGO, mainLogo.get());
        prefs.saveInt(PREF_FOOTER_LOGO, footerLogo.get());
        prefs.saveString(PREF_FOOTER_GREETING_TEXT, footerGreetingText.get());
        prefs.saveString(PREF_FOOTER_TEXT, footerText.get());
        prefs.saveString(PREF_PRIMARY_COLOR, primaryColor.get());
        prefs.saveBoolean(PREF_FOOTER_LOGO_VISIBILITY, footerLogoVisibility.get());
        // Debug log for each config value being saved
        Log.d(TAG, "Saved current config to prefs: \n"
                + "   * footerGreetingText: " + footerGreetingText.get() + " \n"
                + "   * footerText: " + footerText.get() + " \n"
                + "   * primaryColor: " + primaryColor.get() + " \n"
                + "   * footerLogoVisibility: " + footerLogoVisibility.get()
        );
    }

    private static void saveNavItemsToPrefs(PreferencesManager prefs) {
        JSONArray navItemsArray = new JSONArray();
        for (Map.Entry<Integer, List<NavItem>> entry : NAV_ITEMS.entrySet()) {
            for (NavItem item : entry.getValue()) {
                try {
                    JSONObject itemJson = new JSONObject();
                    itemJson.put("navPage", getNavPageName(entry.getKey()));
                    itemJson.put("navName", item.name);

                    // Handle icon source
                    if (item.iconSource instanceof Integer) {
                        itemJson.put("icon", item.iconSource.toString());
                    } else if (item.iconSource instanceof String) {
                        itemJson.put("icon", item.iconSource);
                    }

                    itemJson.put("position", item.position);
                    itemJson.put("enabled", item.enabled);
                    navItemsArray.put(itemJson);

                    // Debug log for each item being saved
                    Log.d(TAG, "Saving NavItem: \n"
                            + "   * navPage: " + getNavPageName(entry.getKey()) + " \n"
                            + "   * navName: " + item.name + " \n"
                            + "   * icon: " + item.iconSource + " \n"
                            + "   * position: " + item.position + " \n"
                            + "   * enabled: " + item.enabled
                    );
                } catch (JSONException e) {
                    Log.e(TAG, "Error saving nav item", e);
                }
            }
        }
//        prefs.remove(PREF_NAV_ITEMS);
        prefs.saveString(PREF_NAV_ITEMS, navItemsArray.toString());
        Log.d(TAG, "Saved nav items to prefs: " + navItemsArray.toString());
    }

    public static String getNavPageName(int navPage) {
        for (Map.Entry<String, Integer> entry : NAV_PAGE_MAP.entrySet()) {
            if (entry.getValue() == navPage) {
                return entry.getKey();
            }
        }
        return "";
    }

    private static void updatePaymentResults(JSONObject config, PreferencesManager prefs) {
        // Implementation for payment results
    }

    private static void loadDefaultValues() {
        mainLogo.set(DEFAULT_MAIN_LOGO);
        footerLogo.set(DEFAULT_FOOTER_LOGO);
        footerLogoVisibility.set(DEFAULT_FOOTER_LOGO_VISIBILITY);
        footerTextVisibility.set(!DEFAULT_FOOTER_LOGO_VISIBILITY);
        footerGreetingText.set(DEFAULT_FOOTER_GREETING_TEXT);
        footerText.set(DEFAULT_FOOTER_TEXT);
        primaryColor.set(DEFAULT_PRIMARY_COLOR);
        Log.d(TAG, "Loaded default values");
    }
}