import requests
from pathlib import Path
import os
from dotenv import load_dotenv
import re
from fastapi import APIRouter

router = APIRouter()
load_dotenv()

ACCESS_TOKEN = os.getenv('DRIVE_ACCESS_TOKEN')
REFRESH_TOKEN = os.getenv('DRIVE_REFRESH_TOKEN')

# Allowed extensions and Google Docs types
ALLOWED_EXTENSIONS = {'.pdf', '.doc', '.docx', '.txt'}
GOOGLE_DOCS_MIME_TYPES = {
    'application/vnd.google-apps.document': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    # Add other Google Docs types and their corresponding export MIME types if needed
}

def extract_id_from_url(url):
    """
    Extracts and returns the Drive ID from the provided Google Drive URL.
    """
    print("extracting folder ", url)

    # Check if the URL is a string
    if not isinstance(url, str):
        print("Error: URL is not a string.")
        return None

    match = re.search(r'/folders/([a-zA-Z0-9_-]+)', url)
    print("matching folder ", match)
    return match.group(1) if match else None

def list_files_in_folder(access_token, folder_id):
    headers = {
        "Authorization": f"Bearer {access_token}"
    }
    params = {
        "q": f"'{folder_id}' in parents and trashed=false",
        "fields": "nextPageToken, files(id, name, mimeType)"
    }
    response = requests.get("https://www.googleapis.com/drive/v3/files", headers=headers, params=params)
    response.raise_for_status()
    file_list = response.json().get('files', [])
    return [(f['id'], f['name'], f['mimeType']) for f in file_list]

def download_file(access_token, file_id, file_name, download_path, mime_type):

    if not access_token:
        access_token = os.getenv('DRIVE_ACCESS_TOKEN')

    headers = {
        "Authorization": f"Bearer {access_token}"
    }
    
    # Check if it's a Google Docs file and adjust the download URL and filename
    if mime_type in GOOGLE_DOCS_MIME_TYPES:
        download_url = f"https://www.googleapis.com/drive/v3/files/{file_id}/export?mimeType={GOOGLE_DOCS_MIME_TYPES[mime_type]}"
        file_extension = Path(file_name).suffix
        file_name = f"{Path(file_name).stem}.docx" if file_extension == '' else file_name
    else:
        download_url = f"https://www.googleapis.com/drive/v3/files/{file_id}?alt=media"
    
    response = requests.get(download_url, headers=headers, stream=True)
    response.raise_for_status()
    
    with open(Path(download_path) / file_name, "wb") as file:
        for chunk in response.iter_content(chunk_size=32768):
            if chunk:
                file.write(chunk)
    print(f"File '{file_name}' downloaded successfully to '{download_path}'")


async def download_files(url, download_path,authCode):

    #access_token = refresh_access_token()
    #access_token = 'ya29.a0AfB_byDwCFKWl3fzhT1Vx8GG3aEUC854vPI3iGdOg-_f0VnWvmIeCapjssjLMIIo1u570uPwMO6H9Iq0WBCi1kRbnbSM0NlLW9wBroo64qMXziN5oYtvvyJVvX-XlXjCmVHrz-vDBuekbFwe72n8d5-u3kKMNvpPjOHaaCgYKAb0SARISFQHGX2MiitWdOAU7v86GCCe8V5vqXQ0171'
    print("inside the download_files")
    token_data = await exchange_code_for_tokens(authCode)
    access_token = token_data.get("access_token")
    
    download_path = Path(download_path)
    download_path.mkdir(parents=True, exist_ok=True)
    
    print("hello baby", access_token)
    try:
        drive_id = extract_id_from_url(url)
    except Exception as e:
        print(f"Error during extracting drive ID : {e}")

    print("drive ID", drive_id)
    if not drive_id:
        raise ValueError("Invalid Google Drive URL")
    
    # Determine if this is a folder or file via the Google Drive API.
    headers = {"Authorization": f"Bearer {access_token}"}
    response = requests.get(f"https://www.googleapis.com/drive/v3/files/{drive_id}", headers=headers)
    print( " Google Drive Auth respionse ", response)
    response.raise_for_status()
    
    file_or_folder = response.json()
    
    # If it's a folder, list and download the files inside it.
    if file_or_folder.get('mimeType') == 'application/vnd.google-apps.folder':
        files = list_files_in_folder(access_token, drive_id)
        for file_id, file_name, mime_type in files:
            if Path(file_name).suffix.lower() in ALLOWED_EXTENSIONS or mime_type in GOOGLE_DOCS_MIME_TYPES:
                download_file(access_token, file_id, file_name, download_path, mime_type)
    # If it's a file, just download it.
    elif file_or_folder.get('mimeType') in GOOGLE_DOCS_MIME_TYPES or Path(file_or_folder.get('name')).suffix.lower() in ALLOWED_EXTENSIONS:
        download_file(access_token, drive_id, file_or_folder.get('name'), download_path, file_or_folder.get('mimeType'))
    else:
        raise ValueError("The Google Drive link is neither a folder nor an allowed file type.")

#Use Code to generate Access token
async def exchange_code_for_tokens(code):

    client_id = os.getenv('GOOGLE_CLIENT_ID')
    client_secret = os.getenv('GOOGLE_CLIENT_SECRET')
    api_domain = os.getenv('MY_APP_DOMAIN')
    #refresh_token = os.getenv('DRIVE_REFRESH_TOKEN')
    redirect_uri = api_domain + '/google-callback'

    token_url = 'https://oauth2.googleapis.com/token'

    payload = {
        'code': code,
        'client_id': client_id,
        'client_secret': client_secret,
        'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code'
    }

    response = requests.post(token_url, data=payload)

    if response.ok:
        return response.json()  # Contains access_token and refresh_token
    else:
        return "NO"
    
#Use Refresh token to generate Access token
def refresh_access_token():
    client_id = os.getenv('GOOGLE_CLIENT_ID')
    client_secret = os.getenv('GOOGLE_CLIENT_SECRET')
    refresh_token = os.getenv('DRIVE_REFRESH_TOKEN')

    # Ensure all credentials are present
    if not client_id or not client_secret or not refresh_token:
        raise ValueError("Missing credentials for Google API.")

    # Define the parameters for the token refresh request
    params = {
        'grant_type': 'refresh_token',
        'client_id': client_id,
        'client_secret': client_secret,
        'refresh_token': refresh_token
    }

    # Make the request to Google's token endpoint
    #headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    token_response = requests.post('https://oauth2.googleapis.com/token', data=params ) #, headers=headers)


    # Check for errors
    if token_response.ok:
        # Parse the token response
        token_response_json = token_response.json()
        new_access_token = token_response_json.get('access_token')

        # Update the access token environment variable
        os.environ['DRIVE_ACCESS_TOKEN'] = new_access_token

        return new_access_token
    else:
        # Raise an error if the token refresh request failed
        raise requests.exceptions.HTTPError(f"Failed to refresh access token: {token_response.text}", response=token_response)



#exchange = exchange_code_for_tokens()
#print("Google Code - :: ", exchange)

# Example usage:
# Set up your download path
download_path = './downloaded_files'  # The path where you want the files to be downloaded

#https://developers.google.com/oauthplayground/?
# URLs
folder_url = "https://drive.google.com/drive/u/0/folders/1aI8QXZH6lRnzkVEjiAMWGwebSmVU-4m2"
file_url = "https://drive.google.com/file/d/1l4sqE9HFA6ni9BYu2OT9nl3ei3ho3PAE/view?usp=sharing"

# Call the function to download files or folder contents
#download_files(folder_url, download_path)  # For folder
# download_files(ACCESS_TOKEN, file_url, download_path)  # For file