#!/usr/bin/env python3
#
# fetch-report-api-data.py
#
# Fetches real data from Vipps MobilePay Report API v2 "dates" endpoint
# and writes a CSV for today's funds & fees across all ledgers.

import requests
import csv
import datetime
import base64

# Set this to:
# True: If using the MIAMI API (for accounting partners)
# False: If using merchant API keys (for merchants)
USE_MIAMI_API = True

# For all types of API users:
CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'

# For merchants using their own API keys: Add these in addition to the above:
SUBSCRIPTION_KEY = 'YOUR_OCP_APIM_SUBSCRIPTION_KEY'
MERCHANT_SERIAL_NUMBER = 'YOUR_MERCHANT_SERIAL_NUMBER'

# Split the base URLs: ledgers live under settlement/v1; reports live under report/v2
LEDGERS_BASE_URL = 'https://api.vipps.no/settlement/v1'
REPORT_BASE_URL  = 'https://api.vipps.no/report/v2'

TOKEN_URL_MIAMI = 'https://api.vipps.no/miami/v1/token'
TOKEN_URL_MERCHANT = 'https://api.vipps.no/accesstoken/get'
COMMON_HEADERS = {
    'Vipps-System-Name': 'Report-API-Python-Example',
    'Vipps-System-Version': '1.0.0',
    'Vipps-System-Plugin-Name': 'Report-API-Python-Example',
    'Vipps-System-Plugin-Version': '1.0.0'
}

# Get access token
def get_access_token():
    if USE_MIAMI_API:
        credentials = f'{CLIENT_ID}:{CLIENT_SECRET}'.encode('utf-8')
        encoded_credentials = base64.b64encode(credentials).decode('utf-8')
        headers = {
            'Authorization': f'Basic {encoded_credentials}',
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
            **COMMON_HEADERS
        }
        data = {'grant_type': 'client_credentials'}
        response = requests.post(TOKEN_URL_MIAMI, headers=headers, data=data)
    else:
        headers = {
            'Content-Type': 'application/json',
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'Ocp-Apim-Subscription-Key': SUBSCRIPTION_KEY,
            'Merchant-Serial-Number': MERCHANT_SERIAL_NUMBER,
            **COMMON_HEADERS
        }
        response = requests.post(TOKEN_URL_MERCHANT, headers=headers, json={})

    response.raise_for_status()
    return response.json()['access_token']

def _with_auth_headers(access_token):
    # Keep existing behavior: always send subscription key and merchant serial if set.
    base = {
        'Authorization': f'Bearer {access_token}',
        **COMMON_HEADERS
    }
    if SUBSCRIPTION_KEY:
        base['Ocp-Apim-Subscription-Key'] = SUBSCRIPTION_KEY
    if MERCHANT_SERIAL_NUMBER:
        base['Merchant-Serial-Number'] = MERCHANT_SERIAL_NUMBER
    return base

# Fetch all ledgers (settlement/v1)
def get_ledgers(access_token):
    url = f"{LEDGERS_BASE_URL}/ledgers"
    headers = _with_auth_headers(access_token)
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()

# Fetch daily report entries for a specific ledger, topic ('funds' or 'fees') and date from report/v2
def get_daily_report_entries(access_token, ledger_id, topic, date):
    if topic not in ('funds', 'fees'):
        raise ValueError("topic must be 'funds' or 'fees'")
    url = f"{REPORT_BASE_URL}/ledgers/{ledger_id}/{topic}/dates/{date}"
    headers = _with_auth_headers(access_token)
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()

# Save to CSV
def save_to_csv(data, filename):
    with open(filename, mode='w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow([
            'Reference (Vipps PSP)',          # API field: reference
            'Time',
            'Ledger Date',
            'Entry Type',
            'Order ID/Reference (merchant)',  # API field: pspReference
            'Currency',
            'Amount',
            'Balance Before',
            'Balance After',
            'Recipient Handle',
            'Message',
            'Name',
            'Masked Phone'
        ])
        for item in data.get('items', []):
            writer.writerow([
                item.get('reference'),
                item.get('time'),
                item.get('ledgerDate'),
                item.get('entryType'),
                item.get('pspReference'),
                item.get('currency'),
                item.get('amount'),
                item.get('balanceBefore'),
                item.get('balanceAfter'),
                item.get('recipientHandle'),
                item.get('message'),
                item.get('name'),
                item.get('maskedPhoneNo')
            ])

if __name__ == "__main__":
    try:
        token = get_access_token()
        today = datetime.date.today().isoformat()
        csv_filename = f"{today}.csv"  # CSV file named by the date only

        # 1) Get ledgers from settlement/v1
        ledgers = get_ledgers(token)

        # 2) Pull both topics ('funds' and 'fees') from report/v2 to produce example data
        all_items = []
        for ledger in ledgers.get('ledgers', []):
            # Spec field name is 'ledgerId' (not 'id')
            ledger_id = ledger.get('ledgerId')
            if not ledger_id:
                continue
            for topic in ('funds', 'fees'):
                entries = get_daily_report_entries(token, ledger_id, topic, today)
                all_items.extend(entries.get('items', []))

        # 3) Save combined items to CSV
        save_to_csv({'items': all_items}, csv_filename)
        print(f"Daily report entries (funds & fees) saved to {csv_filename}")
    except Exception as e:
        print(f"Error: {e}")