import panel as pn
import os
from typing import Literal


def share(
    view,
    __name__,
    __file__,
    sharer: Literal["pn.serve", "embed.html", "pyodide"] | int | None = 2,
    pyodide_kwargs={"runtime": "pyodide-worker", "prerender": False, "inline": False},
    panel_serve_kwargs={"port": 8000, "show": True},
):

    if __name__ == "__main__":
        if isinstance(sharer, int):
            sharer = ["pn.serve", "embed.html", "pyodide", None][sharer]
        if pn.state._is_pyodide:
            return view.servable()
        elif sharer == "pyodide":
            import panel.io.convert
            import http.server
            import socketserver
            import webbrowser

            def start_http_server(port=8000, directory=".", show=True, fn=""):
                """
                Start an HTTP server to serve files from a specific directory.

                :param port: The port to serve on (default is 8000).
                :param directory: The directory to serve files from (default is the current directory).
                """
                # Change the working directory to the specified folder
                current_workdir = os.getcwd()
                os.chdir(directory)

                # Set up the HTTP server
                handler = http.server.SimpleHTTPRequestHandler
                with socketserver.TCPServer(("", port), handler) as httpd:
                    print(f"Serving HTTP on port {port} (http://localhost:{port}/) ...")
                    print(f"Serving files from directory: {os.path.abspath(directory)}")
                    try:
                        if show:
                            webbrowser.open(f"http://localhost:{port}/{fn}")
                        httpd.serve_forever()
                    except KeyboardInterrupt:
                        print("\nShutting down the server.")
                        httpd.server_close()
                        os.chdir(current_workdir)

            source_file = os.path.abspath(__file__)
            assert os.path.isfile(source_file), f"Can't find file `{__file__}`."
            workdir = os.path.join(os.path.split(__file__)[0], "dist")
            if not os.path.isdir(workdir):
                os.mkdir(workdir)
            _ = panel.io.convert.convert_app(
                source_file,
                dest_path=workdir,
                **pyodide_kwargs,
            )
            start_http_server(
                directory=workdir,
                fn=os.path.split(source_file)[1].replace(".py", ".html"),
            )
        elif sharer == "pn.serve":
            if "server" in globals():
                print("found it in globals")
                globals()["server"].stop()
            server: pn.io.server.Server = pn.serve(view, **panel_serve_kwargs)
            globals()["server"] = server
        elif sharer == "embed.html":
            fn = os.path.split(os.path.abspath(__file__))[-1].replace(".py", ".html")
            view.save(fn, embed=True, max_opts=50, embed_json=False)
        else:
            ...
    else:
        return view.servable()
