package com.rdkr.tide_display.backend.images.services;

import com.rdkr.tide_display.backend.gcp.StorageService;
import com.rdkr.tide_display.backend.images.services.mapProvider.MapProvider;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeType;

@Service
public class MapServiceImpl implements MapService {

  private final Map<String, MapProvider> providers = new HashMap<>();
  private final StorageService storageService;

  public MapServiceImpl(List<MapProvider> mapProviders, StorageService storageService) {
    this.storageService = storageService;
    mapProviders.forEach(
        provider -> providers.put(provider.getClass().getAnnotation(Component.class).value().toUpperCase(), provider));
  }

  public List<String> getMapProviders() {
    return List.copyOf(providers.keySet());
  }

  @Cacheable(value = "map", key = "{#provider, #latitude, #longitude, #zoom}")
  public byte[] getStaticMap(String provider, double latitude, double longitude, int zoom) {
    val mapProvider = providers.get(provider.toUpperCase());
    if (mapProvider == null) {
      throw new UnsupportedOperationException("Map provider not found: " + provider);
    }
    val imageData = mapProvider.getStaticMap(latitude, longitude, zoom);
    cacheImage(provider, latitude, longitude, zoom, imageData);
    return imageData;
  }

  private void cacheImage(String provider, double latitude, double longitude, int zoom, byte[] image) {
    storageService.save("mapProvider/" + provider.toUpperCase() + "/" + latitude + "/" + longitude + "/" + zoom + "/image.png", image, MediaType.IMAGE_PNG_VALUE, 60);
  }
}
