"""Views for the Trello integration."""

from __future__ import annotations

import json
import logging
from typing import TYPE_CHECKING
from urllib.parse import urlencode
from urllib.request import urlopen

from django.http import HttpResponse
from django.views.generic import View
from reviewboard.integrations.base import get_integration_manager
from reviewboard.reviews.views import ReviewRequestViewMixin

from rbintegrations.util.compat.logs import log_timed

if TYPE_CHECKING:
    from django.http import HttpRequest


logger = logging.getLogger(__name__)


class TrelloCardSearchView(ReviewRequestViewMixin, View):
    """The view to search for Trello cards (for use with auto-complete)."""

    def get(
        self,
        request: HttpRequest,
        **kwargs,
    ) -> HttpResponse:
        """Perform a search for cards.

        Args:
            request (django.http.HttpRequest):
                The request.

            **kwargs (dict):
                Additional keyword arguments.

        Returns:
            django.http.HttpResponse:
            A response containing JSON with a list of cards matching the
            search criteria.
        """
        from rbintegrations.trello.integration import TrelloIntegration

        integration_manager = get_integration_manager()
        integration = integration_manager.get_integration(
            TrelloIntegration.integration_id)

        configs = (
            config
            for config in integration.get_configs(
                self.review_request.local_site)
            if config.match_conditions(form_cls=integration.config_form_cls,
                                       review_request=self.review_request)
        )

        results = []

        query = request.GET.get('q')

        if not query:
            return HttpResponse(json.dumps([]),
                                content_type='application/json')

        params = {
            'card_board': 'true',
            'card_fields': 'id,name,shortUrl',
            'card_list': 'true',
            'cards_limit': 20,
            'modelTypes': 'cards',
            'partial': 'true',
            'query': query,
        }

        for config in configs:
            params['key'] = config.settings['trello_api_key']
            params['token'] = config.settings['trello_api_token']

            url = 'https://api.trello.com/1/search?%s' % urlencode(params)

            with log_timed(f'Fetching Trello cards at {url}',
                           logger=logger,
                           request=request) as log_timer:
                try:
                    response = urlopen(url)
                    data = json.loads(response.read())

                    for card in data['cards']:
                        results.append({
                            'id': card['id'],
                            'name': card['name'],
                            'board': card.get('board', {}).get('name', ''),
                            'list': card.get('list', {}).get('name', ''),
                            'url': card['shortUrl'],
                        })
                except Exception as e:
                    logger.exception('[%s] Unexpected error when searching '
                                     'for Trello cards: %s',
                                     log_timer.trace_id, e)

        return HttpResponse(json.dumps(results),
                            content_type='application/json')
