import os
import time
import requests
import cloudinary
from cloudinary import uploader, api
#from dotenv import load_dotenv
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# Configure Cloudinary with your credentials
cloudinary.config(
    # cloud_name='df667rfp2',
    cloud_name='dhuti2qu7',

    # api_key='843839891244491',
    api_key='538825812971112',

    # api_secret='GUjP1I7lpjrig5Z7IXOF0WDzOyo'
    api_secret='HDbeJCSBUvoHhnyclj7aF_NW5a0'

)

local_folder_path = 'public/uploads'
cloudinary_folder_path = 'public/uploads'  # Change this to your Cloudinary folder path

def check_internet():
    try:
        # Try to make a request to a reliable server (e.g., Google's DNS server)
        response = requests.get('http://www.google.com', timeout=5)
        response.raise_for_status()  # Raise an error for bad responses (e.g., 404, 500)
        return True
    except requests.RequestException:
        return False

def upload_folder(local_folder, cloudinary_folder):
    # Check if the internet is available
    if not check_internet():
        print("You are offline. Cannot upload to Cloudinary.")
        return

    # Get the list of local files and folders
    local_items = os.listdir(local_folder)

    # Get the list of Cloudinary files and folders
    cloudinary_items = api.subfolders(cloudinary_folder)['folders']

    # Upload missing files and create missing folders on Cloudinary
    for item in local_items:
        item_path = os.path.join(local_folder, item)

        if os.path.isfile(item_path):
            # Check if the file exists on Cloudinary
            cloudinary_file_path = os.path.join(cloudinary_folder, item)
            if cloudinary_file_path not in cloudinary_items:
                upload_file(item_path, cloudinary_file_path)
        elif os.path.isdir(item_path):
            # Check if the folder exists on Cloudinary
            cloudinary_sub_folder_path = os.path.join(cloudinary_folder, item)
            if cloudinary_sub_folder_path not in cloudinary_items:
                create_folder(cloudinary_sub_folder_path)
                upload_folder(item_path, cloudinary_sub_folder_path)

def upload_file(local_path, cloudinary_path):
    # Use os.path.basename to get the filename without the path
    public_id = os.path.basename(local_path)

    # Combine the cloudinary_path and public_id to create the full public_id
    full_public_id = os.path.join(cloudinary_path)

    print(f'Checking if {full_public_id} exists on Cloudinary')

    try:
        # Check if the file exists on Cloudinary
        existing_file = api.resource(full_public_id, type="upload", resource_type="image")

        if not existing_file:
            print(f'Uploading {local_path} to {full_public_id}')
            try:
                uploader.upload(local_path, public_id=full_public_id)
            except cloudinary.exceptions.Error as e:
                print(f'Error uploading file: {e}')
        else:
            print(f'{full_public_id} already exists on Cloudinary. Skipped.')

    except cloudinary.exceptions.NotFound:
        # Handle the NotFound exception (resource doesn't exist on Cloudinary)
        print(f'{full_public_id} does not exist on Cloudinary. Uploading...')
        try:
            uploader.upload(local_path, public_id=full_public_id)
        except cloudinary.exceptions.Error as e:
            print(f'Error uploading file: {e}')

def create_folder(cloudinary_path):
    print(f'Creating folder {cloudinary_path} on Cloudinary')
    api.create_folder(cloudinary_path)

class MyHandler(FileSystemEventHandler):
    def on_created(self, event):
        if event.is_directory:
            self.sync_folder(event.src_path)

    def on_deleted(self, event):
        if event.is_directory:
            self.sync_folder(event.src_path)

    def on_modified(self, event):
        if event.is_directory:
            self.sync_folder(event.src_path)

    def sync_folder(self, local_folder):
        upload_folder(local_folder, cloudinary_folder_path)

if __name__ == "__main__":
    # Initialize the event handler and observer
    event_handler = MyHandler()
    observer = Observer()

    # Schedule the event handler to watch the local folder
    observer.schedule(event_handler, local_folder_path, recursive=True)

    print(f"Monitoring local folder: {local_folder_path}")

    # Start the observer
    observer.start()

    try:
        # Keep the script running
        while True:
            # Check for changes every minute
            time.sleep(60)
            upload_folder(local_folder_path, cloudinary_folder_path)
    except KeyboardInterrupt:
        # Stop the observer on keyboard interrupt
        observer.stop()
        print("Observer stopped.")
        observer.join()

