package com.grigowashere.aismap.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

/**
 * Менеджер настроек приложения
 * Управляет сохранением и загрузкой настроек в SharedPreferences
 */
public class SettingsManager {
    
    private static final String TAG = "SettingsManager";
    private static final String PREFS_NAME = "AISMapSettings";
    
    // Ключи для настроек
    private static final String KEY_UDP_PORT = "udp_port";
    private static final String KEY_UDP_ENABLED = "udp_enabled";
    private static final String KEY_ANDROID_NMEA_ENABLED = "android_nmea_enabled";
    private static final String KEY_UDP_NMEA_ENABLED = "udp_nmea_enabled";
    private static final String KEY_DATA_MODE = "data_mode";
    private static final String KEY_DATA_STALE_WARNING_MINUTES = "data_stale_warning_minutes";
    private static final String KEY_DATA_STALE_REMOVE_MINUTES = "data_stale_remove_minutes";
    private static final String KEY_PATH_TRACKING_ENABLED = "path_tracking_enabled";
    private static final String KEY_PATH_COLOR = "path_color";
    private static final String KEY_PREDICTION_COLOR = "prediction_color";
    private static final String KEY_PATH_WIDTH = "path_width";
    private static final String KEY_PREDICTION_WIDTH = "prediction_width";
    private static final String KEY_VIBRATION_ENABLED = "vibration_enabled";
    private static final String KEY_SOUND_ENABLED = "sound_enabled";
    
    // Значения по умолчанию
    private static final int DEFAULT_UDP_PORT = 10110;
    private static final boolean DEFAULT_UDP_ENABLED = true;
    private static final boolean DEFAULT_ANDROID_NMEA_ENABLED = true;
    private static final boolean DEFAULT_UDP_NMEA_ENABLED = true;
    private static final String DEFAULT_DATA_MODE = "hybrid";
    private static final int DEFAULT_DATA_STALE_WARNING_MINUTES = 5; // Показывать losingtarget.xml
    private static final int DEFAULT_DATA_STALE_REMOVE_MINUTES = 7; // Удалять из списка
    private static final boolean DEFAULT_PATH_TRACKING_ENABLED = true;
    private static final int DEFAULT_PATH_COLOR = 0xFF00FFFF; // Голубой
    private static final int DEFAULT_PREDICTION_COLOR = 0xFFFFFF00; // Желтый
    private static final float DEFAULT_PATH_WIDTH = 3.0f;
    private static final float DEFAULT_PREDICTION_WIDTH = 2.0f;
    private static final boolean DEFAULT_VIBRATION_ENABLED = true;
    private static final boolean DEFAULT_SOUND_ENABLED = true;
    
    // Режимы работы с данными
    public static final String DATA_MODE_HYBRID = "hybrid";
    public static final String DATA_MODE_NMEA_ONLY = "nmea_only";
    public static final String DATA_MODE_ANDROID_ONLY = "android_only";
    
    private Context context;
    private SharedPreferences prefs;
    
    public SettingsManager(Context context) {
        this.context = context;
        this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
    }
    
    /**
     * Получает UDP порт
     */
    public int getUDPPort() {
        return prefs.getInt(KEY_UDP_PORT, DEFAULT_UDP_PORT);
    }
    
    /**
     * Устанавливает UDP порт
     */
    public void setUDPPort(int port) {
        if (port < 1 || port > 65535) {
            Log.w(TAG, "Некорректный порт: " + port + ", используем значение по умолчанию");
            port = DEFAULT_UDP_PORT;
        }
        prefs.edit().putInt(KEY_UDP_PORT, port).apply();
        Log.i(TAG, "UDP порт установлен: " + port);
    }
    
    /**
     * Проверяет, включен ли UDP слушатель
     */
    public boolean isUDPEnabled() {
        return prefs.getBoolean(KEY_UDP_ENABLED, DEFAULT_UDP_ENABLED);
    }
    
    /**
     * Включает/выключает UDP слушатель
     */
    public void setUDPEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_UDP_ENABLED, enabled).apply();
        Log.i(TAG, "UDP слушатель: " + (enabled ? "включен" : "выключен"));
    }
    
    /**
     * Проверяет, включен ли Android NMEA
     */
    public boolean isAndroidNMEAEnabled() {
        return prefs.getBoolean(KEY_ANDROID_NMEA_ENABLED, DEFAULT_ANDROID_NMEA_ENABLED);
    }
    
    /**
     * Включает/выключает Android NMEA
     */
    public void setAndroidNMEAEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_ANDROID_NMEA_ENABLED, enabled).apply();
        Log.i(TAG, "Android NMEA: " + (enabled ? "включен" : "выключен"));
    }
    
    /**
     * Проверяет, включен ли UDP NMEA
     */
    public boolean isUDPNMEAEnabled() {
        return prefs.getBoolean(KEY_UDP_NMEA_ENABLED, DEFAULT_UDP_NMEA_ENABLED);
    }
    
    /**
     * Включает/выключает UDP NMEA
     */
    public void setUDPNMEAEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_UDP_NMEA_ENABLED, enabled).apply();
        Log.i(TAG, "UDP NMEA: " + (enabled ? "включен" : "выключен"));
    }
    
    /**
     * Получает режим работы с данными
     */
    public String getDataMode() {
        return prefs.getString(KEY_DATA_MODE, DEFAULT_DATA_MODE);
    }
    
    /**
     * Устанавливает режим работы с данными
     */
    public void setDataMode(String mode) {
        if (!isValidDataMode(mode)) {
            Log.w(TAG, "Некорректный режим данных: " + mode + ", используем значение по умолчанию");
            mode = DEFAULT_DATA_MODE;
        }
        prefs.edit().putString(KEY_DATA_MODE, mode).apply();
        Log.i(TAG, "Режим данных установлен: " + mode);
    }
    
    /**
     * Проверяет корректность режима данных
     */
    private boolean isValidDataMode(String mode) {
        return DATA_MODE_HYBRID.equals(mode) || 
               DATA_MODE_NMEA_ONLY.equals(mode) || 
               DATA_MODE_ANDROID_ONLY.equals(mode);
    }
    
    /**
     * Проверяет, включен ли гибридный режим
     */
    public boolean isHybridMode() {
        return DATA_MODE_HYBRID.equals(getDataMode());
    }
    
    /**
     * Проверяет, включен ли режим только NMEA
     */
    public boolean isNMEAOnlyMode() {
        return DATA_MODE_NMEA_ONLY.equals(getDataMode());
    }
    
    /**
     * Проверяет, включен ли режим только Android GPS
     */
    public boolean isAndroidOnlyMode() {
        return DATA_MODE_ANDROID_ONLY.equals(getDataMode());
    }
    
    /**
     * Сбрасывает все настройки к значениям по умолчанию
     */
    public void resetToDefaults() {
        prefs.edit()
            .putInt(KEY_UDP_PORT, DEFAULT_UDP_PORT)
            .putBoolean(KEY_UDP_ENABLED, DEFAULT_UDP_ENABLED)
            .putBoolean(KEY_ANDROID_NMEA_ENABLED, DEFAULT_ANDROID_NMEA_ENABLED)
            .putBoolean(KEY_UDP_NMEA_ENABLED, DEFAULT_UDP_NMEA_ENABLED)
            .putString(KEY_DATA_MODE, DEFAULT_DATA_MODE)
            .putInt(KEY_DATA_STALE_WARNING_MINUTES, DEFAULT_DATA_STALE_WARNING_MINUTES)
            .putInt(KEY_DATA_STALE_REMOVE_MINUTES, DEFAULT_DATA_STALE_REMOVE_MINUTES)
            .putBoolean(KEY_VIBRATION_ENABLED, DEFAULT_VIBRATION_ENABLED)
            .putBoolean(KEY_SOUND_ENABLED, DEFAULT_SOUND_ENABLED)
            .apply();
        Log.i(TAG, "Настройки сброшены к значениям по умолчанию");
    }
    
    /**
     * Получает все настройки в виде строки для отладки
     */
    public String getSettingsSummary() {
        return String.format(
            "UDP: порт=%d, включен=%s\n" +
            "Android NMEA: %s\n" +
            "UDP NMEA: %s\n" +
            "Режим данных: %s\n" +
            "Уведомления: вибрация=%s, звук=%s",
            getUDPPort(),
            isUDPEnabled() ? "да" : "нет",
            isAndroidNMEAEnabled() ? "включен" : "выключен",
            isUDPNMEAEnabled() ? "включен" : "выключен",
            getDataMode(),
            isVibrationEnabled() ? "включена" : "выключена",
            isSoundEnabled() ? "включен" : "выключен"
        );
    }
    
    /**
     * Проверяет, нужно ли перезапустить UDP слушатель
     */
    public boolean shouldRestartUDP(int currentPort, boolean currentEnabled) {
        return getUDPPort() != currentPort || isUDPEnabled() != currentEnabled;
    }
    
    /**
     * Проверяет, нужно ли перезапустить NMEA парсер
     */
    public boolean shouldRestartNMEA(boolean currentAndroidNMEA, boolean currentUDPNMEA, String currentDataMode) {
        return isAndroidNMEAEnabled() != currentAndroidNMEA || 
               isUDPNMEAEnabled() != currentUDPNMEA || 
               !getDataMode().equals(currentDataMode);
    }
    
    /**
     * Получает время предупреждения об устаревших данных (в минутах)
     */
    public int getDataStaleWarningMinutes() {
        return prefs.getInt(KEY_DATA_STALE_WARNING_MINUTES, DEFAULT_DATA_STALE_WARNING_MINUTES);
    }
    
    /**
     * Устанавливает время предупреждения об устаревших данных (в минутах)
     */
    public void setDataStaleWarningMinutes(int minutes) {
        if (minutes < 1 || minutes > 60) {
            Log.w(TAG, "Некорректное время предупреждения: " + minutes + ", используем значение по умолчанию");
            minutes = DEFAULT_DATA_STALE_WARNING_MINUTES;
        }
        prefs.edit().putInt(KEY_DATA_STALE_WARNING_MINUTES, minutes).apply();
        Log.i(TAG, "Время предупреждения об устаревших данных установлено: " + minutes + " минут");
    }
    
    /**
     * Получает время удаления устаревших данных (в минутах)
     */
    public int getDataStaleRemoveMinutes() {
        return prefs.getInt(KEY_DATA_STALE_REMOVE_MINUTES, DEFAULT_DATA_STALE_REMOVE_MINUTES);
    }
    
    /**
     * Устанавливает время удаления устаревших данных (в минутах)
     */
    public void setDataStaleRemoveMinutes(int minutes) {
        if (minutes < 1 || minutes > 60) {
            Log.w(TAG, "Некорректное время удаления: " + minutes + ", используем значение по умолчанию");
            minutes = DEFAULT_DATA_STALE_REMOVE_MINUTES;
        }
        prefs.edit().putInt(KEY_DATA_STALE_REMOVE_MINUTES, minutes).apply();
        Log.i(TAG, "Время удаления устаревших данных установлено: " + minutes + " минут");
    }
    
    /**
     * Проверяет, включено ли отслеживание путей
     */
    public boolean isPathTrackingEnabled() {
        return prefs.getBoolean(KEY_PATH_TRACKING_ENABLED, DEFAULT_PATH_TRACKING_ENABLED);
    }
    
    /**
     * Включает/выключает отслеживание путей
     */
    public void setPathTrackingEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_PATH_TRACKING_ENABLED, enabled).apply();
        Log.i(TAG, "Отслеживание путей: " + (enabled ? "включено" : "выключено"));
    }
    
    /**
     * Получает цвет пройденного пути
     */
    public int getPathColor() {
        return prefs.getInt(KEY_PATH_COLOR, DEFAULT_PATH_COLOR);
    }
    
    /**
     * Устанавливает цвет пройденного пути
     */
    public void setPathColor(int color) {
        prefs.edit().putInt(KEY_PATH_COLOR, color).apply();
        Log.i(TAG, "Цвет пройденного пути установлен: " + String.format("#%08X", color));
    }
    
    /**
     * Получает цвет прогнозируемого пути
     */
    public int getPredictionColor() {
        return prefs.getInt(KEY_PREDICTION_COLOR, DEFAULT_PREDICTION_COLOR);
    }
    
    /**
     * Устанавливает цвет прогнозируемого пути
     */
    public void setPredictionColor(int color) {
        prefs.edit().putInt(KEY_PREDICTION_COLOR, color).apply();
        Log.i(TAG, "Цвет прогнозируемого пути установлен: " + String.format("#%08X", color));
    }
    
    /**
     * Получает ширину линии пройденного пути
     */
    public float getPathWidth() {
        return prefs.getFloat(KEY_PATH_WIDTH, DEFAULT_PATH_WIDTH);
    }
    
    /**
     * Устанавливает ширину линии пройденного пути
     */
    public void setPathWidth(float width) {
        if (width < 1.0f || width > 10.0f) {
            Log.w(TAG, "Некорректная ширина пути: " + width + ", используем значение по умолчанию");
            width = DEFAULT_PATH_WIDTH;
        }
        prefs.edit().putFloat(KEY_PATH_WIDTH, width).apply();
        Log.i(TAG, "Ширина пройденного пути установлена: " + width);
    }
    
    /**
     * Получает ширину линии прогнозируемого пути
     */
    public float getPredictionWidth() {
        return prefs.getFloat(KEY_PREDICTION_WIDTH, DEFAULT_PREDICTION_WIDTH);
    }
    
    /**
     * Устанавливает ширину линии прогнозируемого пути
     */
    public void setPredictionWidth(float width) {
        if (width < 1.0f || width > 10.0f) {
            Log.w(TAG, "Некорректная ширина прогноза: " + width + ", используем значение по умолчанию");
            width = DEFAULT_PREDICTION_WIDTH;
        }
        prefs.edit().putFloat(KEY_PREDICTION_WIDTH, width).apply();
        Log.i(TAG, "Ширина прогнозируемого пути установлена: " + width);
    }
    
    /**
     * Проверяет, включена ли вибрация при обнаружении новых AIS целей
     */
    public boolean isVibrationEnabled() {
        return prefs.getBoolean(KEY_VIBRATION_ENABLED, DEFAULT_VIBRATION_ENABLED);
    }
    
    /**
     * Включает/выключает вибрацию при обнаружении новых AIS целей
     */
    public void setVibrationEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_VIBRATION_ENABLED, enabled).apply();
        Log.i(TAG, "Вибрация при обнаружении новых AIS целей: " + (enabled ? "включена" : "выключена"));
    }
    
    /**
     * Проверяет, включен ли звук при обнаружении новых AIS целей
     */
    public boolean isSoundEnabled() {
        return prefs.getBoolean(KEY_SOUND_ENABLED, DEFAULT_SOUND_ENABLED);
    }
    
    /**
     * Включает/выключает звук при обнаружении новых AIS целей
     */
    public void setSoundEnabled(boolean enabled) {
        prefs.edit().putBoolean(KEY_SOUND_ENABLED, enabled).apply();
        Log.i(TAG, "Звук при обнаружении новых AIS целей: " + (enabled ? "включен" : "выключен"));
    }
}
