"""Per-version download bundles, each small enough to upload in one shot."""
import os, sys, json, shutil, subprocess, html, glob

V5 = os.path.abspath('../v5')
GUIDE = os.path.abspath('../guide/Verdant-Ride-eFoil-Gear-Tags.pdf')
PACK = os.path.abspath('../pack6')
if os.path.isdir(PACK):
    shutil.rmtree(PACK)
os.makedirs(PACK)

wings = json.load(open(os.path.join(V5, 'tags.json')))
wings.sort(key=lambda w: (w['series'], int(w['number']) if w['number'].isdigit() else 0))

VERSIONS = {
    'one-piece': dict(
        zipname='Verdant-Ride-Gear-Tags-one-piece',
        title='One piece — nothing to assemble',
        sheet='../sheets/how-to-one-piece.png',
        sheet_as='how-to-one-piece.png',
        plate='all-49-one-piece.3mf',
        files=['{slug}-one-piece.3mf'],
        stls=['{slug}-one-piece.stl'],
        main='{slug}-one-piece.3mf'),
    'glued-halves': dict(
        zipname='Verdant-Ride-Gear-Tags-glued-halves',
        title='Two halves — glued',
        sheet='../sheets/how-to-glue.png',
        sheet_as='how-to-glued-halves.png',
        plate='all-49-glue-halves.3mf',
        files=['{slug}-glue-pair.3mf'],
        stls=['{slug}-glue-front-half.stl', '{slug}-glue-back-half.stl'],
        main='{slug}-glue-pair.3mf'),
    'snap-together': dict(
        zipname='Verdant-Ride-Gear-Tags-snap-together',
        title='Tray and insert — snap together',
        sheet='../sheets/how-to-snap.png',
        sheet_as='how-to-snap-together.png',
        plate='all-49-snap.3mf',
        files=['{slug}-snap.3mf'],
        stls=['{slug}-snap-tray.stl', '{slug}-snap-insert.stl'],
        main='{slug}-snap.3mf'),
}

CSS = '''
 :root { color-scheme: light dark; }
 body { font: 16px/1.5 -apple-system, "Segoe UI", Roboto, sans-serif; margin: 0;
        padding: 28px clamp(14px,4vw,48px) 64px; background:#f4f6f7; color:#22282c; }
 h1 { font-size: clamp(21px,3vw,32px); margin: 0 0 4px; letter-spacing:-.01em; }
 p.sub { margin: 0 0 24px; color:#5d6b73; }
 .grid { display:grid; gap:14px; grid-template-columns:repeat(auto-fill,minmax(178px,1fr)); }
 a.c { display:block; text-decoration:none; color:inherit; background:#fff;
       border:1px solid #dde3e6; border-radius:12px; padding:12px;
       transition:transform .12s ease, box-shadow .12s ease; }
 a.c:hover { transform:translateY(-2px); box-shadow:0 6px 20px rgba(20,30,36,.13); }
 a.c img { width:100%; display:block; border-radius:8px; background:#f4f6f7; }
 a.c b { display:block; margin-top:10px; font-size:15px; }
 a.c i { display:block; font-style:normal; font-size:12.5px; color:#7c8d96; }
 a.c s { display:block; text-decoration:none; font-size:12px; color:#9aa8b0; margin-top:3px; }
 a.c.old { opacity:.78; }
 @media (prefers-color-scheme: dark) {
   body { background:#171c20; color:#e8eef1; }
   a.c { background:#212a30; border-color:#2f3b43; }
   p.sub { color:#9fb0ba; }
 }
'''


def index_html(title, sub, href_tpl):
    cards = []
    for w in wings:
        spec = ' · '.join(x for x in [
            f"{w['area_cm2']} cm²" if w['area_cm2'] else '',
            f"{w['span_cm']} cm span" if w['span_cm'] else '',
            f"AR {w['aspect']}" if w['aspect'] else ''] if x)
        old = '' if w['status'] == 'current' else ' old'
        cards.append(
            f'  <a class="c{old}" href="{href_tpl.format(slug=w["slug"])}">\n'
            f'    <img src="previews/{w["slug"]}.png" alt="{html.escape(w["name"])}" loading="lazy">\n'
            f'    <b>{html.escape(w["name"])}</b>\n'
            f'    <i>{html.escape(w["series"])}'
            f'{"" if w["status"] == "current" else " · discontinued"}</i>\n'
            f'    <s>{spec}</s>\n  </a>')
    return (f'<!doctype html>\n<meta charset="utf-8"><title>{html.escape(title)}</title>\n'
            f'<meta name="viewport" content="width=device-width,initial-scale=1">\n'
            f'<style>{CSS}</style>\n<h1>{html.escape(title)}</h1>\n'
            f'<p class="sub">{sub}</p>\n<div class="grid">\n'
            + '\n'.join(cards) + '\n</div>\n')


def zipdir(root, name):
    subprocess.run(['zip', '-r', '-q', '-9', f'{name}.zip', name], cwd=PACK, check=True)
    return os.path.getsize(os.path.join(PACK, f'{name}.zip'))


out = []
for key, v in VERSIONS.items():
    root = os.path.join(PACK, v['zipname'])
    os.makedirs(os.path.join(root, 'wings'))
    os.makedirs(os.path.join(root, 'previews'))
    for w in wings:
        for tpl in v['files']:
            f = tpl.format(slug=w['slug'])
            shutil.copy(os.path.join(V5, 'tags', w['slug'], f),
                        os.path.join(root, 'wings', f))
        shutil.copy(os.path.join(V5, 'previews', f'{w["slug"]}.png'),
                    os.path.join(root, 'previews'))
    # the PDF guide replaces the old plain-text README -- same content, plus the
    # renders, the layer-profile chart and the full wing catalogue
    shutil.copy(GUIDE, os.path.join(root, 'READ ME FIRST.pdf'))
    shutil.copy(v['sheet'], os.path.join(root, v['sheet_as']))
    open(os.path.join(root, 'index.html'), 'w').write(index_html(
        f'Verdant Ride eFoil Gear Tags — {v["title"]}',
        'All 49 Lift Foils front wings. Click a wing to open its print file. '
        'Assembly is on the how-to sheet in this folder; everything else is in '
        '<b>READ ME FIRST.pdf</b>.',
        'wings/' + v['main']))
    out.append((v['zipname'], zipdir(root, v['zipname'])))

    # STL companion, if it fits inside the 10 MB upload ceiling
    sroot = os.path.join(PACK, v['zipname'] + '-STL')
    os.makedirs(os.path.join(sroot, 'wings'))
    for w in wings:
        for tpl in v['stls']:
            f = tpl.format(slug=w['slug'])
            shutil.copy(os.path.join(V5, 'tags', w['slug'], f),
                        os.path.join(sroot, 'wings', f))
    shutil.copy(GUIDE, os.path.join(sroot, 'READ ME FIRST.pdf'))
    out.append((v['zipname'] + '-STL', zipdir(sroot, v['zipname'] + '-STL')))

# generator
groot = os.path.join(PACK, 'Verdant-Ride-Gear-Tags-generator')
shutil.copytree(os.path.join(PACK, VERSIONS['one-piece']['zipname']), groot,
                ignore=lambda *a: ['wings', 'previews'])
for f in ('shellkit.py', 'tagkit.py', 'build.py', 'genall2.py', 'wings.csv',
          'isodraw.py', 'sheet.py', 'mksheets.py', 'mkbundle2.py', 'verify.py'):
    if os.path.exists(f):
        shutil.copy(f, groot)
shutil.copytree('assets', os.path.join(groot, 'assets'))
out.append(('Verdant-Ride-Gear-Tags-generator',
            zipdir(groot, 'Verdant-Ride-Gear-Tags-generator')))

for f in sorted(glob.glob(os.path.join(V5, 'print-all', '*.3mf'))):
    out.append((os.path.basename(f), os.path.getsize(f)))

print(f'{"file":52s} {"MB":>6s}  upload?')
for n, s in out:
    print(f'{n:52s} {s/1e6:6.2f}  {"ok" if s < 9.6e6 else "TOO BIG"}')
