import datetime
import logging

from requests import Response
from urllib.parse import urlparse, parse_qs

from .base import BaseClient
from watcher.config import settings
from watcher.logic.timezone import now

logger = logging.getLogger(__name__)


class ABCClient(BaseClient):

    TVM2_CLIENT = 'abc'
    X_UID_HEADER = True
    HOST = settings.ABC_API_HOST

    def _raise_for_status(self, response):
        if response.status_code == 409:
            # такая роль уже есть, все ок
            return
        if response.status_code == 403:
            # игнорируем такие ошибки
            logger.warning(f'Got 403 while {response.request.method} {response.request.url}')
            return
        return super()._raise_for_status(response=response)

    def _parse_urlargs(self, url):
        query = parse_qs(urlparse(url).query)
        return {k: v[0] if v and len(v) == 1 else v for k, v in query.items()}

    def request_role(self, service: int, login: str, role: int) -> Response:
        logger.info(f'Requesting role: {role} for: {login} in: {service}')
        return self._make_request(
            path='api/v4/services/members/',
            method='post',
            data={
                'service': service,
                'person': login,
                'role': role,
                'comment': 'Начало дежурства',
                'silent': True,
            }
        )

    def deprive_role(self, membership_id: int) -> Response:
        logger.info(f'Depriving role: {membership_id}')
        return self._make_request(
            path=f'api/frontend/services/members/{membership_id}/',
            method='delete',
        )

    def get_schedule(self, schedule_id: int, fields: str = None) -> Response:
        params = {
            'fields': fields,
        }
        response = self._make_request(
            path=f'api/v4/duty/schedules/{schedule_id}/',
            method='get',
            params=params
        )
        return response.json()

    def patch_schedule(self, schedule_id: int, data: dict = None) -> Response:
        return self._make_request(
            path=f'api/v4/duty/schedules/{schedule_id}/',
            method='patch',
            data=data,
        )

    def delete_schedule(self, schedule_id: int) -> Response:
        logger.info(f'deleting abc schedule: {schedule_id}')
        return self._make_request(
            path=f'api/v4/duty/schedules/{schedule_id}/',
            method='delete',
        )

    def get_schedules(self, service_id: int, fields: str = None) -> list:
        result = []
        params = {
            'service': service_id,
            'fields': fields if fields else 'slug',
            'page_size': 10
        }
        has_next = True
        while has_next:
            response = self._make_request(
                path='api/v4/duty/schedules/',
                params=params,
                method='get',
            )
            response_data = response.json()
            result.extend(response_data['results'])
            url = response_data.get('next')
            if not url:
                has_next = False
            else:
                params = self._parse_urlargs(url)
        return result

    def get_shifts(self, schedule_id: int, fields: str = None) -> list:
        result = []
        date_to = now() + datetime.timedelta(days=settings.ABC_MIGRATION_SHIFT_END_DATE_DELTA)
        params = {
            'schedule': str(schedule_id),
            'date_from': settings.ABC_MIGRATION_SHIFT_START_DATE,
            'date_to': date_to.strftime('%Y-%m-%d'),
            'fields': fields if fields else 'id,person,start_datetime,end_datetime,is_approved',
            'ordering': 'start_datetime'
        }
        has_next = True
        while has_next:
            response = self._make_request(
                path='api/v4/duty/shifts/',
                params=params,
                method='get',
            )
            response_data = response.json()
            result.extend(response_data['results'])
            url = response_data.get('next')
            if not url:
                has_next = False
            else:
                params = self._parse_urlargs(url)
        return result

    def create_duty_to_watcher_link(self, abc_id: int, watcher_id: int) -> None:
        self._make_request(
            path='api/v4/duty/abc_to_watcher/',
            method='post',
            data={
                'abc_id': abc_id,
                'watcher_id': watcher_id,
            }
        )


abc_client = ABCClient()
