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

"""Slack connector — send messages, list channels, upload files."""

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


@connector(
	id='slack',
	name='Slack',
	description='Send messages and interact with Slack workspaces',
	icon='comment-discussion',
	auth_type='api_key',
	auth_fields=[
		ConnectorParam(name='bot_token', type='string', label='Bot Token', required=True,
					   description='Slack Bot User OAuth Token (xoxb-...)'),
	],
)
class SlackConnector(BaseConnector):

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

	async def test_connection(self) -> bool:
		if not self._token:
			return False
		async with httpx.AsyncClient() as client:
			resp = await client.post(
				'https://slack.com/api/auth.test',
				headers={'Authorization': f'Bearer {self._token}'},
				timeout=10,
			)
			data = resp.json()
			return data.get('ok', False)

	@action(
		id='send_message',
		name='Send Message',
		description='Post a message to a Slack channel',
		params=[
			ConnectorParam(name='channel', type='string', required=True, label='Channel',
						   description='Channel ID or name (e.g. #general)'),
			ConnectorParam(name='text', type='string', required=True, label='Message Text'),
		],
	)
	async def send_message(self, channel: str = '', text: str = '', **kw: Any) -> dict[str, Any]:
		async with httpx.AsyncClient() as client:
			resp = await client.post(
				'https://slack.com/api/chat.postMessage',
				headers={'Authorization': f'Bearer {self._token}'},
				json={'channel': channel, 'text': text},
				timeout=15,
			)
			return resp.json()

	@action(
		id='list_channels',
		name='List Channels',
		description='List public channels in the workspace',
		params=[
			ConnectorParam(name='limit', type='number', default=100, label='Limit'),
		],
	)
	async def list_channels(self, limit: int = 100, **kw: Any) -> dict[str, Any]:
		async with httpx.AsyncClient() as client:
			resp = await client.get(
				'https://slack.com/api/conversations.list',
				headers={'Authorization': f'Bearer {self._token}'},
				params={'limit': limit, 'types': 'public_channel'},
				timeout=15,
			)
			return resp.json()

	@action(
		id='upload_file',
		name='Upload File',
		description='Upload a file to a Slack channel',
		params=[
			ConnectorParam(name='channel', type='string', required=True, label='Channel'),
			ConnectorParam(name='content', type='string', required=True, label='File Content'),
			ConnectorParam(name='filename', type='string', default='output.txt', label='Filename'),
		],
	)
	async def upload_file(self, channel: str = '', content: str = '', filename: str = 'output.txt', **kw: Any) -> dict[str, Any]:
		async with httpx.AsyncClient() as client:
			resp = await client.post(
				'https://slack.com/api/files.upload',
				headers={'Authorization': f'Bearer {self._token}'},
				data={'channels': channel, 'content': content, 'filename': filename},
				timeout=30,
			)
			return resp.json()
