from typing import Any, Dict
from urllib.parse import ParseResult, urlencode

from django.core.urlresolvers import reverse
from django.conf import settings

from staff.dismissal.objects import DismissalCtl, DISMISSAL_TYPE
from staff.dismissal.services import DismissalService
from staff.keys.models import SSHKey
from staff.person_profile.permissions.base import BaseRegistry


FEEDBACK_HOST = '%s/?persons={}' % settings.FEEDBACK_HOST
UPRAVLYATOR_HOST = '%s/user/{}' % settings.UPRAVLYATOR_HOST
ML_FRONT_HOST = '//%s/~{}' % settings.ML_FRONT_HOST
LOGIN_LINKER_HOST = '//%s' % settings.LOGIN_LINKER_HOST
CABINET_LINK = '//%s/user/{}' % settings.CABINET_HOST


class LinksGenerator(object):
    def __init__(self, person_data: Dict[str, Any], registry: BaseRegistry):
        self.person_id = person_data['id']
        self.person_login = person_data['login']
        self.person_data = person_data
        self.registry = registry

    def get_links(self) -> Dict:
        result = {}
        for link_name in self.registry.get_links(self.person_login):
            link = getattr(self, f'{link_name}_link')()
            if link is not None:
                result[link_name] = link

        return result

    @property
    def _person_props(self):
        return self.registry.properties

    def _link_info(self, url, method='GET', need_confirm=False, **additional_kw):
        return dict(
            url=url,
            method=method,
            need_confirm=need_confirm,
            **additional_kw
        )

    def salary_link(self):
        return self._link_info(
            f'/wish-form/?login={self.person_login}&buttons=salary|grade|comment'
        )

    def feedback_link(self):
        if not self._person_props.is_owner(self.person_login):
            return self._link_info(FEEDBACK_HOST.format(self.person_id))

    def yamb_link(self):
        return self._link_info(
            url=f'https://q.yandex-team.ru/#/staff/{self.person_login}'
        )

    def slack_link(self):
        return self._link_info(
            url=ParseResult(
                scheme='https',
                netloc=settings.SLACK_HOST,
                path='/ya-admin/redirect-to-dm',
                query=urlencode({'username': self.person_login}),
                params='',
                fragment='',
            ).geturl(),
        )

    def dismiss_create_link(self):
        is_dismissed = self._person_props.is_dismissed(self.person_login)
        is_memorial = self._person_props.is_memorial(self.person_login)
        if is_dismissed and is_memorial:
            return None

        dismissal = DismissalCtl().get(self.person_id)
        if dismissal is None:
            dismissal_procedure_exists = (
                DismissalService.exists_dismissal_procedure(self.person_data)
            )

            if dismissal_procedure_exists:
                return self._link_info(
                    url='/dismissal/{}/'.format(self.person_login),
                    need_confirm=True,
                    type=DISMISSAL_TYPE.FULL,
                )
            else:
                return self._link_info(
                    url=reverse(
                        'dismissal-api:create',
                        kwargs={'login': self.person_login},
                    ),
                    method='POST',
                    need_confirm=True,
                    type=DISMISSAL_TYPE.SHORT,
                )

    def dismiss_edit_link(self):
        is_dismissed = self._person_props.is_dismissed(self.person_login)
        is_memorial = self._person_props.is_memorial(self.person_login)
        if is_dismissed and is_memorial:
            return None
        dismissal = DismissalCtl().get(self.person_id)
        if dismissal:
            return self._link_info(url=reverse('dismissal-edit', args=(dismissal.pk,)))

    def order_card_link(self):
        return self._link_info('https://forms.yandex-team.ru/surveys/56972/')

    def revoke_ssh_link(self):
        if not SSHKey.objects.filter(staff_id=self.person_id).exists():
            return None

        return self._link_info(
            url=reverse('keys:revoke-ssh-keys', kwargs={'login': self.person_login}),
            method='POST',
            need_confirm=True,
        )

    def add_external_login_link(self):
        # звездочка позволяет после редиректа из oauth понять, что запрос из staff
        return self._link_info(
            LOGIN_LINKER_HOST + '/begin/*%s/' % self.person_login
        )

    def delete_external_login_link(self):
        # звездочка позволяет после редиректа из oauth понять, что запрос из staff
        return self._link_info(
            LOGIN_LINKER_HOST + '/unlink/*%s/' % self.person_login,
            method='POST',
            need_confirm=True,
        )

    def delete_all_photos_link(self):
        return self._link_info(
            url=reverse('profile:delete-all-photos', kwargs={'login': self.person_login}),
            method='DELETE',
            need_confirm=True,
        )

    def upravlyator_link(self):
        return self._link_info(UPRAVLYATOR_HOST.format(self.person_login))

    def cabinet_link(self):
        return self._link_info(CABINET_LINK.format(self.person_login))

    def ml_link(self):
        return self._link_info(ML_FRONT_HOST.format(self.person_login))

    def finances_link(self):
        return self._link_info('')

    def fincab_link(self):
        return self._link_info(reverse('anketa-money', kwargs={'yandex_login': self.person_login}))
