from flask_restful import Resource
import globals
from src import auth
from webargs.flaskparser import use_kwargs, parser, abort
from webargs import fields
from bson import json_util, ObjectId
import json

filesDB = globals.filesDB

auth_args = {"Authorization": fields.Str(required=True)}

class GetPageData(Resource):
    fileData_args = {"id": fields.Str(required=True), "pageNum": fields.Str(required=True)}
    @use_kwargs(auth_args, location="headers")
    @use_kwargs(fileData_args, location="query")
    def get(self, id, Authorization, pageNum):
        if auth.verify(str(Authorization).split(" ")[1]):
            pipeline = [
                {
                    "$match": {
                        "_id": ObjectId(id),
                    }
                },
                {
                    '$unwind': '$Pages'
                },
                {
                    "$match": {
                        "Pages.PageNum": int(pageNum),
                    }
                },
                {
                    "$lookup":
                        {
                            'from': 'fixed_layout_lines',
                            'localField': "Pages.PageID",
                            'foreignField': 'pageId',
                            'pipeline': [
                                {
                                    "$match":
                                        {
                                            "$expr": {"$eq": ["$current", 1]}
                                        }
                                },
                                {
                                    "$sort": {"pageLineIndex": 1}
                                },
                            ],
                            'as': 'PageData'
                        }
                }, {
                    "$lookup":
                        {
                            'from': 'fixed_layout_boxes',
                            'localField': "Pages.PageID",
                            'foreignField': 'pageId',
                            'pipeline': [
                                {
                                    "$sort": {"boxIndex": 1}
                                },
                            ],
                            'as': 'Boxes'
                        }
                },
                {
                    "$project": {
                        "_id": 1,
                        "PageCount": "$TotalPages",
                        "PageID": "$Pages.PageID",
                        "PageNum": "$Pages.PageNum",
                        "Image": "$Pages.Image",
                        "Redacted_Image": "$Pages.Redacted_Image",
                        "h_multiplier": "$Pages.Height-Multipler",
                        "w_multiplier": "$Pages.Width-Multipler",
                        "PageData": 1,
                        "Boxes": 1
                    }
                }
            ]
            file = list(filesDB.aggregate(pipeline))
            return json.loads(json_util.dumps(file)), 200
        else:
            return "Unauthorized! Access Denied", 401


class PageReset(Resource):
    @use_kwargs(auth_args, location="headers")
    @use_kwargs({"id":fields.Str(required=True)}, location="query")
    def post(self,Authorization,id):
        if auth.verify(str(Authorization).split(" ")[1]):
            globals.linesDB.delete_many(
                {
                    "$and": [
                    {
                        "pageId": id
                    },
                    {
                        "cursor":
                            {
                                "$ne": 0
                            }
                    }
                    ]
                }
            )

            newLines = []
            for record in globals.linesDB.find(
                {
                    "pageId": id
                }
            ):
                record["_id"] = ObjectId()
                record["cursor"] = 1
                record["current"] = 1
                newLines.append(record)

            globals.linesDB.insert_many(newLines)

            globals.boxesDB.delete_many(
                {
                    "pageId": id
                }
            )
            return {"msg": "Page Reset Successfully"}, 200

        else:
            return {"msg": "Unauthorized! Access Denied"}, 401


@parser.error_handler
def handle_request_parsing_error(err, req, schema, *, error_status_code, error_headers):
    """webargs error handler that uses Flask-RESTful's abort function to return
    a JSON error response to the client.
    """
    code, msg = getattr(err, 'status_code', 400), getattr(err, 'message', 'Invalid Request')
    if not error_status_code:
        abort(400, errors= err.messages)
    else:
        abort(error_status_code, errors=err.messages)