def get_banking_month_count(analytics_data):
    from datetime import datetime

    if not analytics_data or not isinstance(analytics_data, dict):
        return 0

    account_profiles = analytics_data.get("accountProfiles", [])
    if not account_profiles or not isinstance(account_profiles, list):
        return 0

    min_date = None
    max_date = None

    for profile in account_profiles:
        summary = profile.get("summary", {})
        start_str = summary.get("transactionStartDate")
        end_str = summary.get("transactionEndDate")

        if start_str:
            try:
                s_date = datetime.strptime(start_str, "%Y-%m-%d")
                if min_date is None or s_date < min_date:
                    min_date = s_date
            except Exception:
                pass

        if end_str:
            try:
                e_date = datetime.strptime(end_str, "%Y-%m-%d")
                if max_date is None or e_date > max_date:
                    max_date = e_date
            except Exception:
                pass

    if not min_date or not max_date:
        return 0

    days_gap = (datetime.now() - max_date).days
    if days_gap > 30:
        return 0

    months = (
        (max_date.year - min_date.year) * 12
        + (max_date.month - min_date.month)
        + 1
    )

    return int(months)


def get_name_match_score(analytics_data, applicant_name):
    from fuzzywuzzy import fuzz

    if not applicant_name or not analytics_data or not isinstance(analytics_data, dict):
        return 0

    account_profiles = analytics_data.get("accountProfiles", [])
    if not account_profiles:
        return 0

    applicant_name = str(applicant_name).lower().strip()
    max_score = 0

    for profile in account_profiles:
        holders = profile.get("Holders", {}).get("Holder", [])
        if not holders:
            continue

        holder_name = holders[0].get("name", "")
        if not holder_name:
            continue

        holder_name = str(holder_name).lower().strip()

        name1_set = set(applicant_name.split())
        name2_set = set(holder_name.split())

        if name1_set.issubset(name2_set):
            score = 100
        else:
            score = fuzz.ratio(applicant_name, holder_name)

        if score > max_score:
            max_score = score

    return max_score


def get_recent_bounce_count(analytics_data, lookback_months):
    from datetime import datetime
    from dateutil.relativedelta import relativedelta

    if not analytics_data or not isinstance(analytics_data, dict):
        return 0

    try:
        months_val = int(lookback_months)
    except Exception:
        months_val = 3

    lookback_period = (
        datetime.today().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        - relativedelta(months=months_val - 1)
    )

    bounce_root = analytics_data.get("bounceAnalysis", {})

    if bounce_root.get("completeBounceAnalysis"):
        target_data = bounce_root.get("completeBounceAnalysis")
    elif bounce_root.get("monthlyBounceAnalysis"):
        target_data = bounce_root.get("monthlyBounceAnalysis")
    elif bounce_root.get("bounceAnalysis"):
        target_data = bounce_root.get("bounceAnalysis")
    else:
        target_data = bounce_root

    total_bounce = 0

    if target_data and target_data.get("accountWiseBounceAnalytics"):
        account_wise_list = target_data.get("accountWiseBounceAnalytics")

        if isinstance(account_wise_list, list) and len(account_wise_list) > 0:
            account_data = account_wise_list[0]
            monthly_data = account_data.get("monthlyBounceAnalysis", [])

            for month_data in monthly_data:
                try:
                    current_month_year = datetime.strptime(
                        f"{month_data.get('year')}-{month_data.get('month')}",
                        "%Y-%m",
                    )

                    if lookback_period <= current_month_year:
                        if (
                            month_data.get("totalEmiBounceTxn", 0) > 0
                            and month_data.get("totalEmiBounceAmt", 0) > 0
                        ):
                            total_bounce += month_data.get("totalEmiBounceTxn")

                        if (
                            month_data.get("totalEcsBounceChargeTxns", 0) > 0
                            and month_data.get("totalEcsBounceChargeAmount", 0) > 0
                        ):
                            total_bounce += month_data.get(
                                "totalEcsBounceChargeTxns"
                            )
                except Exception:
                    continue

    return int(total_bounce)


def get_speculative_spend_percentage(data, monthly_income):
    from datetime import datetime

    if not data or not monthly_income:
        return 0.0

    try:
        income = float(monthly_income)
        if income <= 0:
            return 0.0
    except Exception:
        return 0.0

    account_profiles = data.get("accountProfiles", [])
    all_transactions = data.get("allTransactions", [])

    min_date = None
    max_date = None

    if account_profiles and isinstance(account_profiles, list):
        for profile in account_profiles:
            summary = profile.get("summary", {})
            start_str = summary.get("transactionStartDate")
            end_str = summary.get("transactionEndDate")

            if start_str:
                try:
                    s_date = datetime.strptime(start_str, "%Y-%m-%d")
                    if min_date is None or s_date < min_date:
                        min_date = s_date
                except Exception:
                    pass

            if end_str:
                try:
                    e_date = datetime.strptime(end_str, "%Y-%m-%d")
                    if max_date is None or e_date > max_date:
                        max_date = e_date
                except Exception:
                    pass

    months_count = 1
    if min_date and max_date:
        months_count = (
            (max_date.year - min_date.year) * 12
            + (max_date.month - min_date.month)
            + 1
        )
        if months_count < 1:
            months_count = 1

    speculative_categories = ["Gambling & Betting", "Gaming"]
    total_spec_amount = 0.0

    for txn in all_transactions:
        category = txn.get("category", "")
        if category in speculative_categories:
            amt = float(txn.get("amount", 0))
            total_spec_amount += abs(amt)

    avg_monthly_spec_spend = total_spec_amount / months_count
    percentage = (avg_monthly_spec_spend / income) * 100

    return float(f"{percentage:.2f}")


def calculate_abb_eligible_amount(analytics_data, multiplier):
    try:
        abb_val = 0.0

        if isinstance(analytics_data, dict):
            abb_val = (
                analytics_data.get("overallAnalysis", {})
                .get("customAbbs", {})
                .get("adjustedAbb2", {})
                .get("averageOfMonthlyAverages", 0.0)
            )

        abb = float(abb_val) if abb_val is not None else 0.0
        mult = float(multiplier) if multiplier is not None else 0.0

        eligible_emi = abb * mult
        return float(f"{eligible_emi:.2f}")

    except Exception:
        return 0.0
