import sys
import json
from urllib.parse import urlparse
from http.server import HTTPServer

from sproutepy.SprouteRequestHandler import SproutRequestHandler
from sproutepy.SprouteRequest import SproutRequest


class SprouteApp:

    def __init__(self):
        self.router = None
        self.database_manager = None
        self.template_engine = None
        
    def set_router(self, router):
        self.router = router

    def set_database_manager(self, database_manager):
        self.database_manager = database_manager

    def set_template_engine(self, template_engine):
        self.template_engine = template_engine

    def strip_protocol(self, url):
        parsed_url = urlparse(url)
        return url.replace(parsed_url.scheme + "://", "") if parsed_url.scheme else url
 
    def start(self, app, host_endpoint='127.0.0.1', port=8000, debug=True):
        host = self.strip_protocol(host_endpoint)
        server_address = (host, port)

        httpd = HTTPServer(
            server_address,
            lambda *args, **kwargs: SproutRequestHandler(app, *args, **kwargs)
        )

        print(f"Serving on http://{host}:{port}")
        httpd.serve_forever()

    def handle_wsgi(self, environ, start_response):
        if not self.router:
            start_response(
                '500 Internal Server Error',
                [('Content-Type', 'text/plain')]
            )
            return [b"Router not initialized"]

        try:
            request = SproutRequest(environ)

            response = self.router.route_request(
                request.path,
                request.method,
                request.body
            )

            # ----------------------------
            # DEFAULT VALUES
            # ----------------------------
            status = '200 OK'
            headers = []
            body = b''

            # 1. Dict response (NEW STANDARD)
            if isinstance(response, dict):
                status = response.get('status', '200 OK')
                headers = response.get('headers', [('Content-Type', 'text/html')])
                body = response.get('body', b'')

                if isinstance(body, str):
                    body = body.encode()

            # 2. Tuple response
            elif isinstance(response, tuple) and len(response) == 3:
                status, headers, body = response
                if isinstance(body, str):
                    body = body.encode()

            # 3. Raw bytes
            elif isinstance(response, bytes):
                body = response
                headers = [('Content-Type', 'application/octet-stream')]

            # 4. String
            elif isinstance(response, str):
                body = response.encode()
                headers = [('Content-Type', 'text/html')]

            # 5. fallback
            else:
                body = str(response).encode()
                headers = [('Content-Type', 'text/html')]

            start_response(status, headers)
            return [body]

        except Exception as e:
            error_body = f"Internal Server Error: {str(e)}".encode()

            start_response(
                '500 Internal Server Error',
                [('Content-Type', 'text/plain')]
            )
            return [error_body]