#!/usr/bin/env python3

from escpos import printer
from PIL import Image
import os
import subprocess
import random
import requests


# Return T20II printer
def get_T20II_usb():
    p = printer.Usb(0x04B8, 0x0202)  # , profile="TM-T20II")
    # p.set_with_default(align='center', font='a', bold=False, width=2, height=2, custom_size=True, smooth=True)
    return p


def get_T20II_ethernet():
    p = printer.Network("192.168.192.168", port=9100)  # , profile="TM-T20II")
    # p.set_with_default(align='center', font='a', bold=False, width=2, height=2, custom_size=True, smooth=True)
    return p


def resize_image_to_fullwidth(img_src_name, target_width=576):
    # Make fullwidth dir
    os.makedirs("img_fullwidth", exist_ok=True)

    # Open the image
    img = Image.open(img_src_name)

    # Get original dimensions
    width, height = img.size

    # Calculate new height to maintain aspect ratio
    aspect_ratio = height / width
    new_height = int(target_width * aspect_ratio)

    # Resize the image
    resized_img = img.resize((target_width, new_height), Image.LANCZOS)

    # Save the resized image
    _, ext = os.path.splitext(img_src_name)
    filename_no_ext = os.path.splitext(os.path.basename(img_src_name))[0]

    # Build destination filename
    dest_name = f"img_fullwidth/{filename_no_ext}_fullwidth{ext}"
    resized_img.save(dest_name)
    return dest_name


def get_random_bant_image():
    # Create img directory if it doesn't exist
    os.makedirs("img", exist_ok=True)

    # Fetch the catalog JSON for /bant/
    url = "https://a.4cdn.org/bant/catalog.json"
    response = requests.get(url)
    response.raise_for_status()
    catalog = response.json()

    # Flatten the list of threads from all pages
    threads = [thread for page in catalog for thread in page["threads"]]

    # Filter threads that have images (tim and ext fields)
    image_threads = [
        thread
        for thread in threads
        if "tim" in thread
        and "ext" in thread
        and thread["ext"].lower() not in [".gif", ".mp4", ".webm"]
    ]

    if not image_threads:
        return None  # No images found

    # Choose a random thread with an image
    thread = random.choice(image_threads)

    # Construct image URL
    image_url = f"https://i.4cdn.org/bant/{thread['tim']}{thread['ext']}"
    filename = f"img/{thread['tim']}{thread['ext']}"

    # Download and save image
    img_response = requests.get(image_url)
    img_response.raise_for_status()

    with open(filename, "wb") as f:
        f.write(img_response.content)

    return filename


def print_random_bant_image(p, sh_file):
    img = get_random_bant_image()
    if img is None:
        print("No images found on /bant/.")
        return
    filename_no_ext = os.path.splitext(os.path.basename(img))[0]
    p.textln(filename_no_ext)
    fimg = resize_image_to_fullwidth(img)
    try:
        p.image(fimg, impl="bitImageColumn")
    except Exception as e:
        print(f"Print failed, reconnecting: {e}")
        subprocess.run(["bash", sh_file], check=True)
        p = get_T20II_ethernet()
    p.cut()


def print_note(p, text):
    p.textln(text)
    p.cut()


def print_local_image(p, sh_file, img_path, message=None):
    if not os.path.isfile(img_path):
        print(f"File not found: {img_path}")
        return
    if message:
        p.textln(message)
    fimg = resize_image_to_fullwidth(img_path)
    try:
        p.image(fimg, impl="bitImageColumn")
    except Exception as e:
        print(f"Print failed, reconnecting: {e}")
        subprocess.run(["bash", sh_file], check=True)
        p = get_T20II_ethernet()
    p.cut()


def main():
    import argparse

    parser = argparse.ArgumentParser(description="Receipt printer CLI")
    subparsers = parser.add_subparsers(dest="command", required=True)

    subparsers.add_parser("image", help="Print a random /bant/ image")

    note_p = subparsers.add_parser("note", help="Print a text note")
    note_p.add_argument("text", help="The note to print")

    print_p = subparsers.add_parser("print", help="Print a local image")
    print_p.add_argument("path", help="Path to the image file")
    print_p.add_argument("message", nargs="?", default=None, help="Optional caption")

    args = parser.parse_args()

    script_dir = os.path.dirname(os.path.abspath(__file__))
    sh_file = os.path.join(script_dir, "connect_recipt.sh")
    subprocess.run(["bash", sh_file], check=True)
    p = get_T20II_ethernet()

    if args.command == "image":
        print_random_bant_image(p, sh_file)
    elif args.command == "note":
        print_note(p, args.text)
    elif args.command == "print":
        print_local_image(p, sh_file, args.path, args.message)


if __name__ == "__main__":
    main()
