"""Registered product categories (Vegetables, Fruits, Grains, ...), managed by
admins and offered as a fixed dropdown when adding/editing a product — instead
of admins free-typing a category name that could drift out of sync (typos,
inconsistent casing/pluralization) across the catalog."""

from django.core.cache import cache

from accounts.supabase_client import get_client

# Categories barely ever change but are read on nearly every product-facing
# page (market listing, product form, category filter) — cached with a short
# TTL and invalidated immediately on create.
_CACHE_KEY = 'pickker_categories_list'
_CACHE_TTL = 60


def get_all_categories():
    categories = cache.get(_CACHE_KEY)
    if categories is None:
        resp = get_client().table('pickker_categories').select('*').order('name').execute()
        categories = resp.data
        cache.set(_CACHE_KEY, categories, _CACHE_TTL)
    return categories


def create_category(name, name_sw='', dispersion_factor=1.0):
    name = (name or '').strip()
    if not name:
        return
    existing = get_client().table('pickker_categories').select('id').ilike('name', name).execute()
    if existing.data:
        return
    get_client().table('pickker_categories').insert({
        'name': name, 'name_sw': (name_sw or '').strip(), 'dispersion_factor': dispersion_factor,
    }).execute()
    cache.delete(_CACHE_KEY)

def delete_category(category_id):
    get_client().table('pickker_categories').delete().eq('id', category_id).execute()
    cache.delete(_CACHE_KEY)

def edit_category(category_id, new_name, new_name_sw='', dispersion_factor=1.0):
    name = (new_name or '').strip()
    if not name:
        return
    get_client().table('pickker_categories').update({
        'name': name, 'name_sw': (new_name_sw or '').strip(), 'dispersion_factor': dispersion_factor,
    }).eq('id', category_id).execute()
    cache.delete(_CACHE_KEY)


def get_category_dispersion_map():
    """{category_name: dispersion_factor} — an admin-tunable estimate of how
    spread out a category's stalls typically are across the market (e.g.
    vegetables are often scattered across many stalls; grains tend to
    cluster in one area). Used only to weight the picking fee's
    extra-distinct-item surcharge — see market/pricing.py — never the base
    weight-tiered fee."""
    return {c['name']: float(c.get('dispersion_factor') or 1.0) for c in get_all_categories()}


def localize_categories(categories, lang):
    """Adds a display_name to each category row for the given site language
    — falls back to the English name whenever no Swahili name has been set,
    same pattern as market/product_i18n.py."""
    for c in categories:
        c['display_name'] = (c.get('name_sw') or c['name']) if lang == 'sw' else c['name']
    return categories


def get_category_display_map(lang):
    """{english_name: display_name} for every registered category — used to
    localize the plain-text category value stored on each product without
    changing what's actually stored (the English name stays the canonical
    key everywhere: filtering, the product row, the dropdown's option
    value)."""
    categories = get_all_categories()
    if lang == 'sw':
        return {c['name']: (c.get('name_sw') or c['name']) for c in categories}
    return {c['name']: c['name'] for c in categories}
