"""Draw the finding as one SVG: mobile web against desktop, human pageviews, year over year.

    python research/wikipedia-traffic/chart.py

Writes site/public/images/wikipedia-mobile-vs-desktop.svg. Palette from the site
(docs/IDENTITY.md): ground #0f1120, amber #f2b544, dusk violet #a9a2c6,
ivory #efe9dc, grid #262a44. A second accent is needed for the second line;
the site's `--rule` slate #4d7ea8 reads as the quiet one against the amber.
"""

import json
import os
import sys

RAW = os.path.expanduser("~/data/wikipedia-traffic")
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                   "..", "..", "site", "public", "images",
                   "wikipedia-mobile-vs-desktop.svg")

W, H = 760, 420
L, R, T, B = 54, 16, 48, 54          # margins (T leaves the marked-date labels
                                     # their own line under the caption)
GROUND, GRID = "#0f1120", "#262a44"
AMBER, VIOLET, IVORY, SLATE = "#f2b544", "#a9a2c6", "#efe9dc", "#7fb2d8"

# The window that bears on the claim. The full series back to 2016 is in
# monthly.csv; 2020-21 whiplash is four times the size of anything here and
# drawing it would hide the thing the chart is about.
FIRST = "2022-01"
LO, HI = -0.22, 0.18                 # y range, fraction

MARKS = (("2022-11", "ChatGPT"), ("2024-05", "AI Overviews"))


def series(access):
    path = os.path.join(RAW, "en.wikipedia__%s__user.json" % access)
    with open(path) as fh:
        data = json.load(fh)
    return {"%s-%s" % (i["timestamp"][:4], i["timestamp"][4:6]): int(i["views"])
            for i in data["items"]}


def yoy(s, m):
    p = "%d-%s" % (int(m[:4]) - 1, m[5:])
    return None if p not in s or not s[p] else s[m] / s[p] - 1.0


def main():
    mweb, desk = series("mobile-web"), series("desktop")
    months = [m for m in sorted(mweb) if m >= FIRST and yoy(desk, m) is not None]
    n = len(months)

    def x(i):
        return L + (W - L - R) * i / (n - 1)

    def y(v):
        v = max(LO, min(HI, v))
        return T + (H - T - B) * (HI - v) / (HI - LO)

    p = ['<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d %d" width="%d" '
         'height="%d" role="img" aria-labelledby="t d" font-family="JetBrains Mono, '
         'ui-monospace, Menlo, monospace" font-size="11">' % (W, H, W, H)]
    p.append('<title id="t">Human pageviews of en.wikipedia, year-over-year change '
             'by month, mobile web against desktop, January 2022 to August 2026</title>')
    p.append('<desc id="d">Two lines, January 2022 to August 2026. Mobile web grew through 2022, 2023 and early 2024, peaking near plus 13 per cent, then turned negative in May '
             '2024 and has been negative in all 28 '
             'months since, reaching about minus 13 per cent in 2026. Desktop crosses '
             'back and forth across zero for the whole window, mostly between minus ten '
             'and plus five per cent, with no break at either marked date, and ends '
             'higher than it started. Two dashed vertical lines mark November 2022, '
             'ChatGPT, and May 2024, AI Overviews. '
             'Source: Wikimedia REST pageview API, agent=user.</desc>')
    p.append('<rect width="%d" height="%d" fill="%s"/>' % (W, H, GROUND))

    for v in (-0.20, -0.10, 0.0, 0.10, 0.20):
        yy = y(v)
        p.append('<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="%s" stroke-width="%s"/>'
                 % (L, yy, W - R, yy, GRID, "1.5" if v == 0 else "1"))
        p.append('<text x="%d" y="%.1f" fill="%s" text-anchor="end">%+d%%</text>'
                 % (L - 8, yy + 4, VIOLET, int(round(v * 100))))

    for m in months:
        if m.endswith("-01"):
            i = months.index(m)
            p.append('<line x1="%.1f" y1="%d" x2="%.1f" y2="%d" stroke="%s" '
                     'stroke-width="1" opacity="0.5"/>' % (x(i), T, x(i), H - B, GRID))
            p.append('<text x="%.1f" y="%d" fill="%s" text-anchor="middle" '
                     'font-size="10">%s</text>' % (x(i), H - B + 18, VIOLET, m[:4]))

    for month, label in MARKS:
        if month not in months:
            continue
        i = months.index(month)
        p.append('<line x1="%.1f" y1="%d" x2="%.1f" y2="%d" stroke="%s" stroke-width="1" '
                 'stroke-dasharray="3 3" opacity="0.8"/>' % (x(i), T, x(i), H - B, IVORY))
        p.append('<text x="%.1f" y="%d" fill="%s" text-anchor="middle" font-size="10">'
                 '%s</text>' % (x(i), T - 11, IVORY, label))

    for s, colour, label in ((desk, SLATE, "desktop"), (mweb, AMBER, "mobile web")):
        pts = " ".join("%.1f,%.1f" % (x(i), y(yoy(s, m))) for i, m in enumerate(months))
        p.append('<polyline points="%s" fill="none" stroke="%s" stroke-width="2" '
                 'stroke-linejoin="round"/>' % (pts, colour))

    # legend, in the empty upper-left quarter
    for k, (colour, label) in enumerate(((AMBER, "mobile web"), (SLATE, "desktop"))):
        yy = T + 16 + 16 * k
        p.append('<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="%s" stroke-width="2"/>'
                 % (L + 8, yy, L + 26, yy, colour))
        p.append('<text x="%d" y="%.1f" fill="%s" font-size="11">%s</text>'
                 % (L + 32, yy + 4, colour, label))

    p.append('<text x="%d" y="16" fill="%s" font-size="11">human pageviews of '
             'en.wikipedia, change on the same month a year earlier</text>' % (L - 2, VIOLET))
    p.append('<text x="%d" y="%d" fill="%s" font-size="10">Wikimedia REST pageview API, '
             'agent=user · drawn 2026-09-09</text>' % (L - 2, H - 10, VIOLET))
    p.append('</svg>')

    path = os.path.abspath(OUT)
    with open(path, "w") as fh:
        fh.write("\n".join(p) + "\n")
    print("wrote", path, "-", n, "months")
    return 0


if __name__ == "__main__":
    sys.exit(main())
