# Copyright (c) DevSecCode. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root.

"""Google Sheets connector — read/write spreadsheet data."""

from __future__ import annotations

from typing import Any

import httpx

from dsc_api.connectors.base import BaseConnector, ConnectorParam
from dsc_api.connectors.sdk import connector, action

_SHEETS_API = 'https://sheets.googleapis.com/v4/spreadsheets'


@connector(
	id='google_sheets',
	name='Google Sheets',
	description='Read and write Google Sheets data',
	icon='table',
	auth_type='api_key',
	auth_fields=[
		ConnectorParam(name='api_key', type='string', label='API Key', required=True,
					   description='Google API key with Sheets access'),
	],
)
class GoogleSheetsConnector(BaseConnector):

	@property
	def _key(self) -> str:
		return self._credentials.get('api_key', '')

	async def test_connection(self) -> bool:
		return bool(self._key)

	@action(
		id='read_range',
		name='Read Range',
		description='Read values from a spreadsheet range',
		params=[
			ConnectorParam(name='spreadsheet_id', type='string', required=True, label='Spreadsheet ID'),
			ConnectorParam(name='range', type='string', required=True, label='Range', default='Sheet1!A1:Z100'),
		],
	)
	async def read_range(self, spreadsheet_id: str = '', range: str = 'Sheet1!A1:Z100', **kw: Any) -> dict[str, Any]:
		async with httpx.AsyncClient() as client:
			resp = await client.get(
				f'{_SHEETS_API}/{spreadsheet_id}/values/{range}',
				params={'key': self._key},
				timeout=15,
			)
			resp.raise_for_status()
			return resp.json()

	@action(
		id='write_range',
		name='Write Range',
		description='Write values to a spreadsheet range',
		params=[
			ConnectorParam(name='spreadsheet_id', type='string', required=True, label='Spreadsheet ID'),
			ConnectorParam(name='range', type='string', required=True, label='Range', default='Sheet1!A1'),
			ConnectorParam(name='values', type='json', required=True, label='Values',
						   description='2D array of values as JSON'),
		],
	)
	async def write_range(self, spreadsheet_id: str = '', range: str = 'Sheet1!A1', values: Any = None, **kw: Any) -> dict[str, Any]:
		import json
		if isinstance(values, str):
			values = json.loads(values)
		async with httpx.AsyncClient() as client:
			resp = await client.put(
				f'{_SHEETS_API}/{spreadsheet_id}/values/{range}',
				params={'key': self._key, 'valueInputOption': 'USER_ENTERED'},
				json={'values': values},
				timeout=15,
			)
			resp.raise_for_status()
			return resp.json()

	@action(
		id='append_row',
		name='Append Row',
		description='Append a row to the end of a sheet',
		params=[
			ConnectorParam(name='spreadsheet_id', type='string', required=True, label='Spreadsheet ID'),
			ConnectorParam(name='range', type='string', required=True, label='Sheet Name', default='Sheet1'),
			ConnectorParam(name='values', type='json', required=True, label='Row Values',
						   description='Array of values for the row'),
		],
	)
	async def append_row(self, spreadsheet_id: str = '', range: str = 'Sheet1', values: Any = None, **kw: Any) -> dict[str, Any]:
		import json
		if isinstance(values, str):
			values = json.loads(values)
		if not isinstance(values[0], list):
			values = [values]
		async with httpx.AsyncClient() as client:
			resp = await client.post(
				f'{_SHEETS_API}/{spreadsheet_id}/values/{range}:append',
				params={'key': self._key, 'valueInputOption': 'USER_ENTERED', 'insertDataOption': 'INSERT_ROWS'},
				json={'values': values},
				timeout=15,
			)
			resp.raise_for_status()
			return resp.json()
