from flask import Flask, request, make_response, jsonify
from flask_httpauth import HTTPBasicAuth
import logging
import datetime
from datetime import datetime, timedelta
from dateutil import parser, tz
from elasticsearch import Elasticsearch
from configparser import ConfigParser
from pandasticsearch import Select
import pandas as pd

logging.basicConfig(filename='/var/www/html/logs/clients_complaints.log',
                    filemode='a',
                    format='%(asctime)s %(name)s %(levelname)s %(message)s',
                    level=logging.INFO)


app = Flask(__name__)

#Read config.ini file
config_object = ConfigParser()
config_object.read("config.ini")



#Get info
elasticinfo = config_object["elastic"]
authinfo = config_object["auth"]

auth = HTTPBasicAuth()

USER_DATA = {
    str(authinfo["username"]): str(authinfo["password"])
}


@auth.verify_password
def verify(username, password):
    if not (username and password):
        return False
    return USER_DATA.get(username) == password


# paginate client complaints
@app.route('/client-complaints/', methods=['POST', 'GET'])
@auth.login_required
def clientComplaints():
    es = Elasticsearch(str(elasticinfo["live"]))
    if request.method == 'POST':
        req = request.get_json()
        username = str(req['username'])
        request_start_date = req['start_date']
        request_end_date = req['end_date']
        today = datetime.utcnow().date()

        
        if not request_start_date.strip() or not request_end_date.strip():
            request_start_date = datetime(today.year, today.month, today.day, tzinfo=tz.tzutc())
            request_end_date = request_start_date + timedelta(days=1, microseconds=-1)
            request_start_date = request_start_date.isoformat()
            request_end_date = request_end_date.isoformat()
        else:
            request_start_date = parser.parse(req['start_date']).isoformat()
            request_end_date = parser.parse(req['end_date']).isoformat()
       
        if not req['cursor'].strip():
             json_payload = {
                            "size": 10,
                            "query": {
                                "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                                {"match": {"username.keyword":username}}]}
                            },
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }
        else:
            cursor = int(req['cursor'])
            json_payload = {
                            "size": 10,
                            "query": {
                                "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                                {"match": {"username.keyword":username}}]}
                            },
                            "search_after" : [cursor],
                            "sort": [
                            { "created_at" :  "desc"}
                            ]   
                         }

        count_payload = {
                        "query": {
                            "bool":{"filter":[{"range":{"created_at":{"gte":"{}".format(request_start_date), "lte":"{}".format(request_end_date)}}},
                            {"match": {"username.keyword":username}}]}
                        },   
                        }
                 

        results = []

        try:
            count = es.count(index="clients-complaints-*", body=count_payload)['count']
            res = es.search(index="clients-complaints-*", body=json_payload)
            for doc in res['hits']['hits']:
                results.append(dict(client_id=doc['_source']['client_id'],
                                    issue_date=doc['_source']['issue_date'],
                                    created_at=doc['_source']['created_at'],
                                    updated_at=doc['_source']['updated_at'],
                                    description=doc['_source']['description'],
                                    resolution_period=doc['_source']['resolution_period'],
                                    status=doc['_source']['status'],
                                    comment=doc['_source']['comment'],
                                    end_date=doc['_source']['end_date'],
                                    product=doc['_source']['product']
                                    ))
            try:
                cursor = res['hits']['hits'][-1]['sort'][0]
                logging.info(f"sort value:{cursor}")
            except:
                cursor = 0
                logging.info(f"sort value:{cursor}")
                
            if not len(results):
                return make_response(jsonify(code=404, error='No search results'), 200)
            else:
                logging.info('Results found')
                logging.info(results[0])
            return make_response(jsonify(code=200, cursor=cursor,
                                    doc_count=count, results=results), 200)
            
        except Exception as e:
            logging.info(f'search failed with error {e}')
            return make_response(jsonify(code=500, error='search api failed'), 200)

