from flask import current_app, Flask
from flask.templating import _render, render_template, render_template_string
from flask_socketio import SocketIO, emit
from werkzeug.routing import Rule
import threading, functools, os, time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class LiveServer:
    def __init__(self, app: Flask) -> None:
        self.app = app
        with self.app.app_context():
            self.app.config['TEMPLATES_AUTO_RELOAD'] = True
            self.socketio: SocketIO = SocketIO(self.app)
            @self.socketio.on('connect') 
            def _connect(): 
                emit("connected", {'success': True})
    def render_template(self, filename, **context):
        
        with open(f"./templates/{filename}", "r") as fp:
            html = fp.read()
        html += """  
<!-- Auth Generated by FlaskLiveServer -->
<script src="https://cdn.socket.io/4.0.1/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('refresh', function(msg) {
    console.log("Reload Page")
    location.reload();
});
socket.on('connected', function(msg) {
    console.log("FlaskLiveServer")
    console.log("Contact: m63#7150 | Lin_Studio#0001")
})
</script>"""
        return render_template_string(html, **context)
    def watchdog(self):
        
        class Handler(FileSystemEventHandler):
            def on_modified(self2, event): 
                if event.is_directory:
                    pass
                else:
                    Fname, Extension = os.path.splitext(os.path.basename(event.src_path))
                    name = f"{Fname}{Extension}"
                    with self.app.app_context():
                        self.socketio.emit(
                            "refresh",
                            {"success": True},
                            broadcast=True,
                        )
                    

        class Watcher:
            def __init__(self, path):
                self.event_handler = None   
                self.observer = Observer()    
                self.target_directory = path   


            def run(self):
                self.event_handler = Handler()
                self.observer.schedule(
                    self.event_handler,
                    self.target_directory,
                    recursive=False
                )

                self.observer.start()
                while True:
                    time.sleep(0.5)
        watch = Watcher("./templates")
        # watch.run()
        threading.Thread(target=watch.run).start()
    def run(self, host="0.0.0.0", port=80, *args, **kwargs):
        self.watchdog()
        with self.app.app_context():
            self.socketio.run(current_app, host=host, port=port, *args, **kwargs)