package com.grigowashere.aismap.controllers;

import android.content.Context;
import android.util.Log;
import com.grigowashere.aismap.maps.MapInterface;
import com.grigowashere.aismap.maps.MapInterfaceChangeListener;
import com.grigowashere.aismap.maps.MarkerManager;
import com.grigowashere.aismap.maps.YandexMapImpl;
import com.grigowashere.aismap.maps.MapLibreMapImpl;
import com.grigowashere.aismap.maps.YandexMarkerManager;
import com.yandex.mapkit.mapview.MapView;

import java.util.ArrayList;
import java.util.List;

/**
 * Контроллер для управления картами
 * Единственный владелец MapInterface - централизованное управление картами
 * Уведомляет всех подписчиков о смене стратегии карты
 */
public class MapController {
    
    private static final String TAG = "MapController";
    private static boolean isYandexMapsInitialized = false;
    
    private Context context;
    private MapInterface currentMapInterface;
    private MapView mapView;
    private org.maplibre.android.maps.MapView mapLibreView;
    
    // Менеджер маркеров (SDK-специфичный)
    private MarkerManager markerManager;
    
    // Список слушателей изменений MapInterface
    private final List<MapInterfaceChangeListener> listeners = new ArrayList<>();
    
    public MapController(Context context) {
        this.context = context;
    }
    
    /**
     * Добавляет слушателя изменений MapInterface
     */
    public void addMapInterfaceChangeListener(MapInterfaceChangeListener listener) {
        if (listener != null && !listeners.contains(listener)) {
            listeners.add(listener);
            Log.d(TAG, "Добавлен слушатель изменений MapInterface: " + listener.getClass().getSimpleName());
        }
    }
    
    /**
     * Удаляет слушателя изменений MapInterface
     */
    public void removeMapInterfaceChangeListener(MapInterfaceChangeListener listener) {
        if (listeners.remove(listener)) {
            Log.d(TAG, "Удален слушатель изменений MapInterface: " + listener.getClass().getSimpleName());
        }
    }
    
    /**
     * Уведомляет всех слушателей о смене MapInterface
     */
    private void notifyMapInterfaceChanged(MapInterface oldMapInterface, MapInterface newMapInterface) {
        Log.i(TAG, "Уведомляем " + listeners.size() + " слушателей о смене MapInterface");
        for (MapInterfaceChangeListener listener : listeners) {
            try {
                listener.onMapInterfaceChanged(oldMapInterface, newMapInterface);
            } catch (Exception e) {
                Log.e(TAG, "Ошибка при уведомлении слушателя " + listener.getClass().getSimpleName() + ": " + e.getMessage());
            }
        }
    }
    
    /**
     * Инициализирует карту указанного типа
     */
    public MapInterface initializeMap(String mapType, MapView mapView) {
        this.mapView = mapView;
        
        MapInterface oldMapInterface = currentMapInterface;
        MapInterface newMapInterface = null;
        
        switch (mapType.toLowerCase()) {
            case "yandex":
                newMapInterface = initializeYandexMaps();
                break;
            case "mapforge":
                newMapInterface = initializeMapForge();
                break;
            default:
                Log.e(TAG, "Неизвестный тип карты: " + mapType);
                return null;
        }
        
        if (newMapInterface != null) {
            currentMapInterface = newMapInterface;
            initializeMarkerManager(); // Инициализируем MarkerManager
            notifyMapInterfaceChanged(oldMapInterface, newMapInterface);
        }
        
        return newMapInterface;
    }

    /**
     * Инициализирует MapLibre
     */
    public MapInterface initializeMapLibre(org.maplibre.android.maps.MapView mapLibreView) {
        try {
            this.mapLibreView = mapLibreView;
            Log.i(TAG, "Создаем интерфейс для MapLibre");
            
            MapInterface oldMapInterface = currentMapInterface;
            currentMapInterface = new MapLibreMapImpl(context, mapLibreView);
            
            // Инициализируем MarkerManager
            initializeMarkerManager();
            
            // Уведомляем слушателей о смене MapInterface
            notifyMapInterfaceChanged(oldMapInterface, currentMapInterface);
            
            return currentMapInterface;
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при создании интерфейса MapLibre: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * Устанавливает VesselPathController в текущий интерфейс карты
     */
    public void setVesselPathController(VesselPathController pathController) {
        if (currentMapInterface instanceof MapLibreMapImpl) {
            ((MapLibreMapImpl) currentMapInterface).setVesselPathController(pathController);
            Log.i(TAG, "VesselPathController установлен в MapLibreMapImpl");
        }
    }
    
    // AppController удален. Метод оставлен неактивным для обратной совместимости.
    
    /**
     * Устанавливает AppCoordinator в текущий интерфейс карты
     */
    public void setAppCoordinator(AppCoordinator appCoordinator) {
        if (currentMapInterface instanceof MapLibreMapImpl) {
            ((MapLibreMapImpl) currentMapInterface).setAppCoordinator(appCoordinator);
            Log.i(TAG, "AppCoordinator установлен в MapLibreMapImpl");
        }
    }
    
    /**
     * Получает текущий MarkerManager
     */
    public MarkerManager getMarkerManager() {
        return markerManager;
    }
    
    /**
     * Инициализирует MarkerManager для текущей карты
     */
    private void initializeMarkerManager() {
        if (currentMapInterface instanceof YandexMapImpl) {
            // Для Yandex Maps создаем YandexMarkerManager
            markerManager = new YandexMarkerManager(context, null, mapView, null);
            Log.i(TAG, "YandexMarkerManager инициализирован");
        } else if (currentMapInterface instanceof MapLibreMapImpl) {
            // Для MapLibre пока что null - маркеры управляются через MapInterface
            markerManager = null;
            Log.i(TAG, "MapLibre использует встроенное управление маркерами");
        }
    }
    
    /**
     * Очищает MarkerManager
     */
    private void cleanupMarkerManager() {
        if (markerManager != null) {
            markerManager.cleanup();
            markerManager = null;
            Log.i(TAG, "MarkerManager очищен");
        }
    }
    
    /**
     * Инициализирует Яндекс.Карты
     */
    private MapInterface initializeYandexMaps() {
        try {
            // Проверяем, что Яндекс.Карты уже инициализированы
            if (!isYandexMapsInitialized) {
                Log.w(TAG, "Яндекс.Карты не инициализированы. Должны быть инициализированы в MainActivity");
                return null;
            }
            
            Log.i(TAG, "Создаем интерфейс для Яндекс.Карт");
            
            // Создаем интерфейс для Яндекс.Карт
            return new YandexMapImpl(context, mapView);
            
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при создании интерфейса Яндекс.Карт: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * Инициализирует MapForge
     */
    private MapInterface initializeMapForge() {
        try {
            // TODO: Реализовать инициализацию MapForge
            Log.i(TAG, "MapForge инициализация (пока не реализована)");
            return null;
        } catch (Exception e) {
            Log.e(TAG, "Ошибка при инициализации MapForge: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * Запускает карту
     */
    public void startMap() {
        if (mapView != null) { mapView.onStart(); }
        if (mapLibreView != null) { mapLibreView.onStart(); }
        
        if (isYandexMapsInitialized) {
            com.yandex.mapkit.MapKitFactory.getInstance().onStart();
        }
    }
    
    /**
     * Останавливает карту
     */
    public void stopMap() {
        if (mapView != null) { mapView.onStop(); }
        if (mapLibreView != null) { mapLibreView.onStop(); }
        
        if (isYandexMapsInitialized) {
            com.yandex.mapkit.MapKitFactory.getInstance().onStop();
        }
    }
    
    /**
     * Получает текущий интерфейс карты
     * Единственный способ получить MapInterface извне
     */
    public MapInterface getCurrentMapInterface() {
        return currentMapInterface;
    }
    
    /**
     * Получает текущий интерфейс карты (алиас для совместимости)
     */
    public MapInterface getMapInterface() {
        return getCurrentMapInterface();
    }
    
    /**
     * Устанавливает флаг инициализации Яндекс.Карт
     */
    public static void setYandexMapsInitialized(boolean initialized) {
        isYandexMapsInitialized = initialized;
    }
    
    /**
     * Освобождает ресурсы
     */
    public void cleanup() {
        Log.i(TAG, "Очистка MapController");
        
        // Очищаем текущий MapInterface
        if (currentMapInterface != null) {
            currentMapInterface.cleanup();
            currentMapInterface = null;
        }
        
        // Очищаем MarkerManager
        cleanupMarkerManager();
        
        // Очищаем слушателей
        listeners.clear();
        
        // Останавливаем карты
        if (mapView != null) { mapView.onStop(); }
        if (mapLibreView != null) { mapLibreView.onStop(); }
        
        if (isYandexMapsInitialized) {
            com.yandex.mapkit.MapKitFactory.getInstance().onStop();
        }
        
        Log.i(TAG, "MapController очищен");
    }
}
