"""Verify the four fixes:
1. +/- steppers move by ONE unit per tap (dedupe of pointerdown+click)
2. 1/16 row: minus on LEFT, plus on RIGHT (same as inches row)
3. Name input placeholder is the auto tag (L1, L2...)
4. Full info sheet fits on screen; stepper taps don't scroll the page
"""
import os
import sys
import time

sys.stdout.reconfigure(encoding="utf-8", errors="replace")

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.service import Service

HERE = os.path.dirname(os.path.abspath(__file__))
GECKODRIVER = os.path.join(HERE, "geckodriver.exe")
BASE = "http://localhost:8000/field-capture.html?debug"

DRAW_JS = """
(function(){
  const canvas = document.getElementById('sketchCanvas');
  canvas.setPointerCapture = function(){};
  canvas.releasePointerCapture = function(){};
  canvas.hasPointerCapture = function(){ return false; };
  const rect = canvas.getBoundingClientRect();
  const opts = { bubbles: true, cancelable: true, pointerId: 1, pointerType: 'touch', isPrimary: true };
  const sx = rect.left + rect.width*0.3, sy = rect.top + rect.height*0.4;
  const ex = rect.left + rect.width*0.7, ey = rect.top + rect.height*0.6;
  canvas.dispatchEvent(new PointerEvent('pointerdown', Object.assign({}, opts, {clientX: sx, clientY: sy})));
  for (let i = 1; i <= 5; i++) canvas.dispatchEvent(new PointerEvent('pointermove', Object.assign({}, opts, {clientX: sx+(ex-sx)*i/5, clientY: sy+(ey-sy)*i/5})));
  canvas.dispatchEvent(new PointerEvent('pointerup', Object.assign({}, opts, {clientX: ex, clientY: ey})));
  return 'drawn';
})();
"""

TAP_JS = """
(function(){
  const canvas = document.getElementById('sketchCanvas');
  canvas.setPointerCapture = function(){};
  canvas.releasePointerCapture = function(){};
  canvas.hasPointerCapture = function(){ return false; };
  const rect = canvas.getBoundingClientRect();
  const opts = { bubbles: true, cancelable: true, pointerId: 3, pointerType: 'touch', isPrimary: true };
  const x = rect.left + rect.width*0.5, y = rect.top + rect.height*0.5;
  canvas.dispatchEvent(new PointerEvent('pointerdown', Object.assign({}, opts, {clientX: x, clientY: y})));
  return 'down';
})();
"""

TAPUP_JS = """
(function(){
  const canvas = document.getElementById('sketchCanvas');
  canvas.setPointerCapture = function(){};
  canvas.releasePointerCapture = function(){};
  canvas.hasPointerCapture = function(){ return false; };
  const rect = canvas.getBoundingClientRect();
  const opts = { bubbles: true, cancelable: true, pointerId: 3, pointerType: 'touch', isPrimary: true };
  const x = rect.left + rect.width*0.5, y = rect.top + rect.height*0.5;
  canvas.dispatchEvent(new PointerEvent('pointerup', Object.assign({}, opts, {clientX: x, clientY: y})));
  return 'up';
})();
"""


def main():
    opts = Options()
    opts.headless = False
    svc = Service(executable_path=GECKODRIVER)
    d = webdriver.Firefox(options=opts, service=svc)
    d.set_window_size(480, 900)
    try:
        d.get(BASE)
        time.sleep(2)
        d.find_element(By.CSS_SELECTOR, '[data-action="newjob"]').click()
        time.sleep(0.8)
        d.find_element(By.CSS_SELECTOR, '[data-action="opensketch"]').click()
        time.sleep(0.8)

        # Inject synthetic photo so the canvas renders
        d.execute_script("""
            const T = window.__test;
            const job = T.state.jobs[0];
            const sk = job.sketches[0];
            const c = document.createElement('canvas');
            c.width = 200; c.height = 150;
            const ctx = c.getContext('2d');
            ctx.fillStyle = '#cccccc'; ctx.fillRect(0,0,200,150);
            ctx.strokeStyle = '#333'; ctx.lineWidth = 4;
            ctx.beginPath(); ctx.moveTo(20,20); ctx.lineTo(180,130); ctx.stroke();
            sk.photo = { dataUrl: c.toDataURL('image/jpeg', 0.8), width: 200, height: 150 };
            T.saveState();
        """)
        d.execute_script(
            "const T=window.__test; T.ui.screen='sketch'; T.ui.sketchId=T.state.jobs[0].sketches[0].id; T.render();"
        )
        time.sleep(0.8)

        print("draw:", d.execute_script(DRAW_JS))
        time.sleep(1)

        # 1. Name input placeholder should be L1
        print("quick label input:", d.execute_script(
            "const el = document.getElementById('quickLabel'); return el ? JSON.stringify({placeholder: el.placeholder, value: el.value}) : 'missing';"
        ))

        # 2. 1/16 row button order: minus first, then plus
        print("1/16 row buttons (expect [-, +]):", d.execute_script("""
            const sheet = document.querySelector('.sheet-minimal');
            const rows = Array.from(sheet.querySelectorAll('div')).filter(d => d.textContent.trim() === '1/16');
            const row = rows[0].parentElement;
            return JSON.stringify(Array.from(row.querySelectorAll('button')).map(b => b.textContent.trim()));
        """))

        # 3. Single click steps by exactly ONE
        d.find_element(By.CSS_SELECTOR, '[data-action="stepup"][data-field="inches"]').click()
        time.sleep(0.4)
        print("after 1 click inches +:", d.execute_script(
            "const T=window.__test; const l=T.state.jobs[0].sketches[0].lines[0]; return JSON.stringify({feet:l.feet, inches:l.inches, sixteenths:l.sixteenths});"
        ))
        d.find_element(By.CSS_SELECTOR, '[data-action="stepup"][data-field="sixteenths"]').click()
        time.sleep(0.4)
        print("after 1 click 1/16 +:", d.execute_script(
            "const T=window.__test; const l=T.state.jobs[0].sketches[0].lines[0]; return JSON.stringify({feet:l.feet, inches:l.inches, sixteenths:l.sixteenths});"
        ))

        # Type a custom name in the quick sheet label input
        d.execute_script("""
            const el = document.getElementById('quickLabel');
            el.value = 'Rise';
            el.dispatchEvent(new Event('input', { bubbles: true }));
        """)
        time.sleep(0.5)
        print("label after typing Rise:", d.execute_script(
            "const T=window.__test; const l=T.state.jobs[0].sketches[0].lines[0]; return JSON.stringify({label: l.label, id: l.id});"
        ))

        # Close quick sheet, long-press line to open full info page
        d.execute_script('document.querySelector(".sheet-minimal [data-action=closesheet]").click()')
        time.sleep(0.5)
        d.execute_script(TAP_JS)
        time.sleep(0.7)
        d.execute_script(TAPUP_JS)
        time.sleep(0.8)

        sheet = d.find_elements(By.CSS_SELECTOR, '.sheet:not(.sheet-minimal)')
        print("full info sheet present:", len(sheet) > 0)
        if sheet:
            print("full sheet text:", sheet[0].text[:300].replace("\n", " | "))
            print("sheet dims:", d.execute_script("""
                const s = document.querySelector('.sheet:not(.sheet-minimal)');
                const r = s.getBoundingClientRect();
                return JSON.stringify({top: Math.round(r.top), bottom: Math.round(r.bottom), winH: window.innerHeight, fits: r.bottom <= window.innerHeight});
            """))
            print("full 1/16 row buttons:", d.execute_script("""
                const s = document.querySelector('.sheet:not(.sheet-minimal)');
                const row = s.querySelector('.stepper-row[data-stepfield="sixteenths"]');
                return JSON.stringify(Array.from(row.querySelectorAll('button')).map(b => b.textContent.trim()));
            """))
            before = d.execute_script("return window.scrollY")
            d.find_element(By.CSS_SELECTOR, '.sheet:not(.sheet-minimal) [data-action="stepup"][data-field="sixteenths"]').click()
            time.sleep(0.4)
            after = d.execute_script("return window.scrollY")
            print("scrollY before/after step:", before, after)
            print("after full sheet 1/16 +:", d.execute_script(
                "const T=window.__test; const l=T.state.jobs[0].sketches[0].lines[0]; return JSON.stringify({feet:l.feet, inches:l.inches, sixteenths:l.sixteenths});"
            ))
    finally:
        d.quit()


if __name__ == "__main__":
    main()