"""Work item operations for Azure DevOps integration."""

from datetime import datetime

from openhands.app_server.integrations.azure_devops.service.base import (
    AzureDevOpsMixinBase,
)
from openhands.app_server.integrations.service_types import Comment, RequestMethod
from openhands.app_server.utils.logger import openhands_logger as logger


class AzureDevOpsWorkItemsMixin(AzureDevOpsMixinBase):
    """Mixin for Azure DevOps work item operations.

    Work Items are unique to Azure DevOps and represent tasks, bugs, user stories, etc.
    in Azure Boards. This mixin provides methods to interact with work item comments.
    """

    def _truncate_comment(self, comment: str, max_length: int = 1000) -> str:
        """Truncate comment to max length."""
        if len(comment) <= max_length:
            return comment
        return comment[:max_length] + '...'

    async def add_work_item_comment(
        self, repository: str, work_item_id: int, comment_text: str
    ) -> dict:
        """Add a comment to an Azure DevOps work item.

        API Reference: https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/comments/add-comment

        Args:
            repository: Repository name in format "organization/project/repo" (project extracted)
            work_item_id: The work item ID
            comment_text: The comment text to post

        Returns:
            API response with created comment information

        Raises:
            HTTPException: If the API request fails
        """
        org, project, _ = self._parse_repository(repository)

        # URL-encode components to handle spaces and special characters
        org_enc = self._encode_url_component(org)
        project_enc = self._encode_url_component(project)

        url = f'{self.base_url}/{org_enc}/{project_enc}/_apis/wit/workItems/{work_item_id}/comments?api-version=7.1-preview.4'

        payload = {
            'text': comment_text,
        }

        response, _ = await self._make_request(
            url=url, params=payload, method=RequestMethod.POST
        )

        logger.info(f'Added comment to work item {work_item_id} in project {project}')
        return response

    async def get_work_item_comments(
        self, repository: str, work_item_id: int, max_comments: int = 100
    ) -> list[Comment]:
        """Get all comments from a work item.

        API Reference: https://learn.microsoft.com/en-us/rest/api/azure/devops/wit/comments/get-comments

        Args:
            repository: Repository name in format "organization/project/repo" (project extracted)
            work_item_id: The work item ID
            max_comments: Maximum number of comments to return

        Returns:
            List of Comment objects sorted by creation date
        """
        org, project, _ = self._parse_repository(repository)

        # URL-encode components to handle spaces and special characters
        org_enc = self._encode_url_component(org)
        project_enc = self._encode_url_component(project)

        url = f'{self.base_url}/{org_enc}/{project_enc}/_apis/wit/workItems/{work_item_id}/comments?api-version=7.1-preview.4'

        response, _ = await self._make_request(url)

        comments_data = response.get('comments', [])
        all_comments: list[Comment] = []

        for comment_data in comments_data:
            # Extract author information
            author_info = comment_data.get('createdBy', {})
            author = author_info.get('displayName', 'unknown')

            # Parse dates
            created_at = (
                datetime.fromisoformat(
                    comment_data.get('createdDate', '').replace('Z', '+00:00')
                )
                if comment_data.get('createdDate')
                else datetime.fromtimestamp(0)
            )

            modified_at = (
                datetime.fromisoformat(
                    comment_data.get('modifiedDate', '').replace('Z', '+00:00')
                )
                if comment_data.get('modifiedDate')
                else created_at
            )

            comment = Comment(
                id=str(comment_data.get('id', 0)),
                body=self._truncate_comment(comment_data.get('text', '')),
                author=author,
                created_at=created_at,
                updated_at=modified_at,
                system=False,
            )

            all_comments.append(comment)

        # Sort by creation date and limit
        all_comments.sort(key=lambda c: c.created_at)
        return all_comments[:max_comments]

    async def add_work_item_reaction(
        self, repository: str, work_item_id: int, reaction_type: str = ':thumbsup:'
    ) -> dict:
        comment_text = f'{reaction_type} OpenHands is processing this work item...'
        return await self.add_work_item_comment(repository, work_item_id, comment_text)
