"""Simple HTTP file server for serving files in web mode."""

import threading
import socket
import logging
from http.server import HTTPServer, SimpleHTTPRequestHandler
from pathlib import Path
from typing import Optional
import mimetypes
import urllib.parse

logger = logging.getLogger(__name__)

# Global server instance
_file_server: Optional[HTTPServer] = None
_server_thread: Optional[threading.Thread] = None
_server_port: int = 8001


class FileServerHandler(SimpleHTTPRequestHandler):
    """HTTP request handler for file serving."""

    def do_GET(self):
        """Handle GET requests."""
        # Parse the path
        parsed_path = urllib.parse.urlparse(self.path)
        file_path = urllib.parse.unquote(parsed_path.path)

        # Remove leading slash
        if file_path.startswith("/"):
            file_path = file_path[1:]

        # Decode the file path (it's URL encoded)
        try:
            full_path = Path(file_path).resolve()

            # Security check: ensure the path is within allowed directories
            # For now, allow all paths (can be restricted later)

            if full_path.is_file() and full_path.exists():
                # Serve the file
                logger.debug(f"Serving file: {full_path}")

                # Determine content type
                content_type, _ = mimetypes.guess_type(str(full_path))
                if content_type is None:
                    content_type = "application/octet-stream"

                try:
                    with open(full_path, "rb") as f:
                        file_content = f.read()

                    self.send_response(200)
                    self.send_header("Content-type", content_type)
                    self.send_header("Content-Length", str(len(file_content)))
                    self.send_header(
                        "Content-Disposition",
                        f'attachment; filename="{full_path.name}"'
                    )
                    self.end_headers()
                    self.wfile.write(file_content)
                    logger.info(f"Successfully served file: {full_path.name}")
                    return
                except Exception as e:
                    logger.error(f"Error serving file: {e}")
                    self.send_error(500, "Internal server error")
                    return
            else:
                logger.warning(f"File not found: {full_path}")
                self.send_error(404, "File not found")
                return

        except Exception as e:
            logger.error(f"Error handling request: {e}")
            self.send_error(400, "Bad request")

    def log_message(self, format, *args):
        """Override to use our logger instead of stderr."""
        logger.debug(format % args)


def get_local_ip() -> Optional[str]:
    """Get the local IP address that's accessible from other devices."""
    try:
        # Connect to a remote server to determine local IP
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception as e:
        logger.warning(f"Failed to determine local IP: {e}")
        return None


def start_file_server(port: int = 8001) -> Optional[str]:
    """Start the HTTP file server.

    Args:
        port: Port to serve on

    Returns:
        Server URL if successful, None otherwise
    """
    global _file_server, _server_thread, _server_port

    if _file_server is not None:
        logger.debug(f"File server already running on port {_server_port}")
        local_ip = get_local_ip()
        if local_ip:
            return f"http://{local_ip}:{_server_port}"
        return None

    try:
        _server_port = port

        # Create server
        server_address = ("", port)
        _file_server = HTTPServer(server_address, FileServerHandler)

        # Start in daemon thread
        _server_thread = threading.Thread(
            target=_file_server.serve_forever,
            daemon=True
        )
        _server_thread.start()

        logger.info(f"File server started on port {port}")

        # Get local IP
        local_ip = get_local_ip()
        if local_ip:
            server_url = f"http://{local_ip}:{port}"
            logger.info(f"File server accessible at: {server_url}")
            return server_url
        else:
            logger.warning("Could not determine local IP")
            return None

    except Exception as e:
        logger.error(f"Failed to start file server: {e}")
        _file_server = None
        _server_thread = None
        return None


def stop_file_server():
    """Stop the HTTP file server."""
    global _file_server, _server_thread

    if _file_server is not None:
        try:
            _file_server.shutdown()
            _file_server.server_close()
            logger.info("File server stopped")
        except Exception as e:
            logger.error(f"Error stopping file server: {e}")
        finally:
            _file_server = None
            _server_thread = None


def get_file_url(file_path: Path, server_url: Optional[str] = None) -> Optional[str]:
    """Get the HTTP URL for a file.

    Args:
        file_path: Path to the file
        server_url: Base server URL (gets determined if None)

    Returns:
        HTTP URL to the file, or None if server not running
    """
    if not file_path.exists():
        logger.warning(f"File does not exist: {file_path}")
        return None

    if server_url is None:
        local_ip = get_local_ip()
        if not local_ip:
            logger.error("Cannot determine local IP for file URL")
            return None
        server_url = f"http://{local_ip}:{_server_port}"

    # URL encode the file path
    encoded_path = urllib.parse.quote(str(file_path.resolve()))
    return f"{server_url}/{encoded_path}"
