"""Google Drive cloud storage provider."""

import os
import json
from typing import Optional, List
from pathlib import Path

from .base import CloudProvider, CloudFile, get_content_type


class GoogleDriveProvider(CloudProvider):
    """
    Google Drive storage provider.

    Requires google-api-python-client and google-auth-oauthlib packages.
    """

    def __init__(self):
        self._service = None
        self._credentials = None
        self._folder_id = None  # Whisper Scribe folder in Drive

    @property
    def name(self) -> str:
        return "google_drive"

    @property
    def display_name(self) -> str:
        return "Google Drive"

    def is_authenticated(self) -> bool:
        return self._service is not None

    async def authenticate(self, credentials: dict) -> bool:
        """
        Authenticate with Google Drive using OAuth credentials.

        credentials should contain:
        - token: OAuth access token (from OAuth flow)
        - refresh_token: OAuth refresh token
        - client_id: OAuth client ID
        - client_secret: OAuth client secret

        Or for service account:
        - service_account_json: Path to service account JSON file
        """
        try:
            from google.oauth2.credentials import Credentials
            from google.oauth2 import service_account
            from googleapiclient.discovery import build

            if 'service_account_json' in credentials:
                # Service account authentication
                scopes = ['https://www.googleapis.com/auth/drive.file']
                creds = service_account.Credentials.from_service_account_file(
                    credentials['service_account_json'],
                    scopes=scopes
                )
            else:
                # OAuth credentials
                creds = Credentials(
                    token=credentials.get('token'),
                    refresh_token=credentials.get('refresh_token'),
                    client_id=credentials.get('client_id'),
                    client_secret=credentials.get('client_secret'),
                    token_uri='https://oauth2.googleapis.com/token'
                )

            self._service = build('drive', 'v3', credentials=creds)
            self._credentials = credentials

            # Create or get Whisper Scribe folder
            await self._ensure_folder()

            return True

        except ImportError:
            raise ImportError(
                "Google Drive support requires: pip install google-api-python-client google-auth-oauthlib"
            )
        except Exception as e:
            print(f"Google Drive auth failed: {e}")
            return False

    async def _ensure_folder(self):
        """Create or get the Whisper Scribe folder."""
        folder_name = "Whisper Scribe Transcriptions"

        # Search for existing folder
        results = self._service.files().list(
            q=f"name='{folder_name}' and mimeType='application/vnd.google-apps.folder' and trashed=false",
            spaces='drive',
            fields='files(id, name)'
        ).execute()

        files = results.get('files', [])
        if files:
            self._folder_id = files[0]['id']
        else:
            # Create folder
            file_metadata = {
                'name': folder_name,
                'mimeType': 'application/vnd.google-apps.folder'
            }
            folder = self._service.files().create(
                body=file_metadata,
                fields='id'
            ).execute()
            self._folder_id = folder['id']

    async def upload_file(
        self,
        file_path: str,
        cloud_path: str = None,
        content_type: str = None
    ) -> CloudFile:
        """Upload a local file to Google Drive."""
        if not self.is_authenticated():
            raise Exception("Not authenticated with Google Drive")

        from googleapiclient.http import MediaFileUpload

        path = Path(file_path)
        filename = cloud_path or path.name
        mime_type = content_type or get_content_type(str(path))

        file_metadata = {
            'name': filename,
            'parents': [self._folder_id] if self._folder_id else []
        }

        media = MediaFileUpload(
            file_path,
            mimetype=mime_type,
            resumable=True
        )

        file = self._service.files().create(
            body=file_metadata,
            media_body=media,
            fields='id, name, size, mimeType, webViewLink'
        ).execute()

        return CloudFile(
            id=file['id'],
            name=file['name'],
            path=f"/{filename}",
            size=int(file.get('size', 0)),
            mime_type=file.get('mimeType', mime_type),
            web_link=file.get('webViewLink')
        )

    async def upload_content(
        self,
        content: bytes,
        filename: str,
        cloud_path: str = None,
        content_type: str = None
    ) -> CloudFile:
        """Upload content directly to Google Drive."""
        if not self.is_authenticated():
            raise Exception("Not authenticated with Google Drive")

        from googleapiclient.http import MediaInMemoryUpload

        dest_name = cloud_path or filename
        mime_type = content_type or get_content_type(filename)

        file_metadata = {
            'name': dest_name,
            'parents': [self._folder_id] if self._folder_id else []
        }

        media = MediaInMemoryUpload(
            content,
            mimetype=mime_type,
            resumable=True
        )

        file = self._service.files().create(
            body=file_metadata,
            media_body=media,
            fields='id, name, size, mimeType, webViewLink'
        ).execute()

        return CloudFile(
            id=file['id'],
            name=file['name'],
            path=f"/{dest_name}",
            size=len(content),
            mime_type=mime_type,
            web_link=file.get('webViewLink')
        )

    async def list_files(self, folder_path: str = None) -> List[CloudFile]:
        """List files in the Whisper Scribe folder."""
        if not self.is_authenticated():
            raise Exception("Not authenticated with Google Drive")

        query = "trashed=false"
        if self._folder_id:
            query = f"'{self._folder_id}' in parents and {query}"

        results = self._service.files().list(
            q=query,
            pageSize=100,
            fields='files(id, name, size, mimeType, webViewLink)'
        ).execute()

        files = []
        for f in results.get('files', []):
            files.append(CloudFile(
                id=f['id'],
                name=f['name'],
                path=f"/{f['name']}",
                size=int(f.get('size', 0)),
                mime_type=f.get('mimeType', ''),
                web_link=f.get('webViewLink')
            ))

        return files

    async def delete_file(self, file_id: str) -> bool:
        """Delete a file from Google Drive."""
        if not self.is_authenticated():
            raise Exception("Not authenticated with Google Drive")

        try:
            self._service.files().delete(fileId=file_id).execute()
            return True
        except Exception:
            return False

    async def get_share_link(self, file_id: str) -> str:
        """Get a shareable link for a file."""
        if not self.is_authenticated():
            raise Exception("Not authenticated with Google Drive")

        # Make file readable by anyone with link
        permission = {
            'type': 'anyone',
            'role': 'reader'
        }
        self._service.permissions().create(
            fileId=file_id,
            body=permission
        ).execute()

        # Get the web link
        file = self._service.files().get(
            fileId=file_id,
            fields='webViewLink'
        ).execute()

        return file.get('webViewLink', '')
