from organisations.models import OrganisationSetting
from ledgers.models import OrganisationSubAccount, OrganisationBranch, Organisation
from customers.models import Customer
from ledgers.ledgers_helper import generate_chart_of_account_code
from decouple import config
from base64 import b64encode

# for soap requests
import requests
import xml.etree.ElementTree as ET
import json

# check if a number is airtel.
def is_airtel_number(telephone_number):
    short_number = telephone_number[-9:]
    provider_code = short_number[:2]
    if provider_code in ['70', '75', '74']:
        return True
    
    return False

# get branch wallet chart
def get_branch_wallet_chart(organisation_id, branch_id):
    
    organisation = Organisation.objects.get(pk=organisation_id)
    setting_key = "{branch_id}_branch_wallet_chart".format(branch_id=branch_id)
    branch_wallet_setting = OrganisationSetting.objects.filter(org_setting_id=organisation_id, setting_key=setting_key).first()
    
    if branch_wallet_setting:
        chart = OrganisationSubAccount.objects.filter(id=branch_wallet_setting.setting_value).first()
        if chart and chart.parent_id.account_code == 'sys-11418':
            return OrganisationSubAccount.objects.filter(id=branch_wallet_setting.setting_value).first()
        else:
            branch_wallet_setting.delete()

    # Create chart if not exists
    branch = OrganisationBranch.objects.filter(id=branch_id).first()
    account_name = "Ewallet - {branch_name}".format(branch_name=branch.name)
    parent_chart = OrganisationSubAccount.objects.filter(account_code='sys-11418', account_organisation_id=organisation_id).first()
    if parent_chart:
        account_code = generate_chart_of_account_code(parent_chart.id, 'assets', organisation_id)
        branch_wallet_ledger = OrganisationSubAccount(account_name=account_name, account_line='assets', account_code=account_code, account_organisation_id=organisation_id, account_type='locked_chart', parent_id=parent_chart, allow_sub_accounts=False)
        branch_wallet_ledger.save()
    else:
        parent_chart = OrganisationSubAccount.objects.filter(account_code='sys-1141', account_organisation_id=organisation_id).first()
        parent_account_name = "System E - Wallets"
        wallet_parent = OrganisationSubAccount(account_name=parent_account_name, account_line='assets', account_code='sys-11418', account_organisation_id=organisation_id, account_type='locked_chart', parent_id=parent_chart, allow_sub_accounts=False)
        wallet_parent.save()

        account_code = generate_chart_of_account_code(wallet_parent.id, 'assets', organisation_id)
        branch_wallet_ledger = OrganisationSubAccount(account_name=account_name, account_line='assets', account_code=account_code, account_organisation_id=organisation_id, account_type='locked_chart', parent_id=wallet_parent, allow_sub_accounts=False)
        branch_wallet_ledger.save()

    OrganisationSetting.objects.create(org_setting=organisation, setting_key=setting_key, setting_value=branch_wallet_ledger.id, setting_added_by=1)
    return branch_wallet_ledger

# get or create member wallet chart under branch wallet
def get_member_wallet_chart(organisation_id, branch_id, customer_id):
    organisation = Organisation.objects.get(pk=organisation_id)
    branch_wallet_chart = get_branch_wallet_chart(organisation_id, branch_id)
    customer = Customer.objects.get(pk=customer_id)

    # account_name = f"Wallet - {customer.member_number}"
    # existing = OrganisationSubAccount.objects.filter(
    #     parent_id=branch_wallet_chart,
    #     account_name=account_name,
    #     account_organisation_id=organisation_id
    # ).first()
    # if existing:
    #     return existing

    # account_code = generate_chart_of_account_code(branch_wallet_chart.id, 'assets', organisation_id)
    # member_wallet_ledger = OrganisationSubAccount(
    #     account_name=account_name,
    #     account_line='assets',
    #     account_code=account_code,
    #     account_organisation_id=organisation_id,
    #     account_type='locked_chart',
    #     parent_id=branch_wallet_chart,
    #     allow_sub_accounts=False
    # )
    # member_wallet_ledger.save()
    # return member_wallet_ledger

    return branch_wallet_chart

# get or create YO settlement wallet chart
def get_yo_wallet_chart(organisation_id, branch_id):
    organisation = Organisation.objects.get(pk=organisation_id)
    setting_key = f"{branch_id}_yo_wallet_chart"
    yo_wallet_setting = OrganisationSetting.objects.filter(org_setting_id=organisation_id, setting_key=setting_key).first()

    if yo_wallet_setting:
        chart = OrganisationSubAccount.objects.filter(id=yo_wallet_setting.setting_value).first()
        if chart and chart.parent_id.account_code == 'sys-11419':
            return chart
        else:
            yo_wallet_setting.delete()

    branch = OrganisationBranch.objects.filter(id=branch_id).first()
    account_name = f"YoWallet - {branch.name}"
    parent_chart = OrganisationSubAccount.objects.filter(account_code='sys-11419', account_organisation_id=organisation_id).first()
    if parent_chart:
        account_code = generate_chart_of_account_code(parent_chart.id, 'assets', organisation_id)
        yo_wallet_ledger = OrganisationSubAccount(account_name=account_name, account_line='assets', account_code=account_code, account_organisation_id=organisation_id, account_type='locked_chart', parent_id=parent_chart, allow_sub_accounts=False)
        yo_wallet_ledger.save()
    else:
        # ensure parent exists
        parent_chart = OrganisationSubAccount.objects.filter(account_code='sys-1141', account_organisation_id=organisation_id).first()
        parent_account_name = "System Yo - Wallets"
        wallet_parent = OrganisationSubAccount(account_name=parent_account_name, account_line='assets', account_code='sys-11419', account_organisation_id=organisation_id, account_type='locked_chart', parent_id=parent_chart, allow_sub_accounts=False)
        wallet_parent.save()

        account_code = generate_chart_of_account_code(wallet_parent.id, 'assets', organisation_id)
        yo_wallet_ledger = OrganisationSubAccount(account_name=account_name, account_line='assets', account_code=account_code, account_organisation_id=organisation_id, account_type='locked_chart', parent_id=wallet_parent, allow_sub_accounts=False)
        yo_wallet_ledger.save()

    OrganisationSetting.objects.create(org_setting=organisation, setting_key=setting_key, setting_value=yo_wallet_ledger.id, setting_added_by=1)
    return yo_wallet_ledger

def get_basic_auth_token():
    basic_token = b64encode(bytes(f"{config('CLIENT_ID')}:{config('CLIENT_SECRET')}", "utf-8")).decode("ascii")
    return basic_token



def consume_yo_api(soap_url, headers, payload):

    # response = requests.post(url, headers=headers, json=data)
    response = requests.post(soap_url, data=payload, headers=headers)
    # return response
    if response.status_code == 200:
        try:
            root = ET.fromstring(response.content)
            data = {}
            for child in root.iter():
                if child.text and child.tag not in ['AutoCreate', 'Request', 'Response']:
                    data[child.tag] = child.text.strip()
            
            # json_response = json.dumps(data, indent=4)
            print("✅ JSON Response:")
            return(data)
        except ET.ParseError as e:
            return { "Status": "ERROR",  "StatusCode": "-13", "StatusMessage": f"Failed to parse XML: {e}" }
            # return("❌ Failed to parse XML:", e)
    else:
        return { "Status": "ERROR",  "StatusCode": "-13", "StatusMessage":  f"Transaction failed: {response.text}" }
        # return(f"❌ HTTP Error {response.status_code}: {response.text}")


