#!/usr/bin/env python3
"""Serve the ACCI Systems Pricer on localhost for the sales team."""
from __future__ import annotations

import argparse
import functools
import os
import socket
import sys
import webbrowser
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]


class Handler(SimpleHTTPRequestHandler):
    extensions_map = {
        **SimpleHTTPRequestHandler.extensions_map,
        ".pdf": "application/pdf",
        ".json": "application/json",
        ".webmanifest": "application/manifest+json",
        ".js": "text/javascript",
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=str(ROOT), **kwargs)

    def end_headers(self):
        self.send_header("Cache-Control", "no-cache")
        super().end_headers()

    def log_message(self, fmt, *args):
        sys.stderr.write("[pricer] " + (fmt % args) + "\n")


def free_port(preferred: int) -> int:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            s.bind(("127.0.0.1", preferred))
            return preferred
        except OSError:
            s.bind(("127.0.0.1", 0))
            return s.getsockname()[1]


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--port", type=int, default=8765)
    ap.add_argument("--host", default="0.0.0.0", help="Bind address (0.0.0.0 = LAN/Tailscale)")
    ap.add_argument("--no-open", action="store_true")
    args = ap.parse_args()
    port = free_port(args.port)
    host = args.host
    # Prefer Tailscale / LAN URLs for remote phones
    urls = [f"http://127.0.0.1:{port}/app/"]
    try:
        import subprocess
        ts = subprocess.check_output(["tailscale", "ip", "-4"], text=True).strip().splitlines()
        if ts:
            urls.append(f"http://{ts[0]}:{port}/app/")
    except Exception:
        pass
    # common LAN
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        lan = s.getsockname()[0]
        s.close()
        if lan and not lan.startswith("127."):
            u = f"http://{lan}:{port}/app/"
            if u not in urls:
                urls.append(u)
    except Exception:
        pass

    httpd = ThreadingHTTPServer((host, port), Handler)
    print("i-poxy")
    for u in urls:
        print(f"Open: {u}")
    print(f"Root: {ROOT}")
    print("Ctrl+C to stop")
    if not args.no_open:
        try:
            webbrowser.open(urls[0])
        except Exception:
            pass
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nStopped.")


if __name__ == "__main__":
    main()
