"""Google Drive upload utility menggunakan OAuth2 token."""

import io
import logging
import mimetypes
import uuid

from app.core.config import settings

logger = logging.getLogger(__name__)

GDRIVE_SCOPES = ["https://www.googleapis.com/auth/drive"]


def _get_drive_service():
    """Build Google Drive API service menggunakan OAuth2 token dari file."""
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from googleapiclient.discovery import build

    token_path = settings.GDRIVE_TOKEN_PATH
    creds = Credentials.from_authorized_user_file(token_path, GDRIVE_SCOPES)

    if not creds.valid:
        if creds.expired and creds.refresh_token:
            creds.refresh(Request())
            with open(token_path, "w") as f:
                f.write(creds.to_json())
            logger.info("GDrive: access token di-refresh")
        else:
            raise RuntimeError(
                "Token tidak valid dan tidak bisa di-refresh. "
                "Jalankan ulang scripts/gdrive_oauth_setup.py"
            )

    return build("drive", "v3", credentials=creds)


def _get_or_create_subfolder(service, parent_id: str, folder_name: str) -> str:
    """Ambil folder ID berdasarkan nama, buat jika belum ada."""
    query = (
        f"name='{folder_name}' and "
        f"'{parent_id}' in parents and "
        f"mimeType='application/vnd.google-apps.folder' and "
        f"trashed=false"
    )
    results = service.files().list(q=query, fields="files(id)").execute()
    files = results.get("files", [])
    if files:
        return files[0]["id"]

    metadata = {
        "name": folder_name,
        "mimeType": "application/vnd.google-apps.folder",
        "parents": [parent_id],
    }
    folder = service.files().create(body=metadata, fields="id").execute()
    return folder["id"]


def gdrive_upload(
    file_bytes: bytes,
    unique_name: str,   # already formatted by save_upload
    spbu_code: str,
    tipe: str,
    env: str,           # "dev" | "live"
) -> str:
    """
    Upload file ke Google Drive.

    Struktur folder: {root}/{env}/{spbu_code}/{tipe}/
    Nama file: unique_name (sudah diformat oleh save_upload)

    Return: URL web view (https://drive.google.com/file/d/{id}/view)
    """
    from googleapiclient.http import MediaIoBaseUpload

    service = _get_drive_service()
    root_id = settings.GDRIVE_ROOT_FOLDER_ID

    folder_path = f"{env}/{spbu_code}/{tipe}"

    current_parent = root_id
    for part in folder_path.split("/"):
        current_parent = _get_or_create_subfolder(service, current_parent, part)

    mime_type, _ = mimetypes.guess_type(unique_name)
    mime_type = mime_type or "application/octet-stream"

    file_metadata = {
        "name": unique_name,
        "parents": [current_parent],
    }
    media = MediaIoBaseUpload(
        io.BytesIO(file_bytes),
        mimetype=mime_type,
        resumable=True,
    )
    uploaded = service.files().create(
        body=file_metadata,
        media_body=media,
        fields="id,webViewLink",
    ).execute()

    file_id = uploaded["id"]

    # Set permission agar bisa diakses via link (viewer)
    service.permissions().create(
        fileId=file_id,
        body={"type": "anyone", "role": "reader"},
    ).execute()

    url = f"https://drive.google.com/file/d/{file_id}/view"
    logger.info("GDrive: uploaded '%s' → %s", unique_name, url)
    return url


def gdrive_fetch(file_id: str) -> tuple[bytes, str]:
    """Download file bytes from Google Drive by file ID.

    Returns (content_bytes, mime_type).
    Raises RuntimeError if download fails.
    """
    from googleapiclient.http import MediaIoBaseDownload

    service = _get_drive_service()
    file_metadata = service.files().get(fileId=file_id, fields="mimeType").execute()
    content_type = file_metadata.get("mimeType", "application/octet-stream")

    request = service.files().get_media(fileId=file_id)
    fh = io.BytesIO()
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    while not done:
        _, done = downloader.next_chunk()
    return fh.getvalue(), content_type


def gdrive_delete(file_url: str) -> None:
    """Hapus file dari Google Drive berdasarkan web view URL."""
    try:
        # Extract file ID dari URL: https://drive.google.com/file/d/{id}/view
        file_id = file_url.split("/d/")[1].split("/")[0]
        service = _get_drive_service()
        service.files().delete(fileId=file_id).execute()
        logger.info("GDrive: deleted file_id '%s'", file_id)
    except Exception as e:
        logger.warning("GDrive: gagal delete '%s' — %s", file_url, e)
