# -*- coding: utf-8 -*-
"""PayGo UI building blocks on top of paygo_lib primitives."""
from paygo_lib import *

# --------------------------------------------------------------------------
# Atoms
# --------------------------------------------------------------------------
def status_bar(parent, time="9:41", right="nfc", dark=False, name="Status bar"):
    fg = PAPER if dark else INK
    bar = row(parent, name, gap=8, padding=[14, 20, 8, 20], main="spaceBetween",
              cross="center", fill_w=True)
    txt(bar, time, 13, "SemiBold", fg, name="Time")
    rt = row(bar, "Indicators", gap=6)
    if right == "nfc":
        icon(rt, "nfc", 14, fg)
        txt(rt, "100%", 12, "SemiBold", fg, name="Battery")
    else:
        txt(rt, right, 12, "SemiBold", fg, name="Battery")
    return bar


def pill(parent, label, bg=TINT, fg=BLUE_DARK, border=TINT_LINE):
    p = row(parent, "Pill · " + label, gap=0, padding=[5, 11, 5, 11], fill=bg,
            radius=999, stroke=border)
    txt(p, label, 11, "Bold", fg)
    return p


def app_header(parent, title=None, sub=None, back=None, right_pill=None,
               right_icon=None, name="App header"):
    """White header bar with a 1px bottom rule."""
    h = row(parent, name, gap=10, padding=[13, 20, 13, 20], fill=PAPER,
            main="spaceBetween", cross="center", fill_w=True,
            stroke=LINE, stroke_sides=[False, False, True, False])
    left = row(h, "Leading", gap=6)
    if back:
        icon(left, "arrow-left", 17, BLUE_DARK)
        txt(left, back, 14, "Bold", BLUE_DARK, name="Back")
    else:
        c = col(left, "Titles", gap=1)
        txt(c, title, 16, "SemiBold", INK, name="Title")
        if sub:
            txt(c, sub, 11.5, "Regular", MUTED, name="Subtitle")
    if right_pill:
        pill(h, right_pill)
    elif right_icon:
        icon(h, right_icon, 20, BLUE_DEEP)
    return h


def hero_header(parent, title, sub=None, back=False, name="Header · Gradient"):
    """PayWise-style blue gradient header."""
    h = col(parent, name, gap=2, padding=[10, 20, 26, 20], fill_w=True,
            fills=[{"type": "linearGradient", "stops": [BLUE_DARK, BLUE_MID],
                    "from": [0, 0], "to": [0.4, 1]}])
    top = row(h, "Row", gap=10, fill_w=True, cross="center")
    if back:
        icon(top, "arrow-left", 20, PAPER)
    txt(top, title, 19, "SemiBold", PAPER, name="Title")
    spacer(top)
    icon(top, "bell", 19, PAPER)
    if sub:
        txt(h, sub, 12, "Regular", "#FFFFFFCC", name="Subtitle")
    return h


def button(parent, label, variant="green", icon_key=None, align="center",
           name=None):
    spec = {
        "green":  (GREEN, ON_GREEN, GREEN_MID),
        "blue":   (BLUE_DEEP, PAPER, None),
        "ghost":  (PAPER, INK, LINE),
        "danger": (PAPER, DANGER, DANGER_LINE),
    }[variant]
    bg, fg, border = spec
    b = row(parent, name or ("Button · " + label), gap=9,
            padding=[15, 16, 15, 16], fill=bg, radius=R_BTN,
            main=align, cross="center", fill_w=True, stroke=border)
    if icon_key:
        icon(b, icon_key, 19, fg)
    txt(b, label, 14.5, "Bold", fg, name="Label")
    return b


def link_button(parent, label):
    b = row(parent, "Link · " + label, gap=0, padding=[10, 8, 10, 8],
            main="center", fill_w=True)
    txt(b, label, 13.5, "Bold", BLUE_DARK, decoration="underline", name="Label")
    return b


def card(parent, name="Card", gap=5, padding=15, fill=PAPER, border=LINE,
         radius=R_CARD, shadow=False, horizontal=False, main="min",
         cross="center"):
    kw = dict(gap=gap, padding=padding, fill=fill, radius=radius, stroke=border,
              fill_w=True, effects=CARD_SHADOW if shadow else None)
    if horizontal:
        return row(parent, name, main=main, cross=cross, **kw)
    return col(parent, name, **kw)


def section_label(parent, label):
    return txt(parent, label, 11, "Bold", BLUE_DEEP, tracking="12%",
               case="upper", name="Section · " + label)


def amount_display(parent, amount, caption, size=31, align="center",
                   caption_case="upper", caption_size=11):
    c = col(parent, "Amount", gap=5, fill_w=True,
            cross="center" if align == "center" else "min")
    txt(c, amount, size, "ExtraBold", INK, tracking="-2%",
        align=align, name="Amount")
    txt(c, caption, caption_size, "Bold", MUTED, tracking="8%",
        case=caption_case, align=align, name="Caption")
    return c


def badge(parent, label, kind="success"):
    bg, fg = {"success": (SUCCESS_BG, GREEN_DEEP),
              "declined": (DANGER_SOFT, DANGER),
              "pending": (PENDING_BG, PENDING_INK)}[kind]
    b = row(parent, "Badge · " + label, gap=0, padding=[3, 8, 3, 8],
            fill=bg, radius=999)
    txt(b, label, 10, "ExtraBold", fg, tracking="4%")
    return b


def txn_row(parent, title, amount, sub, badge_label, kind="success", last=False):
    t = col(parent, "Txn · " + title, gap=4, padding=[13, 20, 13, 20],
            fill_w=True, stroke=None if last else LINE,
            stroke_sides=None if last else [False, False, True, False])
    top = row(t, "Top", gap=10, fill_w=True, main="spaceBetween")
    txt(top, title, 13.5, "SemiBold", INK, name="Id")
    txt(top, amount, 13.5, "ExtraBold", INK, name="Amount")
    bot = row(t, "Bottom", gap=10, fill_w=True, main="spaceBetween", cross="center")
    txt(bot, sub, 11, "Regular", MUTED, name="Meta")
    badge(bot, badge_label, kind)
    return t


def field(parent, label, value, muted_value=False):
    f = col(parent, "Field · " + label, gap=6, fill_w=True)
    txt(f, label, 11, "Bold", MUTED, tracking="6%", case="upper", name="Label")
    box = row(f, "Input", gap=0, padding=[0, 14, 0, 14], height=48, fill=PAPER,
              radius=R_INPUT, stroke=LINE, fill_w=True, cross="center",
              hug_v=False)
    nset(box, sizingV="fixed", height=48)
    txt(box, value, 14, "Regular", MUTED if muted_value else INK, name="Value")
    return f


def toggle(parent, on=True):
    t = row(parent, "Toggle", gap=0, padding=0, width=48, height=28,
            fill=GREEN if on else LINE, radius=999,
            main="max" if on else "min", cross="center")
    nset(t, sizingH="fixed", sizingV="fixed", paddingLeft=3, paddingRight=3)
    create("ellipse", parent=t, name="Knob", width=22, height=22,
           props={"fill": PAPER,
                  "effects": [{"type": "dropShadow", "color": "#00000040",
                               "offset": [0, 1], "radius": 3, "spread": 0,
                               "visible": True}]})
    return t


def checkbox(parent, checked=True):
    c = row(parent, "Checkbox", gap=0, width=22, height=22,
            fill=BLUE_DEEP if checked else PAPER, radius=7,
            stroke=None if checked else LINE, main="center", cross="center")
    nset(c, sizingH="fixed", sizingV="fixed")
    if checked:
        icon(c, "check", 14, PAPER)
    return c


def nav_item(parent, label, icon_key, active=False):
    fg = BLUE_DEEP if active else MUTED
    it = col(parent, ("Nav · " + label) + ("  (active)" if active else ""),
             gap=5, padding=[12, 4, 14, 4], fill_w=True, cross="center")
    nset(it, sizingH="fill")
    icon(it, icon_key, 21, fg)
    txt(it, label, 10.5, "ExtraBold" if active else "SemiBold", fg, name="Label")
    return it


def bottom_nav(parent, active="Home", x=None, y=None, name=None):
    nav = row(parent, name or ("Bottom nav / " + active), gap=0, padding=0,
              fill=PAPER, width=SCREEN_W, x=x, y=y,
              stroke=LINE, stroke_sides=[True, False, False, False])
    for label, key in (("Home", "home"), ("Transactions", "receipt"),
                       ("Settings", "gear")):
        nav_item(nav, label, key, active == label)
    return nav


# --------------------------------------------------------------------------
# QR code artwork (from the design's 26x26 module grid)
# --------------------------------------------------------------------------
QR_DATA = ("M10 1h2v2h-2zM13 1h1v2h-1zM8 3h1v2H8zM10 4h3v1h-3zM12 6h2v2h-2z"
           "M9 9h2v2H9zM14 9h1v1h-1zM17 9h2v2h-2zM8 12h2v2H8zM11 12h3v1h-3z"
           "M16 12h2v2h-2zM10 15h2v2h-2zM14 15h3v2h-3zM17 14h1v3h-1zM7 8h1v2H7z"
           "M11 8h2v1h-2zM12 10h1v2h-1zM9 12h1v2H9z")


def qr_code(parent, size=200, name="QR code"):
    k = size / 26.0
    box = create("frame", parent=parent, name=name, width=size, height=size,
                 props={"fill": "none", "clip": False, "layout": None})
    for ox, oy in ((1, 1), (18, 1), (1, 18)):
        create("rectangle", parent=box, name="Finder", x=ox * k, y=oy * k,
               width=7 * k, height=7 * k, props={"fill": INK})
        create("rectangle", parent=box, name="Finder inner", x=(ox + 1) * k,
               y=(oy + 1) * k, width=5 * k, height=5 * k, props={"fill": PAPER})
        create("rectangle", parent=box, name="Finder eye", x=(ox + 2) * k,
               y=(oy + 2) * k, width=3 * k, height=3 * k, props={"fill": INK})
    bx, by, bw, bh = bbox(QR_DATA)
    create("vector", parent=box, name="Modules", path=QR_DATA,
           x=bx * (k - 1), y=by * (k - 1), width=bw * k, height=bh * k,
           props={"fill": INK, "stroke": "none"})
    return box


# --------------------------------------------------------------------------
# Screen shell
# --------------------------------------------------------------------------
GUTTER = 96
LABEL_Y = -92


def screen(index, code, title, desc, fill=PAPER, fills=None, clip=True):
    """A 390x844 artboard plus its caption, laid out in a row on the page."""
    x = index * (SCREEN_W + GUTTER)
    lab = col(None, "Label · " + code, gap=3, width=SCREEN_W, x=x, y=LABEL_Y)
    nset(lab, sizingH="fixed")
    txt(lab, code, 12, "ExtraBold", BLUE, tracking="10%", case="upper", name="Kicker")
    txt(lab, title, 19, "SemiBold", INK, name="Title")
    t = txt(lab, desc, 12.5, "Regular", MUTED, name="Desc")
    nset(t, sizingH="fill", textAutoResize="height")

    props = {"layout": "vertical", "gap": 0, "padding": 0, "mainAlign": "min",
             "crossAlign": "min", "clip": clip, "cornerRadius": 0,
             "effects": PHONE_SHADOW,
             "exports": [{"format": "png", "size": {"by": "scale", "value": 2}, "suffix": "@2x"},
                         {"format": "svg", "size": {"by": "scale", "value": 1}}]}
    props["fills"] = fills if fills else [fill]
    s = create("frame", name=code + " · " + title, x=x, y=0,
               width=SCREEN_W, height=SCREEN_H, props=props)
    return s


def body(screen_id, gap=14, padding=None, name="Content"):
    b = col(screen_id, name, gap=gap,
            padding=padding if padding is not None else [16, PAD, 20, PAD],
            fill_w=True, fill_v=True, hug_v=False)
    return b
