# -*- coding: utf-8 -*-
import logging
from ylog.context import log_context
from flask import g
from flask_login import current_user

from datacloud.score_api.validators.validators import Partner
from datacloud.score_api.server.blueprints.views import ApiView

from collections import namedtuple


logger = logging.getLogger(__name__)


__all__ = [
    'RejectRequestView'
]


REJECT_LOG_TAG = 'reject_value_request'


input_schema = {
    "description": "DataCloud reject API query",
    "id": "reject_request",
    "properties": {
        "score_name": {
            "type": "string"
        },
        "request_id": {
            "type": "string"
        },
        "timestamp": {
            "type": "integer"
        },
        "external_pid": {  # Just alias to score_name for some partners (equifax)
            "type": "string"
        },
    },
    "required": [
        "request_id",
        "timestamp"
    ]
}


# TODO: просто возвращать 200
output_schema = {
    # "description": "DataCloud stability API response",
    # "id": "score_response",
    # "properties": {
    #     "status": {
    #         "type": "string",
    #     },
    #     "stability_bins": {
    #         "type": "object"
    #     }
    # },
    # "required": ["status"]
}


ScoreValue = namedtuple('ScoreValue', 'name value')


class RejectRequestView(ApiView):
    """
    View for reading score values
    """
    params_schema = {
        'partner_id': Partner,
    }

    request_body_schema = input_schema
    request_body_required = True
    result_schema = output_schema

    permissions = {'partner_read'}

    def __init__(self, ydb_manager, connection_params, ydb_root_dir, reject_storage, *args, **kwargs):
        """
        Params:
        """
        super(RejectRequestView, self).__init__(**kwargs)
        self._connection_params = connection_params
        self._ydb_manager = ydb_manager
        self._ydb_root_dir = ydb_root_dir
        self._reject_storage = reject_storage

    def post(self, partner_id):
        return self._process(partner_id)

    def _process(self, partner_id):
        request_body = g.request_body

        request_id = request_body.get('request_id')
        request_timestamp = request_body.get('timestamp')
        score_id = request_body.get('score_name', None)
        external_pid = request_body.get('external_pid', None)

        if external_pid is not None:  # external_pid is just alias for score_id for some partners
            score_id = external_pid
        if score_id is None:
            response = {'error': 'Please provide score_id or external_pid'}
            with log_context(tag=REJECT_LOG_TAG, success=True, response=response):
                logger.info('Failed /reject request, no score_id or external_pid provided.', current_user.id)
            return response, 400

        with log_context(partner_id=partner_id, query=request_body, user=current_user.id):
            try:
                self._reject_request(partner_id, score_id, request_id, request_timestamp)
            except Exception as e:  # noqa
                with log_context(tag=REJECT_LOG_TAG, success=False):
                    logger.info('score request reject processing fail')
                raise
            response = {'status': 'done'}
            with log_context(tag=REJECT_LOG_TAG, success=True, response=response):
                logger.info('score request rejected by %s', current_user.id)
            return response

    def _reject_request(self, partner_id, score_id, request_id, request_timestamp):
        # YDB can not work with Unicode
        partner_id = str(partner_id)
        score_id = str(score_id)
        request_id = str(request_id)
        return self._reject_storage.reject_request(partner_id, score_id, request_id, request_timestamp)
