"""Terms & Conditions / Privacy Policy / Cookie Policy — admin-editable
content (versioned, so a content change forces every user to re-accept),
plus the acceptance log itself. New users accept the current version of all
three at signup; an existing user is asked to re-accept only the ones that
changed since they last did."""

from datetime import datetime, timezone

from django.core.cache import cache

from accounts.supabase_client import get_client

POLICY_TYPES = ['terms', 'privacy', 'cookies']

_CACHE_KEY = 'pickker_legal_policies_all'
_CACHE_TTL = 300


def _all_policies():
    policies = cache.get(_CACHE_KEY)
    if policies is None:
        rows = get_client().table('pickker_legal_policies').select('*').execute().data
        policies = {row['policy_type']: row for row in rows}
        cache.set(_CACHE_KEY, policies, _CACHE_TTL)
    return policies


def _invalidate():
    cache.delete(_CACHE_KEY)


def get_policy(policy_type):
    return _all_policies().get(policy_type)


def localize_policy(policy, lang):
    """A policy row has both English (title/content) and Swahili
    (title_sw/content_sw) text under one shared version — a change to
    either language still bumps the one version, so everyone re-accepts
    regardless of which language they read it in. Falls back to English
    if a Swahili translation hasn't been filled in yet."""
    if lang == 'sw' and policy.get('title_sw') and policy.get('content_sw'):
        return {**policy, 'title': policy['title_sw'], 'content': policy['content_sw']}
    return policy


def get_all_policies():
    """Ordered list (terms, privacy, cookies) for the footer/signup checkbox."""
    policies = _all_policies()
    return [policies[t] for t in POLICY_TYPES if t in policies]


def update_policy(policy_type, title, content, title_sw='', content_sw=''):
    """Any content edit (either language) bumps the version, which is
    exactly what forces every user (who accepted an older version) to
    review and re-accept it next time they log in — see
    get_outdated_policies below."""
    current = get_policy(policy_type)
    next_version = (current['version'] + 1) if current else 1
    get_client().table('pickker_legal_policies').update({
        'title': title.strip(),
        'content': content.strip(),
        'title_sw': title_sw.strip(),
        'content_sw': content_sw.strip(),
        'version': next_version,
        'updated_at': datetime.now(timezone.utc).isoformat(),
    }).eq('policy_type', policy_type).execute()
    _invalidate()


def get_user_accepted_versions(user_id):
    """The latest accepted version per policy type for this user, e.g.
    {'terms': 2, 'privacy': 1, 'cookies': 1} — missing keys mean never
    accepted at all."""
    rows = (
        get_client()
        .table('pickker_policy_acceptances')
        .select('policy_type, version')
        .eq('user_id', user_id)
        .order('version', desc=True)
        .execute()
        .data
    )
    accepted = {}
    for row in rows:
        # First row seen per policy_type is the highest version, since we
        # ordered by version desc.
        accepted.setdefault(row['policy_type'], row['version'])
    return accepted


def get_outdated_policies(user_id):
    """Policies this user either never accepted or accepted an older
    version of — what they need to (re-)accept before continuing."""
    current = _all_policies()
    accepted = get_user_accepted_versions(user_id)
    return [
        current[t] for t in POLICY_TYPES
        if t in current and accepted.get(t, 0) < current[t]['version']
    ]


def record_acceptance(user_id, policy_type, version):
    get_client().table('pickker_policy_acceptances').insert({
        'user_id': user_id,
        'policy_type': policy_type,
        'version': version,
    }).execute()


def record_all_current_acceptances(user_id):
    """Called right after signup — accepts the current version of every
    policy in one go, since the signup checkbox covers all three at once."""
    client = get_client()
    rows = [
        {'user_id': user_id, 'policy_type': t, 'version': p['version']}
        for t, p in _all_policies().items()
    ]
    if rows:
        client.table('pickker_policy_acceptances').insert(rows).execute()
