'''
Created on 3 May 2021

@author: jacklok
'''

from flask import Blueprint
import logging
from trexanalytics.controllers.bigquery.query_base_routes import CategoryAndCountQueryBaseResource,\
    QueryBaseResource
from flask_restful import Api
from trexanalytics.conf import BIGQUERY_GCLOUD_PROJECT_ID, MERCHANT_DATASET


transaction_analytics_data_bp = Blueprint('transaction_analytics_data_bp', __name__,
                                 template_folder='templates',
                                 static_folder='static',
                                 url_prefix='/analytics/transaction')

logger = logging.getLogger('query')

query_transaction_data_api = Api(transaction_analytics_data_bp)

@transaction_analytics_data_bp.route('/index')
def query_transaction_index(): 
    return 'ping', 200


def process_transaction_result_into_fieldname_and_value(job_result_rows):
    row_list = []
    for row in job_result_rows:
        #logger.debug(row)
        column_dict = {}
        column_dict['date_range']           = row.date_range
        column_dict['sumTransactAmount']    = row.sumTransactAmount
        column_dict['transactionCount']     = row.transactionCount
        
        row_list.append(column_dict)
    
    return row_list

def process_transaction_result_without_dange_range_into_fieldname_and_value(job_result_rows):
    row_list = []
    for row in job_result_rows:
        #logger.debug(row)
        column_dict = {}
        column_dict['totalTransactAmount']      = row.totalTransactAmount
        column_dict['transactionCount']         = row.transactionCount
        
        row_list.append(column_dict)
    
    return row_list     

class CustomerTransactionQueryBase(QueryBaseResource):
    def process_query_result(self, job_result_rows):
        return process_transaction_result_into_fieldname_and_value(job_result_rows)
    

class QueryAllCustomerTransactionByYearMonth(CustomerTransactionQueryBase):
    def prepare_query(self, **kwrgs):
        
        year_month_from   = kwrgs.get('year_month_from')
        year_month_to     = kwrgs.get('year_month_to')
        
        where_condition  = ''
        
        if year_month_from and year_month_to:
            where_condition = "WHERE _TABLE_SUFFIX BETWEEN '{year_month_from}' and '{year_month_to}'".format(year_month_from=year_month_from, 
                                                                                                         year_month_to=year_month_to)
        
        query = '''
            SELECT FORMAT_DATETIME('%Y-%m', TransactDateTime) as date_range, sum(TotalTransactAmount) as sumTransactAmount, count(*) as transactionCount
            FROM (
                        SELECT TransactDateTime, SUM(TransactAmount) as TotalTransactAmount
                        FROM (
                            SELECT TransactDateTime, TransactionId, TransactAmount
                            FROM `{project_id}.{dataset_name}.customer_transaction_*`
                            {where_condition}
                            GROUP BY TransactDateTime, TransactionId, TransactAmount
                        )
                        GROUP BY TransactDateTime
                     
            ) GROUP BY date_range  
            order by date_range          
            '''.format(project_id=BIGQUERY_GCLOUD_PROJECT_ID, dataset_name=MERCHANT_DATASET, where_condition=where_condition)    
            
        logger.debug('QueryAllCustomerTransactionByYearMonth: query=%s', query)
    
        return query 
    
class QueryMerchantCustomerTransactionByYearMonth(CustomerTransactionQueryBase):
    def prepare_query(self, **kwrgs):
        account_code      = kwrgs.get('account_code')
        year_month_from   = kwrgs.get('year_month_from')
        year_month_to     = kwrgs.get('year_month_to')
        
        account_code = account_code.replace('-','')
        
        where_condition  = ''
        
        if year_month_from and year_month_to:
            where_condition = "WHERE _TABLE_SUFFIX BETWEEN '{year_month_from}' and '{year_month_to}'".format(year_month_from=year_month_from, 
                                                                                                         year_month_to=year_month_to)
        
        query = '''
            SELECT FORMAT_DATETIME('%Y-%m', TransactDateTime) as date_range, sum(TotalTransactAmount) as sumTransactAmount, count(*) as transactionCount
            FROM (
                        SELECT TransactDateTime, SUM(TransactAmount) as TotalTransactAmount
                        FROM (
                            SELECT TransactDateTime, TransactionId, TransactAmount
                            FROM `{project_id}.{dataset_name}.customer_transaction_{account_code}_*`
                            {where_condition}
                            GROUP BY TransactDateTime, TransactionId, TransactAmount
                        )
                        GROUP BY TransactDateTime
                     
            ) GROUP BY date_range  
            order by date_range          
            '''.format(project_id=BIGQUERY_GCLOUD_PROJECT_ID, dataset_name=MERCHANT_DATASET, where_condition=where_condition, account_code=account_code)    
            
        logger.debug('QueryMerchantCustomerTransactionByYearMonth: query=%s', query)
    
        return query
    
class QueryMerchantCustomerTransactionByDateRange(CustomerTransactionQueryBase):
    def prepare_query(self, **kwrgs):
        account_code      = kwrgs.get('account_code')
        date_range_from   = kwrgs.get('date_range_from')
        date_range_to     = kwrgs.get('date_range_to')
        
        account_code = account_code.replace('-','')
        
        where_condition  = ''
        
        if date_range_from and date_range_to:
            where_condition = "WHERE _TABLE_SUFFIX BETWEEN '{date_range_from}' and '{date_range_to}'".format(date_range_from=date_range_from, 
                                                                                                         date_range_to=date_range_to)
        
        query = '''
            SELECT FORMAT_DATETIME('%Y-%m-%d', TransactDateTime) as date_range, sum(TotalTransactAmount) as sumTransactAmount, count(*) as transactionCount
            FROM (
                        SELECT TransactDateTime, SUM(TransactAmount) as TotalTransactAmount
                        FROM (
                            SELECT TransactDateTime, TransactionId, TransactAmount
                            FROM `{project_id}.{dataset_name}.customer_transaction_{account_code}_*`
                            {where_condition}
                            GROUP BY TransactDateTime, TransactionId, TransactAmount
                        )
                        GROUP BY TransactDateTime
                     
            ) GROUP BY date_range    
            order by date_range        
            '''.format(project_id=BIGQUERY_GCLOUD_PROJECT_ID, dataset_name=MERCHANT_DATASET, where_condition=where_condition, account_code=account_code)    
            
        logger.debug('QueryMerchantCustomerTransactionByYearMonth: query=%s', query)
    
        return query
    
class QueryMerchantCustomerTransactionTotalByDateRange(CustomerTransactionQueryBase):
    def prepare_query(self, **kwrgs):
        account_code      = kwrgs.get('account_code')
        date_range_from   = kwrgs.get('date_range_from')
        date_range_to     = kwrgs.get('date_range_to')
        
        account_code = account_code.replace('-','')
        
        where_condition  = ''
        
        if date_range_from and date_range_to:
            where_condition = "WHERE _TABLE_SUFFIX BETWEEN '{date_range_from}' and '{date_range_to}'".format(date_range_from=date_range_from, 
                                                                                                         date_range_to=date_range_to)
        
        query = '''
            
                        SELECT SUM(TransactAmount) as totalTransactAmount, count(*) as transactionCount
                        FROM (
                            SELECT TransactDateTime, TransactionId, TransactAmount
                            FROM `{project_id}.{dataset_name}.customer_transaction_{account_code}_*`
                            {where_condition}
                            GROUP BY TransactDateTime, TransactionId, TransactAmount
                        )
                        
                     
                   
            '''.format(project_id=BIGQUERY_GCLOUD_PROJECT_ID, dataset_name=MERCHANT_DATASET, where_condition=where_condition, account_code=account_code)    
            
        logger.debug('QueryMerchantCustomerTransactionByYearMonth: query=%s', query)
    
        return query    
    
    def process_query_result(self, job_result_rows):
        return process_transaction_result_without_dange_range_into_fieldname_and_value(job_result_rows)
    

query_transaction_data_api.add_resource(QueryAllCustomerTransactionByYearMonth,   '/all-transaction-by-year-month')
query_transaction_data_api.add_resource(QueryMerchantCustomerTransactionByYearMonth,   '/merchant-transaction-by-year-month')
query_transaction_data_api.add_resource(QueryMerchantCustomerTransactionByDateRange,   '/merchant-transaction-by-date-range')
query_transaction_data_api.add_resource(QueryMerchantCustomerTransactionTotalByDateRange,   '/merchant-transaction-total-by-date-range')


