import { useCallback, useEffect, useMemo, useState } from "react";
import {
  Box,
  Button,
  Card,
  CircularProgress,
  Grid,
  Stack,
  Typography,
} from "@mui/joy";
import { AlertTriangle, RefreshCw } from "lucide-react";
import { Navigate, useLocation, useNavigate } from "react-router";
import { apiClient } from "../lib/api";
import { useAuth } from "../context/auth-context";
import { TopStatsGrid } from "../components/dashboard/top-stats-grid";
import { ServerLoadCard } from "../components/dashboard/server-load-card";
import { ProjectsListCard } from "../components/dashboard/projects-list-card";
import { CpuInfoDto, ProjectDto } from "@sigma/common";
import { DashboardSummary } from "../components/dashboard/types";

function buildDashboardSummary(
  projects: ProjectDto[],
  cpuUsage: number
): DashboardSummary {
  const totals = projects.reduce(
    (acc, project) => {
      acc.totalFunctions += project.functions?.length ?? 0;
      acc.totalInvocations += project.functionsInvocationCount ?? 0;
      acc.totalErrors += project.functionsErrorCount ?? 0;
      acc.quotaTotal += project.cpuTimeQuotaMsPerMinute ?? 0;
      acc.quotaUsed += project.cpuTimeUsedMs ?? 0;
      return acc;
    },
    {
      totalFunctions: 0,
      totalInvocations: 0,
      totalErrors: 0,
      quotaTotal: 0,
      quotaUsed: 0,
    }
  );

  return {
    totalProjects: projects.length,
    totalFunctions: totals.totalFunctions,
    totalInvocations: totals.totalInvocations,
    totalErrors: totals.totalErrors,
    quotaUsed: totals.quotaUsed,
    quotaTotal: totals.quotaTotal,
    serverLoadPercent: cpuUsage,
  };
}

export function Dashboard() {
  const location = useLocation();
  const navigate = useNavigate();
  const { isAuthenticated, loading: authLoading } = useAuth();
  const [projects, setProjects] = useState<ProjectDto[]>([]);
  const [cpuUsage, setCpuUsage] = useState<number>(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null);

  const fetchProjects = useCallback(async () => {
    setLoading(true);
    setError(null);

    try {
      const { data } = await apiClient.get<ProjectDto[]>("/projects");
      setProjects(data);
      setLastUpdated(new Date());
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "Unable to load projects right now"
      );
    } finally {
      setLoading(false);
    }
  }, []);

  const updateCpuUsage = useCallback(async () => {
    try {
      const { data } = await apiClient.get<CpuInfoDto>("/health/cpu");

      setCpuUsage(data.usage);
    } catch (err) {
      console.error("Failed to fetch CPU usage:", err);
    }
  }, [setCpuUsage]);

  useEffect(() => {
    fetchProjects();
  }, [fetchProjects]);

  useEffect(() => {
    const interval = setInterval(() => updateCpuUsage(), 1000);

    return () => clearInterval(interval);
  }, [updateCpuUsage]);

  const summary = useMemo(
    () => buildDashboardSummary(projects, cpuUsage),
    [projects, cpuUsage]
  );

  const handleCreateProject = () => {
    navigate("/projects/new");
  };

  if (!authLoading && !isAuthenticated) {
    return (
      <Navigate
        to="/login"
        replace
        state={{ from: location.pathname ?? "/" }}
      />
    );
  }

  return (
    <Box sx={{ p: 3, display: "flex", flexDirection: "column", gap: 3 }}>
      <Stack direction="row" alignItems="center" justifyContent="space-between">
        <Box>
          <Typography level="h2" fontWeight={700}>
            Dashboard
          </Typography>
          <Typography level="body-sm" textColor="neutral.500">
            Realtime overview of project health and usage
          </Typography>
        </Box>
        <Stack direction="row" gap={1} alignItems="center">
          {lastUpdated ? (
            <Typography level="body-xs" textColor="neutral.500">
              Updated {lastUpdated.toLocaleTimeString()}
            </Typography>
          ) : null}
          <Button
            size="sm"
            startDecorator={<RefreshCw size={16} />}
            variant="outlined"
            color="neutral"
            onClick={fetchProjects}
            disabled={loading}
          >
            Refresh
          </Button>
        </Stack>
      </Stack>

      {loading ? (
        <Stack alignItems="center" justifyContent="center" sx={{ py: 6 }}>
          <CircularProgress size="lg" />
          <Typography level="body-sm" textColor="neutral.500" mt={1.5}>
            Loading usage data…
          </Typography>
        </Stack>
      ) : error ? (
        <Card variant="soft" color="danger">
          <Stack direction="row" alignItems="center" gap={1.5}>
            <AlertTriangle size={20} />
            <Box>
              <Typography level="title-sm">Unable to load dashboard</Typography>
              <Typography level="body-sm">{error}</Typography>
            </Box>
          </Stack>
        </Card>
      ) : (
        <>
          <TopStatsGrid summary={summary} />

          <Grid container spacing={2} mt={2}>
            <Grid xs={12} lg={8}>
              <ProjectsListCard
                projects={projects}
                onCreateProject={handleCreateProject}
              />
            </Grid>
            <Grid xs={12} lg={4}>
              <ServerLoadCard summary={summary} />
            </Grid>
          </Grid>
        </>
      )}
    </Box>
  );
}
