import fs from "fs";
import Jimp from "jimp";

/**
 * 
 * @module color-predictor
 */

const calcAvg = (arr: number[]) =>
  arr.reduce((acc, num) => acc + num, 0) / (arr.length - 1);

/**
 *
 * @param url
 * @returns color
 */
const colorFromURL = async (url: string): Promise<string> => {
  try {
    let color = "";
    const red: number[] = [];
    const green: number[] = [];
    const blue: number[] = [];

    const image = await Jimp.read(url);

    image.cover(
      224,
      224,
      Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE
    );

    image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x, y, _) => {
      const pixel = Jimp.intToRGBA(image.getPixelColor(x, y));
      red.push(pixel.r);
      green.push(pixel.g);
      blue.push(pixel.b);
    });

    const [redavg, greeenavg, blueavg] = await Promise.all([
      calcAvg(red),
      calcAvg(green),
      calcAvg(blue),
    ]);

    if (redavg > greeenavg && redavg > blueavg) {
      color = "red";
    } else if (greeenavg > redavg && greeenavg > blueavg) {
      color = "green";
    } else if (blueavg > redavg && blueavg > greeenavg) {
      color = "blue";
    } else {
      throw Error("something went wrong");
    }

    return color;
  } catch (error) {
    console.log(error);
    return "something went wrong";
  }
};

/**
 * 
 * @param reds
 * @param greens
 * @param blues
 */

const colorFromRGB = async (
  r: number[],
  g: number[],
  b: number[]
): Promise<string> => {
  try {
    let color = "";
    const [redavg, greeenavg, blueavg] = await Promise.all([
      calcAvg(r),
      calcAvg(g),
      calcAvg(b),
    ]);

    if (redavg > greeenavg && redavg > blueavg) {
      color = "red";
    } else if (greeenavg > redavg && greeenavg > blueavg) {
      color = "green";
    } else if (blueavg > redavg && blueavg > greeenavg) {
      color = "blue";
    } else {
      throw Error("something went wrong with the color");
    }
    return color;
  } catch (error) {
    console.log(error);
    throw Error("something went wrong with color");
  }
};



/**
 * 
 * @param path - path to image
 * @returns color
 */

const colorFromImage = async (path: string): Promise<string> => {
    try {
        if(!fs.existsSync(path)){
            throw Error("image not found");
        }

        let color = "";
        const red: number[] = [];
        const green: number[] = [];
        const blue: number[] = [];
    
        const image = await Jimp.read(path);
    
        image.cover(
          224,
          224,
          Jimp.HORIZONTAL_ALIGN_CENTER | Jimp.VERTICAL_ALIGN_MIDDLE
        );
    
        image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x, y, _) => {
          const pixel = Jimp.intToRGBA(image.getPixelColor(x, y));
          red.push(pixel.r);
          green.push(pixel.g);
          blue.push(pixel.b);
        });
    
        const [redavg, greeenavg, blueavg] = await Promise.all([
          calcAvg(red),
          calcAvg(green),
          calcAvg(blue),
        ]);
    
        if (redavg > greeenavg && redavg > blueavg) {
          color = "red";
        } else if (greeenavg > redavg && greeenavg > blueavg) {
          color = "green";
        } else if (blueavg > redavg && blueavg > greeenavg) {
          color = "blue";
        } else {
          throw Error("something went wrong");
        }
    
        return color;
      } catch (error) {
        console.log(error);
        return "something went wrong";
      }
}

const predict = {
    colorFromURL,
    colorFromRGB,
    colorFromImage
}


export default predict;
