# -*- coding: utf-8 -*-
"""Metadata chips (1080p · MKV · 725 MB · CZ) rendered as one image per list row.

Kodi list layouts cannot size a chip background to its text (controls inside a
grouplist in an itemlayout do not resolve ListItem infolabels — verified live
in Kodi 21), so each row gets a PNG with snug chips: white text on a faint
white pill, tinted by `colordiffuse` in the XML (idle vs focused). Rendered at
2x for crisp output on 1440p/4K GUIs; cached by content.

Geometry (1080p skin px, measured on the design reference): height 33,
horizontal text padding 14, gap 15, fully rounded ends, fill alpha ~11.5 %,
text Kodi Arial at font10 size.
"""

import hashlib
import os

import xbmc
import xbmcvfs

SCALE = 2
HEIGHT = 33
PAD_X = 14
GAP = 15
FONT_SIZE = 18  # measured on the reference: chip text widths within 1 px
FILL = (255, 255, 255, 29)
TEXT = (255, 255, 255, 255)
MAX_CHIP_CHARS = 18
# Kodi's own Arial avoids shipping a font and works with PIL.
_FONT_FILE = 'special://xbmc/media/Fonts/arial.ttf'
_VERSION = '4'  # bump when the rendering changes, so cached strips are regenerated
_CACHE_DIR = 'special://profile/addon_data/plugin.video.milionar/cache/chips/'
_font = None


def _get_font():
    global _font
    if _font is None:
        from PIL import ImageFont
        _font = ImageFont.truetype(xbmcvfs.translatePath(_FONT_FILE), FONT_SIZE * SCALE)
    return _font


def _text_width(font, text):
    """Pillow 8+ getlength; older Pillow (Kodi's script.module.pil 5.x on Windows) getsize."""
    return font.getlength(text) if hasattr(font, 'getlength') else font.getsize(text)[0]


def _ink_span(font, text):
    """(top, bottom) of the ink of text: getbbox in Pillow 8+, the mask bbox in older Pillow."""
    if hasattr(font, 'getbbox'):
        box = font.getbbox(text)
        return box[1], box[3]
    box = font.getmask(text).getbbox()
    return box[1], box[3]


def _pill(draw, left, right, height, fill):
    """Fully rounded bar; rounded_rectangle only exists in Pillow 8.2+."""
    if hasattr(draw, 'rounded_rectangle'):
        draw.rounded_rectangle([left, 0, right, height - 1], radius=height // 2, fill=fill)
        return
    radius = height // 2
    draw.rectangle([left + radius, 0, right - radius, height - 1], fill=fill)
    draw.ellipse([left, 0, left + height - 1, height - 1], fill=fill)
    draw.ellipse([right - height + 1, 0, right, height - 1], fill=fill)


def chip_strip(values):
    """Path to a PNG with one chip per non-empty value ('' when nothing to show)."""
    values = [str(v).strip()[:MAX_CHIP_CHARS] for v in values if v and str(v).strip() and v != 'N/A']
    if not values:
        return ''
    key = hashlib.sha1((_VERSION + '|' + '|'.join(values)).encode('utf-8')).hexdigest()[:16]
    folder = xbmcvfs.translatePath(_CACHE_DIR)
    path = os.path.join(folder, 'chips_{}.png'.format(key))
    if os.path.exists(path):
        return path
    try:
        from PIL import Image, ImageDraw
        font = _get_font()
        height, pad, gap = HEIGHT * SCALE, PAD_X * SCALE, GAP * SCALE
        widths = [int(round(_text_width(font, v))) + 2 * pad for v in values]
        img = Image.new('RGBA', (sum(widths) + gap * (len(values) - 1), height), (0, 0, 0, 0))
        draw = ImageDraw.Draw(img)
        x = 0
        for value, width in zip(values, widths):
            _pill(draw, x, x + width - 1, height, FILL)
            # vertical centre on the ink of digits/caps so "1080p" and "MKV" sit alike
            top, bottom = _ink_span(font, '0MK')
            y = (height - (bottom - top)) / 2 - top
            draw.text((x + pad, y), value, font=font, fill=TEXT)
            x += width + gap
        os.makedirs(folder, exist_ok=True)
        img.save(path, 'PNG')
        return path
    except Exception as exc:
        xbmc.log('[plugin.video.milionar] chip_strip failed: {}'.format(exc), xbmc.LOGWARNING)
        return ''
