from Blueprints.BaseRequestParser import base_parser, handle_request
from Rest.ChannelsREST import ChannelsREST
from flask_restx import Resource, Namespace
from Rest.Answer import message_response_model
from Blueprints.APIModels import a_post, post_a_post_content, a_channel, post_channels_ids, post_a_reaction

api = Namespace('Channel', path='/channels/', description='Channel and Post related Operations')

channel_parser = base_parser.copy()
channel_parser.add_argument('channel_id', location='args', required=True)

get_parser = channel_parser.copy()
get_parser.add_argument('last_post_id', location='args')
get_parser.add_argument('limit', location='args', type=int)

get_main_channel_parser = base_parser.copy()
get_main_channel_parser.add_argument('last_post_id', location='args')
get_main_channel_parser.add_argument('limit', location='args', type=int)

delete_parser = base_parser.copy()
delete_parser.add_argument('post_id', location='args', type=str, required=True)

a_post_response = message_response_model(a_post)
a_post_response_single = message_response_model(a_post, single=True)

a_channel_response = message_response_model(a_channel)
a_channel_response_single = message_response_model(a_channel, single=True)

normal_post_mask = """
message,
result{
    id,
    author_id,
    date_created,
    author_display_name,
    author_username,
    author_profile_pic_id,
    rank,
    content,
    linked_user,
    is_self,
    blocked,
    anonymous,
    reactions,
    image_id,
    tags,
    comment_channel_id,
    comments
}"""
detailed_post_mask = """
message,
result{
    other_user,
    project,
    content,
    linked_user,
    image_id,
    is_self,
    blocked,
    anonymous,
    reactions,
    tags,
    comment_channel_id,
    comments
}"""


@api.route('/messages')
class Posts(Resource):
    @api.doc(parser=get_parser)
    def get(self):
        return handle_request(parser=get_parser,
                              arg_dict={'channel_id': None, 'last_post_id': None, 'limit': 20},
                              rest_function=ChannelsREST.get_channel_posts,
                              model=a_post_response,
                              mask=normal_post_mask)

    @api.doc(parser=channel_parser, body=post_a_post_content)
    def put(self):
        return handle_request(parser=channel_parser,
                              arg_dict={'channel_id': None},
                              json_data=True,
                              rest_function=ChannelsREST.post_to_channel,
                              model=a_post_response_single,
                              mask=normal_post_mask)

    @api.doc(parser=delete_parser)
    def delete(self):
        return handle_request(
            parser=delete_parser,
            arg_dict={'post_id': None},
            rest_function=ChannelsREST.delete_channel_post)


@api.route('/message/<post_id>')
class Post(Resource):
    @api.doc(parser=base_parser)
    def get(self, post_id):
        return handle_request(path_args=[post_id],
                              rest_function=ChannelsREST.get_post,
                              model=a_post_response_single,
                              mask=detailed_post_mask,
                              skip_none=False)


@api.route('/message/<post_id>/react')
class React(Resource):
    @api.doc(parser=base_parser, body=post_a_reaction)
    def post(self, post_id):
        return handle_request(path_args=[post_id],
                              json_data=True,
                              rest_function=ChannelsREST.post_reaction,
                              model=a_post_response_single,
                              mask=normal_post_mask,
                              skip_none=False)


@api.route('/')
class Channels(Resource):
    @api.doc(parser=base_parser, body=post_channels_ids)
    def get(self):
        return handle_request(json_data=True,
                              rest_function=ChannelsREST.get_channels,
                              model=a_channel_response)


@api.route('/read_message/<post_id>')
@api.doc(params={'post_id': 'Id of last read post in a channel'})
class ReadMessage(Resource):
    @api.doc(parser=base_parser)
    def post(self, post_id):
        return handle_request(path_args=[post_id],
                              rest_function=ChannelsREST.post_message_read)


@api.route('/block_post/<post_to_block_id>')
@api.doc(params={'post_to_block_id': 'Id of Post that will be blocked'})
class BlockPost(Resource):
    @api.doc(parser=base_parser)
    def post(self, post_to_block_id):
        return handle_request(path_args=[post_to_block_id],
                              rest_function=ChannelsREST.post_block_post)


@api.route('/unblock_post/<post_to_unblock_id>')
@api.doc(params={'post_to_unblock_id': 'Id of Post that will be unblocked'})
class UnBlock(Resource):
    @api.doc(parser=base_parser)
    def post(self, post_to_unblock_id):
        return handle_request(path_args=[post_to_unblock_id],
                              rest_function=ChannelsREST.post_unblock_post)
