# -*- coding: utf-8 -*-
import json
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__ = [
    'StabilityView'
]


STABILITY_LOG_TAG = 'stability_value_request'


# TODO: Update schema for stability
# input_schema = {
#     "description": "DataCloud score API query",
#     "id": "score_request",
#     "properties": {
#         "response_ids": {
#           "type": "object",
#           "properties": {
#               "external_id": {
#                   "type": "string"
#               },
#               "request_id": {
#                   "type": "string"
#               }
#           }
#         },
#         "user_ids": {
#             "type": "object",
#             "properties": {
#                 "external_id": {
#                     "type": "string"
#                 },
#                 "phones": {
#                     "type": "array",
#                     "items": {
#                         "type": "object",
#                         "properties": {
#                             "id_value": {
#                                 "type": "string"
#                             },
#                             "phone": {
#                                 "type": "string"
#                             }
#                         }
#                     }
#                 },
#                 "emails": {
#                     "type": "array",
#                     "items": {
#                         "type": "object",
#                         "properties": {
#                             "id_value": {
#                                 "type": "string"
#                             },
#                             "email": {
#                                 "type": "string"
#                             }
#                         }
#                     }
#                 },
#                 "cookies": {
#                     "type": "array",
#                     "items": {
#                         "type": "object",
#                         "properties": {
#                             "cookie": {
#                                 "type": "string"
#                             },
#                             "cookie_vendor": {
#                                 "type": "string"
#                             }
#                         },
#                         "required": [
#                             "cookie",
#                             "cookie_vendor"
#                         ]
#                     }
#                 }
#             }
#         },
#         "scores": {
#             "type": "array",
#             "items": {
#                 "type": "object",
#                 "properties": {
#                     "score_name": {
#                         "type": "string"
#                     }
#                 },
#                 "required": ["score_name"]
#             }
#         }
#     },
#     "required": [
#         "user_ids",
#         "scores"
#     ]
# }


output_schema = {
    "description": "DataCloud stability API response",
    "id": "score_response",
    "properties": {
        "status": {
            "type": "string",
        },
        "stability_bins": {
            "type": "array"
        }
    },
    "required": ["status"]
}


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


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

    # request_body_schema = input_schema
    # request_body_required = True
    request_body_required = False
    args_schema = None
    result_schema = output_schema

    permissions = {'partner_read'}

    def __init__(self, ydb_manager, connection_params, ydb_root_dir, stability_storage, *args, **kwargs):
        """
        Params:
        """
        super(StabilityView, self).__init__(**kwargs)
        self._connection_params = connection_params
        self._ydb_manager = ydb_manager
        self._ydb_root_dir = ydb_root_dir
        self._stability_storage = stability_storage

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

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

    def _process(self, partner_id):
        date = g.args.get('date', '')
        request_body = g.request_body

        with log_context(partner_id=partner_id, query=request_body, user=current_user.id):
            try:
                date = g.args.get('date', '')  # get date from url ?date=
                if not date:  # get date from json params
                    date = request_body.get('date', '')
                score_id = request_body.get('score_id', '')
                if partner_id == 'tcs' and not score_id:  # hach to return score for tcs if no score is set
                    score_id = 'tcs_xprod_987_20181212'
                segment = request_body.get('stability_segment', 'daily')
                stability = self._get_stability_value(date, partner_id, score_id, segment)
                if stability:
                    stability = json.loads(stability)
            except Exception as e:  # noqa
                with log_context(tag=STABILITY_LOG_TAG, success=False):
                    logger.info('stability request processing fail')
                raise
            if stability:
                response = {
                    'status': 'done',
                    'stability_bins': stability
                }
            else:
                response = {
                    'status': 'wrong_request'
                }
            with log_context(tag=STABILITY_LOG_TAG, success=True, response=response):
                logger.info('stability requested by %s', current_user.id)
            return response

    def _get_stability_value(self, date, partner_id, score_id, segment):
        # YDB can not work with Unicode
        partner_id = str(partner_id)
        score_id = str(score_id)
        date = str(date)
        segment = str(segment)
        return self._stability_storage.get_stability(date, partner_id, score_id, segment)
