"""Admin-editable home-page content: the "how to use PickkerMarket" video
and a news/announcements list — both editable without a code deploy, same
spirit as the rest of market/site_settings.py."""

import re
from datetime import datetime, timezone

from django.core.cache import cache

from accounts.supabase_client import get_client

_HERO_IMAGE_CACHE_KEY = 'pickker_hero_image_url'
_HOW_TO_CACHE_KEY = 'pickker_how_to_content'
_NEWS_CACHE_KEY = 'pickker_active_news'
_PARTNERS_CACHE_KEY = 'pickker_active_partners'
_PARTNERS_HEADING_CACHE_KEY = 'pickker_partners_heading'
_CACHE_TTL = 60

_YOUTUBE_PATTERNS = [
    re.compile(r'(?:youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/)([\w-]+)'),
]

_HOW_TO_FIELDS = ['how_to_title', 'how_to_description', 'how_to_video_url', 'how_to_image_url', 'how_to_thumbnail_url']
_PARTNERS_HEADING_FIELDS = ['partners_heading', 'partners_subheading']
_HOME_TEXT_FIELDS = [
    'hero_title_line1', 'hero_title_line2', 'hero_title_line3',
    'home_plan_label', 'home_order_label', 'home_market_pill', 'home_news_heading',
]
_HOME_TEXT_CACHE_KEY = 'pickker_home_text_overrides'


def to_embeddable_video_url(url):
    """Converts a plain YouTube watch/share link into its embeddable form;
    any other URL (Vimeo, a direct video file, an already-embed link) is
    passed through unchanged, since it's the admin's responsibility to
    paste something a browser can actually embed."""
    if not url:
        return None
    for pattern in _YOUTUBE_PATTERNS:
        match = pattern.search(url)
        if match:
            return f'https://www.youtube.com/embed/{match.group(1)}'
    return url


def get_how_to_content():
    """Title/description/media for the homepage "how it works" section — a
    video takes priority if set, otherwise the image; either is optional,
    and the whole section is simply omitted if none of these are set."""
    content = cache.get(_HOW_TO_CACHE_KEY)
    if content is None:
        resp = get_client().table('pickker_site_settings').select(','.join(_HOW_TO_FIELDS)).eq('id', 1).execute()
        row = resp.data[0] if resp.data else {}
        content = {field: row.get(field) or None for field in _HOW_TO_FIELDS}
        cache.set(_HOW_TO_CACHE_KEY, content, _CACHE_TTL)
    return content


def update_how_to_content(title=None, description=None, video_url=None, image_url=None, thumbnail_url=None):
    """Only the fields actually passed get updated — image/thumbnail are
    handled separately from the text fields since they come from a file
    upload that may not be present on every save."""
    row = {}
    if title is not None:
        row['how_to_title'] = title.strip()
    if description is not None:
        row['how_to_description'] = description.strip()
    if video_url is not None:
        row['how_to_video_url'] = video_url.strip()
    if image_url is not None:
        row['how_to_image_url'] = image_url
    if thumbnail_url is not None:
        row['how_to_thumbnail_url'] = thumbnail_url
    if row:
        get_client().table('pickker_site_settings').update(row).eq('id', 1).execute()
        cache.delete(_HOW_TO_CACHE_KEY)


def get_hero_image_url():
    """The homepage top hero banner image — admin-uploadable, falls back to
    the bundled static default (img/tomato-web.jpg) when unset."""
    url = cache.get(_HERO_IMAGE_CACHE_KEY)
    if url is None:
        resp = get_client().table('pickker_site_settings').select('hero_image_url').eq('id', 1).execute()
        url = (resp.data[0].get('hero_image_url') if resp.data else None) or ''
        cache.set(_HERO_IMAGE_CACHE_KEY, url, _CACHE_TTL)
    return url or None


def update_hero_image_url(image_url):
    get_client().table('pickker_site_settings').update({'hero_image_url': image_url}).eq('id', 1).execute()
    cache.delete(_HERO_IMAGE_CACHE_KEY)


def get_home_text():
    """Admin overrides for every other static text block on the homepage
    (hero headline, tile labels, news heading) — each falls back to the
    bundled translation string in the template (`{{ home_text.x|default:t.y }}`)
    when unset, so nothing needs to be filled in for the site to keep
    working exactly as it does out of the box."""
    text = cache.get(_HOME_TEXT_CACHE_KEY)
    if text is None:
        resp = get_client().table('pickker_site_settings').select(','.join(_HOME_TEXT_FIELDS)).eq('id', 1).execute()
        row = resp.data[0] if resp.data else {}
        text = {field: row.get(field) or None for field in _HOME_TEXT_FIELDS}
        cache.set(_HOME_TEXT_CACHE_KEY, text, _CACHE_TTL)
    return text


def update_home_text(**kwargs):
    row = {field: (kwargs[field] or '').strip() for field in _HOME_TEXT_FIELDS if field in kwargs}
    if row:
        get_client().table('pickker_site_settings').update(row).eq('id', 1).execute()
        cache.delete(_HOME_TEXT_CACHE_KEY)


def get_active_news(limit=6):
    news = cache.get(_NEWS_CACHE_KEY)
    if news is None:
        resp = (
            get_client()
            .table('pickker_news')
            .select('*')
            .eq('is_active', True)
            .order('created_at', desc=True)
            .limit(limit)
            .execute()
        )
        news = resp.data
        cache.set(_NEWS_CACHE_KEY, news, _CACHE_TTL)
    return news


def get_all_news():
    resp = get_client().table('pickker_news').select('*').order('created_at', desc=True).execute()
    return resp.data


def create_news(title, body, image_url=None):
    title = (title or '').strip()
    if not title:
        return
    row = {'title': title, 'body': (body or '').strip()}
    if image_url is not None:
        row['image_url'] = image_url
    get_client().table('pickker_news').insert(row).execute()
    cache.delete(_NEWS_CACHE_KEY)


def update_news(news_id, title, body, image_url=None):
    row = {
        'title': (title or '').strip(),
        'body': (body or '').strip(),
        'updated_at': datetime.now(timezone.utc).isoformat(),
    }
    if image_url is not None:
        row['image_url'] = image_url
    get_client().table('pickker_news').update(row).eq('id', news_id).execute()
    cache.delete(_NEWS_CACHE_KEY)


def toggle_news_active(news_id):
    client = get_client()
    resp = client.table('pickker_news').select('is_active').eq('id', news_id).execute()
    if resp.data:
        current = resp.data[0]['is_active']
        client.table('pickker_news').update({'is_active': not current}).eq('id', news_id).execute()
        cache.delete(_NEWS_CACHE_KEY)
        return not current
    return None


def delete_news(news_id):
    get_client().table('pickker_news').delete().eq('id', news_id).execute()
    cache.delete(_NEWS_CACHE_KEY)


def get_partners_heading():
    heading = cache.get(_PARTNERS_HEADING_CACHE_KEY)
    if heading is None:
        resp = get_client().table('pickker_site_settings').select(','.join(_PARTNERS_HEADING_FIELDS)).eq('id', 1).execute()
        row = resp.data[0] if resp.data else {}
        heading = {field: row.get(field) or '' for field in _PARTNERS_HEADING_FIELDS}
        cache.set(_PARTNERS_HEADING_CACHE_KEY, heading, _CACHE_TTL)
    return heading


def update_partners_heading(heading, subheading):
    get_client().table('pickker_site_settings').update({
        'partners_heading': (heading or '').strip(),
        'partners_subheading': (subheading or '').strip(),
    }).eq('id', 1).execute()
    cache.delete(_PARTNERS_HEADING_CACHE_KEY)


def get_active_partners():
    """Homepage display order — lowest sort_order first, then newest."""
    partners = cache.get(_PARTNERS_CACHE_KEY)
    if partners is None:
        resp = (
            get_client()
            .table('pickker_partners')
            .select('*')
            .eq('is_active', True)
            .order('sort_order')
            .order('created_at', desc=True)
            .execute()
        )
        partners = resp.data
        cache.set(_PARTNERS_CACHE_KEY, partners, _CACHE_TTL)
    return partners


def get_all_partners():
    resp = get_client().table('pickker_partners').select('*').order('sort_order').order('created_at', desc=True).execute()
    return resp.data


def create_partner(name, logo_url, website_url='', sort_order=0):
    name = (name or '').strip()
    if not name or not logo_url:
        return
    get_client().table('pickker_partners').insert({
        'name': name,
        'logo_url': logo_url,
        'website_url': (website_url or '').strip(),
        'sort_order': sort_order or 0,
    }).execute()
    cache.delete(_PARTNERS_CACHE_KEY)


def update_partner(partner_id, name, website_url, logo_url=None, sort_order=None):
    row = {'name': (name or '').strip(), 'website_url': (website_url or '').strip()}
    if logo_url is not None:
        row['logo_url'] = logo_url
    if sort_order is not None:
        row['sort_order'] = sort_order
    get_client().table('pickker_partners').update(row).eq('id', partner_id).execute()
    cache.delete(_PARTNERS_CACHE_KEY)


def toggle_partner_active(partner_id):
    client = get_client()
    resp = client.table('pickker_partners').select('is_active').eq('id', partner_id).execute()
    if resp.data:
        current = resp.data[0]['is_active']
        client.table('pickker_partners').update({'is_active': not current}).eq('id', partner_id).execute()
        cache.delete(_PARTNERS_CACHE_KEY)
        return not current
    return None


def delete_partner(partner_id):
    get_client().table('pickker_partners').delete().eq('id', partner_id).execute()
    cache.delete(_PARTNERS_CACHE_KEY)
