# library for interacting with the file system and image files
import os

# library to open and manipulate image files
from PIL import Image

# numerical arrays and math operations
import numpy as np

# fetch data (e.g. images) from URLs
import requests

# treat raw bytes as a file-like object in memory
from io import BytesIO


# ---------------------------------------------------------------------------
# Constants (variables) we will use across the code
# ---------------------------------------------------------------------------

IMG_SIZE = (128, 128)
CLASSES = ["chihuahua", "muffin"]
BINS_PER_CHANNEL = 32


# ---------------------------------------------------------------------------
# Step 1: Featurizing the Image Data
# ---------------------------------------------------------------------------

def extract_color_histogram(img, img_size=IMG_SIZE, bins=BINS_PER_CHANNEL):
    img = img.convert("RGB").resize(img_size)
    arr = np.array(img) / 255.0

    hist_feats = []
    for ch in range(3):
        hist, _ = np.histogram(arr[:, :, ch], bins=bins, range=(0, 1))
        hist_feats.append(hist)

    hist_feats = np.concatenate(hist_feats).astype(np.float64)
    hist_feats /= hist_feats.sum() + 1e-8
    return hist_feats

def load_one_folder(folder, label):
    X, y = [], []
    filenames = os.listdir(folder)
    for filename in filenames:
        if filename.endswith(".jpg"):
            full_path = folder + filename
            X.append(extract_color_histogram(Image.open(full_path)))
            y.append(label)
    return X, y

# ---------------------------------------------------------------------------
# 5. Let's predict!
# ---------------------------------------------------------------------------

def predict_image_from_url(img_url, model, classes=CLASSES):
    response = requests.get(img_url, timeout=10)
    response.raise_for_status()  # raises an error if the download failed

    img = Image.open(BytesIO(response.content))
    features = extract_color_histogram(img).reshape(1, -1)

    pred = model.predict(features)[0]
    proba = model.predict_proba(features)[0]

    print(f"\nImage URL: {img_url}")
    print(f"Prediction: {pred} (0={classes[0]}, 1={classes[1]})")
    print(f"Probabilities: {classes[0]}={proba[0]:.3f}, {classes[1]}={proba[1]:.3f}")
    return classes[pred]
