"""Refactored dashboard with dependency injection and better separation of concerns."""

import logging
import os
from pathlib import Path
from typing import Optional

from fastapi import Depends, FastAPI, HTTPException, Request, status
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from .auth_v2 import create_auth_dependency
from .config import ColorScheme, MonitorConfig
from .exceptions import ValidationError
from .repository import SQLiteRepository
from .services import MonitorService

logger = logging.getLogger(__name__)


class DashboardService:
    """Service for dashboard operations."""

    def __init__(self, monitor_service: MonitorService, config: MonitorConfig):
        self.monitor_service = monitor_service
        self.config = config

    async def get_dashboard_stats(self) -> dict:
        """Get formatted stats for dashboard."""
        try:
            stats_data = await self.monitor_service.get_statistics()

            return [
                {
                    "label": "Total Requests",
                    "value": f"{stats_data.total_requests:,}",
                    "icon": self._get_icon("requests"),
                },
                {
                    "label": "Avg Response Time",
                    "value": f"{stats_data.avg_response_time:.2f}ms",
                    "icon": self._get_icon("time"),
                },
                {
                    "label": "Error Rate",
                    "value": f"{stats_data.error_rate:.1f}%",
                    "icon": self._get_icon("error_rate"),
                },
                {
                    "label": "Error Count",
                    "value": f"{stats_data.error_count:,}",
                    "icon": self._get_icon("errors"),
                },
            ]
        except Exception as e:
            logger.error(f"Failed to get dashboard stats: {e}")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Failed to retrieve statistics"
            )

    def _get_icon(self, icon_type: str) -> str:
        """Get SVG icon for stat type."""
        icon_path = Path(__file__).parent / "static" / "icons" / f"{icon_type}.svg"
        if icon_path.exists():
            return icon_path.read_text()
        return ""


def create_dashboard_app(
    config_or_db_path: Optional[MonitorConfig] = None,
    monitor_service: Optional[MonitorService] = None,
    # Legacy parameters for backward compatibility
    db_path: Optional[str] = None,
    username: Optional[str] = None,
    password: Optional[str] = None,
    color_scheme: Optional[ColorScheme] = None,
) -> FastAPI:
    """Create dashboard FastAPI application with dependency injection.
    
    Args:
        config_or_db_path: Monitor configuration (preferred) or legacy db_path string
        monitor_service: Monitor service instance (optional)
        db_path: Legacy - database path
        username: Legacy - dashboard username
        password: Legacy - dashboard password
        color_scheme: Legacy - color scheme
    """

    # Handle legacy usage where first parameter is db_path string
    if isinstance(config_or_db_path, str):
        # Legacy call: create_dashboard_app("db.db", username="admin", ...)
        config = MonitorConfig(
            db_path=config_or_db_path,
            dashboard_username=username,
            dashboard_password=password,
            color_scheme=color_scheme or ColorScheme.DEFAULT
        )
    elif config_or_db_path is None:
        # Handle legacy parameters
        config = MonitorConfig(
            db_path=db_path or "monitor.db",
            dashboard_username=username,
            dashboard_password=password,
            color_scheme=color_scheme or ColorScheme.DEFAULT
        )
    else:
        # New usage with config object
        config = config_or_db_path

    # Setup services
    if monitor_service is None:
        repository = SQLiteRepository(config)
        monitor_service = MonitorService(repository, config)

    dashboard_service = DashboardService(monitor_service, config)

    # Create FastAPI app
    app = FastAPI(
        title="FastAPI Monitor Dashboard",
        description="Real-time monitoring dashboard for FastAPI applications",
        version="2.0.0"
    )

    # Setup static files and templates
    package_dir = os.path.dirname(__file__)
    app.mount(
        "/static",
        StaticFiles(directory=os.path.join(package_dir, "static")),
        name="static",
    )
    templates = Jinja2Templates(directory=os.path.join(package_dir, "templates"))

    # Setup authentication
    auth_dependency = create_auth_dependency(config)

    # Routes
    @app.get("/", response_class=HTMLResponse)
    async def dashboard(
        request: Request,
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Main dashboard page."""
        try:
            return templates.TemplateResponse(
                request=request,
                name="pages/dashboard.html",
                context={
                    "theme_mode": "light",
                    "color_scheme": config.color_scheme.value,
                    "user": user
                },
            )
        except Exception as e:
            logger.error(f"Dashboard error: {e}")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Dashboard unavailable"
            )

    @app.get("/api/stats")
    async def get_stats(user: Optional[str] = Depends(auth_dependency)):
        """Get current statistics."""
        return await monitor_service.get_statistics()

    @app.get("/api/requests")
    async def get_requests(
        page: int = 1,
        limit: int = 20,
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Get recent requests with pagination."""
        try:
            records, pagination = await monitor_service.get_recent_requests(page, limit)
            return {
                "requests": [record.dict() for record in records],
                "pagination": pagination.dict()
            }
        except ValidationError as e:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))

    @app.get("/api/requests/{request_id}")
    async def get_request_detail(
        request_id: int,
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Get detailed request information."""
        try:
            record = await monitor_service.get_request_details(request_id)
            if not record:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="Request not found"
                )
            return record.dict()
        except ValidationError as e:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))

    @app.get("/api/analytics")
    async def get_analytics(
        resolution: str = "30s",
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Get analytics data for charts."""
        try:
            return await monitor_service.get_analytics_data(resolution)
        except ValidationError as e:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))

    # HTMX partial endpoints
    @app.get("/stats")
    async def stats_partial(
        request: Request,
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Partial template for stats (HTMX)."""
        try:
            stats = await dashboard_service.get_dashboard_stats()
            return templates.TemplateResponse(
                request=request,
                name="partials/stats.html",
                context={"stats": stats}
            )
        except Exception as e:
            logger.error(f"Stats partial error: {e}")
            return HTMLResponse("Error loading stats", status_code=500)

    @app.get("/requests")
    async def requests_partial(
        request: Request,
        page: int = 1,
        limit: int = 20,
        user: Optional[str] = Depends(auth_dependency),
    ):
        """Partial template for requests table rows (HTMX)."""
        try:
            records, pagination = await monitor_service.get_recent_requests(page, limit)

            return templates.TemplateResponse(
                request=request,
                name="partials/requests.html",
                context={
                    "requests": records,
                    "pagination": pagination,
                },
            )
        except ValidationError as e:
            return HTMLResponse(f"Invalid request: {e}", status_code=400)
        except Exception as e:
            logger.error(f"Requests partial error: {e}")
            return HTMLResponse("Error loading requests", status_code=500)

    @app.get("/requests/{request_id}")
    async def request_detail_partial(
        request: Request,
        request_id: int,
        user: Optional[str] = Depends(auth_dependency),
    ):
        """Get detailed request information (HTMX)."""
        try:
            record = await monitor_service.get_request_details(request_id)
            if not record:
                return HTMLResponse("Request not found", status_code=404)

            return templates.TemplateResponse(
                request=request,
                name="components/request-details-drawer.html",
                context={"request": record},
            )
        except ValidationError as e:
            return HTMLResponse(f"Invalid request: {e}", status_code=400)
        except Exception as e:
            logger.error(f"Request detail error: {e}")
            return HTMLResponse("Error loading request details", status_code=500)

    @app.get("/analytics", response_class=HTMLResponse)
    async def analytics_page(
        request: Request,
        user: Optional[str] = Depends(auth_dependency)
    ):
        """Analytics dashboard page."""
        try:
            return templates.TemplateResponse(
                request=request,
                name="pages/analytics.html",
                context={"user": user}
            )
        except Exception as e:
            logger.error(f"Analytics page error: {e}")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Analytics page unavailable"
            )

    # Health check endpoint
    @app.get("/health")
    async def health_check():
        """Health check endpoint."""
        return {"status": "healthy", "service": "fastapi-monitor-dashboard"}

    return app


# Legacy compatibility function
def create_dashboard_app_legacy(
    db_path: str = "monitor.db",
    username: Optional[str] = None,
    password: Optional[str] = None,
    color_scheme: ColorScheme = ColorScheme.DEFAULT,
) -> FastAPI:
    """Legacy function for backward compatibility."""
    return create_dashboard_app(
        db_path=db_path,
        username=username,
        password=password,
        color_scheme=color_scheme
    )
