"""
CLD Mass Update Task Queue — serve.py patch
Adds two endpoints to your existing serve.py:

  POST /task-queue        — load or update the full task list
  POST /print-next        — print the next task receipt + advance state

State file: /home/ubuntu/second-brain/task_queue.json
Printer:    192.168.12.200:9100 (ESC/POS TCP)

HOW TO DEPLOY:
  Copy the two handler blocks below into your serve.py do_POST method,
  following the same pattern as your existing /print and /turso handlers.
  Then restart: sudo systemctl restart second-brain-web
"""

import json
import socket
import os

TASK_QUEUE_FILE = "/home/ubuntu/second-brain/task_queue.json"
PRINTER_HOST = "192.168.12.200"
PRINTER_PORT = 9100


# ─── ESC/POS helpers ──────────────────────────────────────────────────────────

def esc(b): return bytes([0x1B]) + bytes([b]) if isinstance(b, int) else bytes([0x1B]) + b
def gs(b):  return bytes([0x1D]) + bytes([b]) if isinstance(b, int) else bytes([0x1D]) + b

RESET       = esc(b'@')
ALIGN_LEFT  = esc(b'\x61\x00')
ALIGN_CTR   = esc(b'\x61\x01')
BOLD_ON     = esc(b'\x45\x01')
BOLD_OFF    = esc(b'\x45\x00')
SIZE_LARGE  = gs(b'\x21\x11')   # double width + height
SIZE_NORMAL = gs(b'\x21\x00')
CUT         = gs(b'\x56\x00')
LF          = b'\n'


def build_receipt(order, total, task_text):
    """Build ESC/POS bytes for one task receipt."""
    buf = b''
    buf += RESET
    buf += ALIGN_CTR

    # Header
    buf += SIZE_NORMAL
    buf += BOLD_ON
    buf += f"TASK {order} of {total}".encode('utf-8') + LF
    buf += BOLD_OFF
    buf += b'--------------------------------' + LF
    buf += LF

    # Task text — large, bold, centered
    buf += SIZE_LARGE
    buf += BOLD_ON
    # Word-wrap at ~16 chars per line (large text ~16 chars wide on 80mm)
    words = task_text.split()
    line = ''
    for word in words:
        if len(line) + len(word) + 1 > 16:
            buf += line.strip().encode('utf-8') + LF
            line = word + ' '
        else:
            line += word + ' '
    if line.strip():
        buf += line.strip().encode('utf-8') + LF

    buf += BOLD_OFF
    buf += SIZE_NORMAL
    buf += LF
    buf += b'--------------------------------' + LF

    # Footer
    buf += ALIGN_LEFT
    buf += SIZE_NORMAL
    if order < total:
        buf += f"NEXT: task {order + 1}".encode('utf-8') + LF
    else:
        buf += b'FINAL TASK' + LF

    buf += LF + LF + LF
    buf += CUT
    return buf


def send_to_printer(data_bytes):
    """Send raw bytes to ESC/POS printer over TCP."""
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(5)
        s.connect((PRINTER_HOST, PRINTER_PORT))
        s.sendall(data_bytes)


def print_task(order, total, task_text, copies=2):
    """Print N copies of the receipt for this task."""
    receipt = build_receipt(order, total, task_text)
    send_to_printer(receipt * copies)


# ─── State helpers ────────────────────────────────────────────────────────────

def load_queue():
    if os.path.exists(TASK_QUEUE_FILE):
        with open(TASK_QUEUE_FILE, 'r') as f:
            return json.load(f)
    return {"tasks": [], "current_index": 0}


def save_queue(queue):
    with open(TASK_QUEUE_FILE, 'w') as f:
        json.dump(queue, f, indent=2)


# ─── Endpoint handlers (add these into your do_POST) ─────────────────────────

"""
Add this block inside your do_POST, alongside existing /turso and /print handlers:

    elif path == '/task-queue':
        # Load or replace the full task list
        # Body: {"tasks": ["Task one text", "Task two text", ...], "current_index": 0}
        body = json.loads(self.rfile.read(int(self.headers['Content-Length'])))
        queue = {
            "tasks": body.get("tasks", []),
            "current_index": body.get("current_index", 0)
        }
        save_queue(queue)
        response = {"status": "ok", "task_count": len(queue["tasks"]), "current_index": queue["current_index"]}
        self._respond(200, response)

    elif path == '/print-next':
        # Print the current task, advance the index
        # Optional body: {"tasks": [...], "current_index": N} to update list before printing
        content_length = int(self.headers.get('Content-Length', 0))
        if content_length > 0:
            body = json.loads(self.rfile.read(content_length))
            if 'tasks' in body:
                queue = {"tasks": body['tasks'], "current_index": body.get('current_index', 0)}
                save_queue(queue)
        
        queue = load_queue()
        tasks = queue.get("tasks", [])
        idx = queue.get("current_index", 0)

        if not tasks:
            self._respond(400, {"error": "No task queue loaded. POST to /task-queue first."})
            return
        if idx >= len(tasks):
            self._respond(400, {"error": "All tasks complete.", "total": len(tasks)})
            return

        task_text = tasks[idx]
        order = idx + 1
        total = len(tasks)

        try:
            print_task(order, total, task_text, copies=2)
            queue["current_index"] = idx + 1
            save_queue(queue)
            response = {
                "status": "printed",
                "order": order,
                "total": total,
                "task": task_text,
                "remaining": total - order
            }
            self._respond(200, response)
        except Exception as e:
            self._respond(500, {"error": str(e)})
"""


# ─── BetterTouchTool curl command for Command+9 ───────────────────────────────
#
# In BetterTouchTool, add a new Keyboard Shortcut:
#   Trigger: Command + 9
#   Action:  Run Terminal Command (or Shell Script)
#   Command: curl -s -X POST http://100.115.237.105:7001/print-next
#
# That's it. One keystroke → Pi prints next receipt → state advances.
#
# To load your task list initially, POST to /task-queue:
#   curl -s -X POST http://100.115.237.105:7001/task-queue \
#     -H "Content-Type: application/json" \
#     -d '{"tasks": ["Task one", "Task two", "Task three"], "current_index": 0}'
#
# To update mid-session (e.g. reorder or add tasks), POST to /task-queue again
# with the new list and the current_index you want to resume from.
