import os
import uuid

import requests
from environment import Environment
from firebase_admin import storage as firebase_storage
from google.cloud import storage as google_storage
from PIL import Image


class FirebaseStorageService:

    # Returns a list of the download links for the folder specified in Firebase Storage (sorted from newest files to oldest files)
    @staticmethod
    def get_download_links_for_folders(paths):
        bucket_name = f"{Environment.GCLOUD_PROJECT_ID}.appspot.com"

        storage_client = google_storage.Client.from_service_account_json(Environment.FIREBASE_CRED_PATH) if not Environment.LIVE_SERVER else google_storage.Client()

        # Initialize an empty list to collect all blobs
        all_blobs_with_time = []

        for path in paths:
            blobs = storage_client.list_blobs(bucket_name, prefix=path)

            # Filter out any "blobs" that represent directories or prefixes
            valid_blobs = [blob for blob in blobs if not blob.name.endswith("/")]

            # Extend the all_blobs_with_time list with tuples containing a blob's public_url and time_created
            all_blobs_with_time.extend(
                [(blob.public_url, blob.time_created) for blob in valid_blobs]
            )

        # Sort the list of tuples by the time_created in descending order (i.e., newest to oldest)
        sorted_blobs_with_time = sorted(
            all_blobs_with_time, key=lambda x: x[1], reverse=True
        )

        # Create a list of download urls sorted from newest to oldest
        download_urls = [blob[0] for blob in sorted_blobs_with_time]

        return download_urls
    
    # Upload a file to Firebase Storage and returns the link to the uploded file
    @staticmethod
    def upload_file_to_storage(source_path, destination_path):
        def convert_jpg_to_webp(path):
            if "jpg" in path:
                new_path = path.replace("jpg", "webp")
                print(new_path)
                with Image.open(path) as image:
                    image.save(new_path, "WEBP")
            else:
                new_path = path
            return new_path
        
        # convert jpgs to webp before uploading
        new_source_path = convert_jpg_to_webp(source_path)

        new_file_name = new_source_path.split("/")[-1]

        bucket = firebase_storage.bucket(f"{Environment.GCLOUD_PROJECT_ID}.appspot.com")
        blob = bucket.blob(destination_path + "/" + new_file_name)

        if "webp" in new_file_name: # if webp, set metadata accordingly
            uuid_value = str(uuid.uuid4())
            blob.metadata = {"firebaseStorageDownloadTokens": uuid_value}
            blob.upload_from_filename(new_source_path, content_type="image/webp")
        else:
            blob.upload_from_filename(new_source_path)
        print(f"File {new_file_name} uploaded to Firebase Storage.")

        try:
            os.remove(new_source_path)
        except Exception as e:
            print(f"Unable to remove file after upload: {e}")

        return blob.public_url
    
    @staticmethod
    def download_image_from_url(url, destination_path):
        response = requests.get(url, stream=True)
        response.raise_for_status()  # Raises an HTTPError if the HTTP request returned an unsuccessful status code

        with open(destination_path, 'wb') as file:
            for chunk in response.iter_content(chunk_size=8192):
                file.write(chunk)

        return destination_path
