package com.grigowashere.aismap.utils;

import android.util.Log;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Утилита для отправки логов на внешний ресурс
 * Отправляет GET запросы на https://ais.grigowashere.ru/add
 */
public class LogSender {
    
    private static final String TAG = "LogSender";
    private static final String BASE_URL = "https://ais.grigowashere.ru/add";
    private static final ExecutorService executor = Executors.newSingleThreadExecutor();
    
    /**
     * Отправляет лог NMEA сообщения
     * @param nmeaMessage NMEA сообщение
     */
    public static void logNMEA(String nmeaMessage) {
        if (nmeaMessage == null || nmeaMessage.trim().isEmpty()) {
            return;
        }
        
        executor.execute(() -> {
            try {
                String encodedMessage = encodeForURL(nmeaMessage);
                String url = BASE_URL + "?nmea=" + encodedMessage + "&color=blue";
                
                sendGetRequest(url);
                Log.d(TAG, "NMEA лог отправлен: " + nmeaMessage);
            } catch (Exception e) {
                Log.e(TAG, "Ошибка отправки NMEA лога: " + e.getMessage(), e);
            }
        });
    }
    
    /**
     * Отправляет лог обновления информации о корабле
     * @param mmsi MMSI корабля
     * @param vesselInfo Информация о корабле
     */
    public static void logShipUpdate(String mmsi, String vesselInfo) {
        if (mmsi == null || mmsi.trim().isEmpty()) {
            return;
        }
        
        executor.execute(() -> {
            try {
                String message = "MMSI: " + mmsi;
                if (vesselInfo != null && !vesselInfo.trim().isEmpty()) {
                    message += " | " + vesselInfo;
                }
                
                // Извлекаем тип судна из vesselInfo и генерируем цвет
                // Генерируем уникальный цвет для корабля на основе MMSI
                String vesselColor = generateVesselColor(mmsi);
                
                String encodedMessage = encodeForURL(message);
                String encodedColor = encodeColorForURL(vesselColor);
                String url = BASE_URL + "?ships=" + encodedMessage + "&color=" + encodedColor;
                
                sendGetRequest(url);
                Log.d(TAG, "Ship update лог отправлен: " + message + " ( " + ", цвет: " + vesselColor + ")");
            } catch (Exception e) {
                Log.e(TAG, "Ошибка отправки ship update лога: " + e.getMessage(), e);
            }
        });
    }
    
    /**
     * Отправляет лог обновления информации о корабле с заданным цветом
     * @param mmsi MMSI корабля
     * @param vesselInfo Информация о корабле
     * @param color Цвет в формате HEX (#RRGGBB) или имя цвета
     */
    public static void logShipUpdate(String mmsi, String vesselInfo, String color) {
        if (mmsi == null || mmsi.trim().isEmpty()) {
            return;
        }
        
        executor.execute(() -> {
            try {
                String message = "MMSI: " + mmsi;
                if (vesselInfo != null && !vesselInfo.trim().isEmpty()) {
                    message += " | " + vesselInfo;
                }
                
                // Используем переданный цвет или генерируем на основе типа судна
                String vesselColor;
                if (color != null && !color.trim().isEmpty()) {
                    vesselColor = color;
                } else {
                    // Генерируем уникальный цвет для корабля на основе MMSI
                    vesselColor = generateVesselColor(mmsi);
                }
                
                String encodedMessage = encodeForURL(message);
                String encodedColor = encodeColorForURL(vesselColor);
                String url = BASE_URL + "?ships=" + encodedMessage + "&color=" + encodedColor;
                
                sendGetRequest(url);
                Log.d(TAG, "Ship update лог отправлен: " + message + " (цвет: " + vesselColor + ")");
            } catch (Exception e) {
                Log.e(TAG, "Ошибка отправки ship update лога: " + e.getMessage(), e);
            }
        });
    }
    
    /**
     * Отправляет произвольный лог
     * @param logName Имя лога
     * @param message Сообщение
     * @param color Цвет (опционально)
     */
    public static void logCustom(String logName, String message, String color) {
        if (logName == null || logName.trim().isEmpty() || message == null || message.trim().isEmpty()) {
            return;
        }
        
        executor.execute(() -> {
            try {
                String encodedMessage = encodeForURL(message);
                String url = BASE_URL + "?" + logName + "=" + encodedMessage;
                
                if (color != null && !color.trim().isEmpty()) {
                    url += "&color=" + color;
                }
                
                sendGetRequest(url);
                Log.d(TAG, "Custom лог отправлен: " + logName + " = " + message);
            } catch (Exception e) {
                Log.e(TAG, "Ошибка отправки custom лога: " + e.getMessage(), e);
            }
        });
    }
    
    
    
    
    /**
     * Генерирует уникальный цвет для корабля на основе MMSI (устаревший метод)
     * @param mmsi MMSI корабля
     * @return HEX цвет в формате #RRGGBB
     */
    private static String generateVesselColor(String mmsi) {
        try {
            // Преобразуем MMSI в число для хеширования
            long mmsiValue = Long.parseLong(mmsi);
            
            // Используем хеш-функцию для получения равномерного распределения
            int hash = Long.hashCode(mmsiValue);
            
            // Извлекаем RGB компоненты из хеша
            int r = (hash & 0xFF0000) >> 16;
            int g = (hash & 0x00FF00) >> 8;
            int b = hash & 0x0000FF;
            
            // Проверяем, не слишком ли темный цвет (чтобы избежать черного)
            int brightness = (r + g + b) / 3;
            if (brightness < 100) {
                // Если цвет слишком темный, осветляем его
                r = Math.min(255, r + 120);
                g = Math.min(255, g + 120);
                b = Math.min(255, b + 120);
            }
            
            // Проверяем, не слишком ли светлый цвет (чтобы избежать белого)
            if (brightness > 220) {
                // Если цвет слишком светлый, затемняем его
                r = Math.max(0, r - 60);
                g = Math.max(0, g - 60);
                b = Math.max(0, b - 60);
            }
            
            // Форматируем в HEX
            String color = String.format("#%02X%02X%02X", r, g, b);
            
            Log.d(TAG, "Сгенерирован цвет для MMSI " + mmsi + ": " + color + " (RGB: " + r + "," + g + "," + b + ")");
            
            return color;
            
        } catch (NumberFormatException e) {
            Log.w(TAG, "Не удалось распарсить MMSI как число: " + mmsi + ", используем цвет по умолчанию");
            return "#00AA00"; // Зеленый по умолчанию
        } catch (Exception e) {
            Log.e(TAG, "Ошибка генерации цвета для MMSI " + mmsi + ": " + e.getMessage(), e);
            return "#00AA00"; // Зеленый по умолчанию
        }
    }
    
    /**
     * Определяет тип судна по MMSI
     * Использует более точную логику на основе стандартных диапазонов MMSI
     * @param mmsi MMSI судна
     * @return Тип судна
     */
    private static String getVesselTypeByMMSI(long mmsi) {
        // Стандартные диапазоны MMSI для разных типов судов
        if (mmsi >= 100000000 && mmsi <= 199999999) {
            return "COASTAL"; // Прибрежные суда
        } else if (mmsi >= 200000000 && mmsi <= 299999999) {
            return "FISHING"; // Рыболовные суда
        } else if (mmsi >= 300000000 && mmsi <= 399999999) {
            return "CARGO"; // Грузовые суда
        } else if (mmsi >= 400000000 && mmsi <= 499999999) {
            return "TANKER"; // Танкеры
        } else if (mmsi >= 500000000 && mmsi <= 599999999) {
            return "PASSENGER"; // Пассажирские суда
        } else if (mmsi >= 600000000 && mmsi <= 699999999) {
            return "MILITARY"; // Военные корабли
        } else if (mmsi >= 700000000 && mmsi <= 799999999) {
            return "PILOT"; // Лоцманские суда
        } else if (mmsi >= 800000000 && mmsi <= 899999999) {
            return "PILOT"; // Лоцманские суда (дополнительный диапазон)
        } else if (mmsi >= 900000000 && mmsi <= 999999999) {
            return "MILITARY"; // Военные корабли (дополнительный диапазон)
        } else if (mmsi >= 1000000000 && mmsi <= 1099999999) {
            return "SAR"; // Спасательные суда
        } else if (mmsi >= 1100000000 && mmsi <= 1199999999) {
            return "TUG"; // Буксиры
        } else if (mmsi >= 1200000000 && mmsi <= 1299999999) {
            return "PORT_TENDER"; // Портовые суда
        } else if (mmsi >= 1300000000 && mmsi <= 1399999999) {
            return "ANTI_POLLUTION"; // Антизагрязнительные суда
        } else if (mmsi >= 1400000000 && mmsi <= 1499999999) {
            return "LAW_ENFORCEMENT"; // Правоохранительные суда
        } else if (mmsi >= 1500000000 && mmsi <= 1599999999) {
            return "MEDICAL"; // Медицинские суда
        } else if (mmsi >= 1600000000 && mmsi <= 1699999999) {
            return "SPECIAL_CRAFT"; // Специальные суда
        } else if (mmsi >= 1700000000 && mmsi <= 1799999999) {
            return "PASSENGER"; // Пассажирские суда (дополнительный диапазон)
        } else if (mmsi >= 1800000000 && mmsi <= 1899999999) {
            return "CARGO"; // Грузовые суда (дополнительный диапазон)
        } else if (mmsi >= 1900000000 && mmsi <= 1999999999) {
            return "TANKER"; // Танкеры (дополнительный диапазон)
        } else if (mmsi >= 2000000000 && mmsi <= 2099999999) {
            return "OTHER"; // Другие типы судов
        } else if (mmsi >= 2100000000L && mmsi <= 2199999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2200000000L && mmsi <= 2299999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2300000000L && mmsi <= 2399999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2400000000L && mmsi <= 2499999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2500000000L && mmsi <= 2599999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2600000000L && mmsi <= 2699999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2700000000L && mmsi <= 2799999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2800000000L && mmsi <= 2899999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else if (mmsi >= 2900000000L && mmsi <= 2999999999L) {
            return "OTHER"; // Другие типы судов (дополнительный диапазон)
        } else {
            return "UNKNOWN"; // Неизвестный тип
        }
    }
    
    /**
     * Кодирует цвет для безопасного использования в URL
     * Специально обрабатывает HEX цвета, заменяя # на %23
     * @param color Цвет в формате HEX (#RRGGBB) или имя цвета
     * @return Закодированный цвет
     */
    private static String encodeColorForURL(String color) {
        if (color == null || color.trim().isEmpty()) {
            return "green"; // Цвет по умолчанию
        }
        
        try {
            // Если цвет начинается с #, заменяем его на %23
            if (color.startsWith("#")) {
                String encoded = "%23" + color.substring(1);
                Log.d(TAG, "Закодирован HEX цвет: " + color + " -> " + encoded);
                return encoded;
            } else {
                // Для именованных цветов используем стандартное кодирование
                String encoded = URLEncoder.encode(color, StandardCharsets.UTF_8.toString());
                Log.d(TAG, "Закодирован именованный цвет: " + color + " -> " + encoded);
                return encoded;
            }
        } catch (Exception e) {
            Log.e(TAG, "Ошибка кодирования цвета: " + e.getMessage(), e);
            return "green"; // Цвет по умолчанию
        }
    }
    
    /**
     * Кодирует строку для безопасного использования в URL
     * Дополнительно экранирует символы, которые могут вызывать проблемы
     * @param message Исходное сообщение
     * @return Закодированное сообщение
     */
    private static String encodeForURL(String message) {
        try {
            // Сначала используем стандартное URL кодирование
            String encoded = URLEncoder.encode(message, StandardCharsets.UTF_8.toString());
            
            // Дополнительно экранируем символы, которые могут вызывать проблемы
            // Заменяем < на %3C, > на %3E, & на %26, " на %22, ' на %27, # на %23
            encoded = encoded.replace("<", "%3C")
                           .replace(">", "%3E")
                           .replace("&", "%26")
                           .replace("\"", "%22")
                           .replace("'", "%27")
                           .replace("#", "%23");
            
            // Логируем для отладки
            Log.d(TAG, "Исходное сообщение: " + message);
            Log.d(TAG, "Закодированное сообщение: " + encoded);
            
            return encoded;
        } catch (Exception e) {
            Log.e(TAG, "Ошибка кодирования URL: " + e.getMessage(), e);
            // В случае ошибки возвращаем базовое кодирование
            String fallback = message.replace("<", "%3C")
                                   .replace(">", "%3E")
                                   .replace("&", "%26")
                                   .replace("\"", "%22")
                                   .replace("'", "%27")
                                   .replace("#", "%23")
                                   .replace(" ", "%20");
            Log.d(TAG, "Fallback кодирование: " + fallback);
            return fallback;
        }
    }
    
    /**
     * Отправляет GET запрос
     * @param urlString URL для запроса
     */
    private static void sendGetRequest(String urlString) {
        HttpURLConnection connection = null;
        try {
            // Логируем полный URL для отладки
            Log.d(TAG, "Отправляем GET запрос на: " + urlString);
            
            @SuppressWarnings("deprecation")
            URL url = new URL(urlString);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000); // 5 секунд
            connection.setReadTimeout(5000); // 5 секунд
            connection.setRequestProperty("User-Agent", "AISMap/1.0");
            
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                Log.d(TAG, "Лог успешно отправлен, код ответа: " + responseCode);
            } else {
                Log.w(TAG, "Лог отправлен с предупреждением, код ответа: " + responseCode);
            }
        } catch (IOException e) {
            Log.e(TAG, "Ошибка HTTP запроса: " + e.getMessage(), e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
    
    /**
     * Останавливает executor (вызывать при завершении приложения)
     */
    public static void shutdown() {
        executor.shutdown();
    }
}
