"""Google Drive 업로드 모듈"""

import logging
import re
from typing import Optional

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaInMemoryUpload

from . import config

logger = logging.getLogger(__name__)


def _get_drive_service():
    """OAuth2 인증으로 Drive 서비스 생성"""
    creds = Credentials(
        token=None,
        refresh_token=config.DRIVE_REFRESH_TOKEN,
        client_id=config.DRIVE_CLIENT_ID,
        client_secret=config.DRIVE_CLIENT_SECRET,
        token_uri="https://oauth2.googleapis.com/token",
    )
    return build("drive", "v3", credentials=creds)


def _find_or_create_folder(service, parent_id: str, folder_name: str) -> str:
    """폴더 찾기 또는 생성"""
    query = (
        f"'{parent_id}' in parents and name='{folder_name}'"
        " and mimeType='application/vnd.google-apps.folder' and trashed=false"
    )
    results = service.files().list(q=query, fields="files(id)", pageSize=1).execute()
    files = results.get("files", [])
    if files:
        return files[0]["id"]

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


def _safe_filename(title: str) -> str:
    """파일명에 사용할 수 없는 문자 제거"""
    return re.sub(r'[/\\:*?"<>|]', "_", title)[:50]


def upload_markdown(
    content: str,
    channel_name: str,
    video_title: str,
    video_date: str,
    suffix: str = "",  # '_요약' 또는 '_전사'
) -> str:
    """마크다운 파일을 Drive에 업로드하고 webViewLink 반환"""
    service = _get_drive_service()
    root_id = config.DRIVE_ROOT_FOLDER_ID

    # 04_유튜브요약/{채널명}/ 폴더 구조
    youtube_folder_id = _find_or_create_folder(service, root_id, "04_유튜브요약")
    channel_folder_id = _find_or_create_folder(service, youtube_folder_id, channel_name)

    safe_title = _safe_filename(video_title)
    file_name = f"{video_date}_{safe_title}{suffix}.md"

    # 중복 방지: 동일 파일명 존재 시 기존 URL 반환
    query = f"'{channel_folder_id}' in parents and name='{file_name}' and trashed=false"
    existing = (
        service.files()
        .list(q=query, fields="files(id,webViewLink)", pageSize=1)
        .execute()
    )
    existing_files = existing.get("files", [])
    if existing_files:
        logger.info("Drive 중복 파일 스킵: %s", file_name)
        return existing_files[0].get("webViewLink", existing_files[0]["id"])

    media = MediaInMemoryUpload(content.encode("utf-8"), mimetype="text/plain")
    file_metadata = {
        "name": file_name,
        "mimeType": "text/plain",
        "parents": [channel_folder_id],
    }
    result = (
        service.files()
        .create(body=file_metadata, media_body=media, fields="id,webViewLink")
        .execute()
    )

    url = result.get("webViewLink", result.get("id", ""))
    logger.info("Drive 업로드 완료: %s → %s", file_name, url)
    return url


def build_summary_markdown(
    summary: str,
    title: str,
    channel_name: str,
    video_id: str,
    published_at: str,
    duration: str,
    transcription_source: str,
    transcript_length: int,
) -> str:
    """요약 마크다운 문서 생성"""
    return f"""# {title}

- **채널**: {channel_name}
- **영상 ID**: {video_id}
- **게시일**: {published_at[:10]}
- **길이**: {duration}
- **전사 방식**: {transcription_source}
- **전사 길이**: {transcript_length:,}자
- **요약 생성**: Gemini 2.5 Flash

---

{summary}
"""


def build_transcript_markdown(
    transcript: str,
    title: str,
    channel_name: str,
    video_id: str,
    published_at: str,
    duration: str,
    transcription_source: str,
) -> str:
    """전사 원문 마크다운 문서 생성"""
    return f"""# {title} — 전사 원문

- **채널**: {channel_name}
- **영상 ID**: {video_id}
- **게시일**: {published_at[:10]}
- **길이**: {duration}
- **전사 방식**: {transcription_source}

---

{transcript}
"""


def upload_processing_log(log_content: str, date_str: str) -> str:
    """처리 로그를 Drive에 업로드"""
    service = _get_drive_service()
    root_id = config.DRIVE_ROOT_FOLDER_ID

    youtube_folder_id = _find_or_create_folder(service, root_id, "04_유튜브요약")
    log_folder_id = _find_or_create_folder(service, youtube_folder_id, "_처리로그")

    file_name = f"{date_str}_크롤링로그.md"
    media = MediaInMemoryUpload(log_content.encode("utf-8"), mimetype="text/plain")
    file_metadata = {
        "name": file_name,
        "mimeType": "text/plain",
        "parents": [log_folder_id],
    }
    result = (
        service.files()
        .create(body=file_metadata, media_body=media, fields="id,webViewLink")
        .execute()
    )
    return result.get("webViewLink", result.get("id", ""))
