import logging
import requests
import pyodbc
import pandas as pd
import sys
import traceback


def get_token(auth_server_url: str, client_id: str, secret: str):
    try:
        token_req = {'client_id': client_id,
                     'client_secret': secret,
                     'grant_type': 'client_credentials'}

        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
        try:
            token_response = requests.post(auth_server_url, data=token_req, headers=headers)
            token_response.raise_for_status()
        except requests.exceptions.RequestException as e:
            logging.error(e)
            sys.exit(1)

        tokens = token_response.json()
        return tokens.get('access_token')
    except Exception as e:
        print(f'enable logging for more information: {traceback.format_exc()}')


def migrate(api_url: str, schema: str, table_name: str, token: str, conn_string: str, *date_field: str):
    try:
        api_call_headers = {'Authorization': f'Bearer {token}'}

        page = 1


        try:
            conn = pyodbc.connect(conn_string)
            cursor = conn.cursor()
        except Exception as e:
            logging.error(e)
            sys.exit(1)
        try:
            cursor.execute(f'TRUNCATE TABLE [{schema}].[{table_name}]')
            while True:
                params = {
                    'pageSize': 10000,
                    'page': page
                }
                try:
                    api_call_response = requests.get(api_url, headers=api_call_headers, params=params)
                except Exception as e:
                    logging.error(e)
                    sys.exit(1)

                if api_call_response.status_code != 200:
                    logging.error(f'Return code: {api_call_response.status_code}. Exiting script.')
                    sys.exit(1)

                response_data = api_call_response.json()
                if 'DataSet' not in response_data:
                    logging.error('No data in response.')
                    sys.exit(1)

                temp_df = pd.DataFrame(response_data['DataSet']);
                rows, _ = temp_df.shape

                if temp_df.empty:
                    break
                col_list = list(temp_df)
                column_names = ','.join(col_list)
                values = '?' * len(col_list)
                values = ','.join(values)

                for field in date_field:
                    try:
                        temp_df[field] = pd.to_datetime(temp_df[field], utc=True, errors='coerce')
                        if pd.api.types.is_datetime64_any_dtype(temp_df[field]):
                            temp_df[field] = temp_df[field].dt.tz_convert('Pacific/Auckland').dt.tz_localize(None,
                                                                                                         ambiguous=False)

                    except Exception as e:
                        logging.error(e)
                try:
                    cursor.fast_executemany = True
                    cursor.executemany(f'INSERT INTO [{schema}].[{table_name}]({column_names})'
                                   f'VALUES({values})',
                                   temp_df.values.tolist())
                except Exception as e:
                    logging.error(e)
                conn.commit()
                page += 1
            logging.info('Closing connection to db')
            conn.close()
        except Exception as e:
            logging.error(e)

    except Exception as e:
        print(f'enable logging for more information: {traceback.format_exc()}')
