import requests
from decouple import config
import re
import random
import string
from .models import OrganisationThirdPartyIntegration
from ussdbanking.helpers import get_basic_auth_token

def flexi_pay_sacco_onboarding(sacco, account_number, added_by):
    exist = OrganisationThirdPartyIntegration.objects.filter(organisation=sacco, third_party="flexi_pay").order_by('-sacco_id').first()
    if exist:
        exist.is_active = True
        exist.save()
    else:
        sacco_id =  generate_flexi_pay_sacco_number()
        account_number = account_number
        if not account_number:
            account_number = ''.join(random.choice(string.digits) for _ in range(10))

        data = {
                "sacco_name": sacco.name,
                "sacco_id":sacco_id,
                "sacco_account": account_number,
                "amount": "0"
        }

        basic_token = get_basic_auth_token()
        response = requests.post(
            config('PAYMENT_GATEWAY_URL') + 'akello-pay/token-auth',
            json = {"grant_type": "client_credentials"},
            headers = {
                "Content-Type": "application/x-www-form-urlencoded",
                "Authorization": f"Basic {basic_token}"
            }
        )

        if response.status_code == 200:
            response_data = response.json()
            response = requests.post(
                config('PAYMENT_GATEWAY_URL') + 'api/akello-pay/flexipay/request-to-onboard-sacco/',
                json = data,
                headers = {
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {response_data['access_token']}"
                }
            )
            if response.status_code == 200:
                integration_obj = {"organisation":sacco, "sacco_id":sacco_id, "sacco_name":sacco.name, "sacco_account":account_number, "third_party":"flexi_pay", "added_by":added_by}
                OrganisationThirdPartyIntegration.objects.create(**integration_obj)
        return True


def generate_flexi_pay_sacco_number():
    last_sacco_number = 'FLXSACCO000'
    onboarding = OrganisationThirdPartyIntegration.objects.filter(third_party="flexi_pay").order_by('-sacco_id').first()
    if onboarding: 
        last_sacco_number = onboarding.sacco_id
    
    # Use regex to separate the prefix and the numeric part
    match = re.match(r"([A-Za-z]+)(\d+)", last_sacco_number)
    if match:
        prefix = match.group(1)
        number = match.group(2)
        
        # Increment the numeric part
        incremented_number = str(int(number) + 1).zfill(len(number))
        
        # Concatenate the prefix and the new numeric part
        new_sacco_number = f"{prefix}{incremented_number}"
        return new_sacco_number
    
    return "00000000000"
    



"""
Credit score integration
Feb 12th, 2025 
Wamula Bashir Saidi
"""
def gnugrid_authenticate():
    postData ={
    "grant_type": "client_credentials",
    "client_id":config('GNUGRID_CLIENT_ID'),
    "client_secret": config('GNUGRID_CLIENT_SECRET'),
    # "url":config('GNUGRID_API_END_POINT')+'oauth/token'
    }

    response = requests.post(config('GNUGRID_API_END_POINT')+'oauth/token',
                             json=postData,
                             headers={
                                 "Content-Type":"application/json"
                             })
    # return response.json()
    try:
        return response.json()
    except requests.exceptions.JSONDecodeError:
        return {"error": "Invalid JSON response", "raw_response": response.text}
    

def gnugrid_credit_score(token, postData):
    print(">>> ENTERED gnugrid_credit_score() <<<")
    response = requests.post(config('GNUGRID_API_END_POINT')+'credit-enquiries/credit-scores',
                             json=postData,
                             headers={
                                 "Content-Type":"application/json",
                                 "Authorization": f"Bearer {token}"
                             })
    print(">>> GNUGrid response status:", response.status_code)
    print(">>> GNUGrid response text:", response.text)
    # return response.json()
    try:
        return response.json()
    
    except requests.exceptions.JSONDecodeError:
        return {"error": "Invalid JSON response", "raw_response": response.text}

def handle_school_hub_validate(customer_account, student_number, school):
    results = []
    postData = {"student_number": student_number}

    try:
        response = requests.post(
            config('SCHOOL_HUB_API_END_POINT') + 'api/FeesPayment/validateStudent',
            json=postData,
            headers={
                "Content-Type":"application/json",
                "Authorization": config('SCHOOL_HUB_API_AUTH_TOKEN')
            }
        )

        if response.status_code == 200:
            student = response.json()
            results.append({
                "accountNumber": student['accountNumber'],
                "accountName": student['accountName'],
                "accountProvider": student['accountProvider'],
                "outstandingBalance": student['outstandingBalance'],
                "accountType": student['accountType'],
                "customer_id": school.customer.id,
                "customer_name": school.customer.name,
                "saving_account_id": customer_account.id
            })
    except Exception as e:
        print("School Hub validation error:", str(e))

    return results


def handle_school_hub_payment(postData):
    try:
        response = requests.post(
            config('SCHOOL_HUB_API_END_POINT') + 'api/FeesPayment/payStudentFees',
            json=postData,
            headers={
                "Content-Type":"application/json",
                "Authorization": config('SCHOOL_HUB_API_AUTH_TOKEN')
            }
        )
        response.raise_for_status()  # raises HTTPError for 4xx/5xx
        return response
    except requests.exceptions.RequestException as e:
        print("School Hub payment error:", str(e))
        return None
