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

import com.rdkr.tide_display.backend.images.responses.ImageResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HexFormat;
import javax.imageio.ImageIO;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ImageConverterService {

  public byte[] convert(byte[] image) throws IOException {
    val img = ImageIO.read(new ByteArrayInputStream(image));
    val celShadedImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);

    for (int y = 0; y < img.getHeight(); y++) {
      for (int x = 0; x < img.getWidth(); x++) {
        // Pixel-Farbe auslesen
        int rgb = img.getRGB(x, y);

        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = rgb & 0xFF;

        int gray = (r + g + b) / 3;

        int celShadeLevel = gray / 16;
        int newGray = celShadeLevel * 16;

        int newRGB = (newGray << 16) | (newGray << 8) | newGray;

        celShadedImage.setRGB(x, y, newRGB);
      }
    }
    val out = new ByteArrayOutputStream();
    ImageIO.write(celShadedImage, "png", out);
    return out.toByteArray();
  }


  public ImageResponse ePaperFormat(byte[] image) throws IOException {
    val img = ImageIO.read(new ByteArrayInputStream(image));
    val width = img.getWidth();
    val height = img.getHeight();
    val result = new ByteArrayOutputStream(image.length);
    for (int y = 0; y < height; y++) {
      int b = 0;
      boolean done = true;
      for (int x = 0; x < width; x++) {
        val color = img.getRGB(x, y);
        if (x % 2 == 0) {
          b = color >> 4;
          done = false;
        } else {
          b |= color & 0xF0;
          result.write(b);
          done = true;
        }
      }
      if (!done) {
        result.write(b);
      }
    }
    val bytes = result.toByteArray();
    if (log.isDebugEnabled()) {
      val hex = HexFormat.of().withUpperCase().withPrefix("0x").withSuffix(", ").formatHex(bytes);
      log.debug("Image: {}", hex);
    }
    return new ImageResponse(width, height, Base64.getEncoder().encode(bytes));
  }
}
