"""
Google Sheets API client.

Isolated client that can run without FastAPI.
"""

from typing import Optional
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


class GoogleSheetsError(Exception):
    """Sheets API error."""
    pass


class GoogleSheetsClient:
    """
    Google Sheets API client.

    Provides methods to read spreadsheet data.
    """

    def __init__(self, credentials: Credentials):
        """
        Initialize Sheets client.

        Args:
            credentials: Google OAuth2 credentials
        """
        self.credentials = credentials
        self.service = build("sheets", "v4", credentials=credentials)

    def get_spreadsheet_metadata(self, spreadsheet_id: str) -> dict:
        """
        Get spreadsheet metadata (title, sheets, etc.).

        Args:
            spreadsheet_id: The spreadsheet ID

        Returns:
            Spreadsheet metadata
        """
        try:
            result = self.service.spreadsheets().get(
                spreadsheetId=spreadsheet_id
            ).execute()
            return result
        except HttpError as e:
            raise GoogleSheetsError(f"Failed to get spreadsheet: {e}")

    def get_sheet_values(
        self,
        spreadsheet_id: str,
        range_name: str,
        value_render_option: str = "FORMATTED_VALUE",
    ) -> list[list]:
        """
        Get values from a sheet range.

        Args:
            spreadsheet_id: The spreadsheet ID
            range_name: A1 notation range (e.g., 'Sheet1!A1:D10')
            value_render_option: How values should be rendered
                - FORMATTED_VALUE: Values formatted as strings (default)
                - UNFORMATTED_VALUE: Values in calculated format
                - FORMULA: Formulas

        Returns:
            List of rows, each row is a list of cell values
        """
        try:
            result = self.service.spreadsheets().values().get(
                spreadsheetId=spreadsheet_id,
                range=range_name,
                valueRenderOption=value_render_option,
            ).execute()
            return result.get("values", [])
        except HttpError as e:
            raise GoogleSheetsError(f"Failed to get values: {e}")

    def get_all_sheets(self, spreadsheet_id: str) -> list[dict]:
        """
        Get list of all sheets in a spreadsheet.

        Args:
            spreadsheet_id: The spreadsheet ID

        Returns:
            List of sheet metadata (title, id, index, etc.)
        """
        metadata = self.get_spreadsheet_metadata(spreadsheet_id)
        return [
            {
                "title": sheet["properties"]["title"],
                "sheet_id": sheet["properties"]["sheetId"],
                "index": sheet["properties"]["index"],
                "row_count": sheet["properties"]["gridProperties"].get("rowCount", 0),
                "column_count": sheet["properties"]["gridProperties"].get("columnCount", 0),
            }
            for sheet in metadata.get("sheets", [])
        ]

    def batch_get_values(
        self,
        spreadsheet_id: str,
        ranges: list[str],
        value_render_option: str = "FORMATTED_VALUE",
    ) -> dict:
        """
        Get multiple ranges in a single request.

        Args:
            spreadsheet_id: The spreadsheet ID
            ranges: List of A1 notation ranges
            value_render_option: How values should be rendered

        Returns:
            Dict with spreadsheetId and valueRanges list
        """
        try:
            result = self.service.spreadsheets().values().batchGet(
                spreadsheetId=spreadsheet_id,
                ranges=ranges,
                valueRenderOption=value_render_option,
            ).execute()
            return result
        except HttpError as e:
            raise GoogleSheetsError(f"Failed to batch get values: {e}")
