import React, { useState, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/dashboard/ui/card";
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  Tooltip,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
} from "recharts";
import { Loader2, AlertTriangle } from "lucide-react";
import {
  Tooltip as UITooltip,
  TooltipContent,
  TooltipTrigger,
  TooltipProvider,
} from "@/components/dashboard/ui/tooltip";
import { Alert, AlertDescription } from "@/components/dashboard/ui/alert";
import { Button } from "@/components/dashboard/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/dashboard/ui/tabs";
import {
  Table,
  TableHeader,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
} from "@/components/dashboard/ui/table";
import { format } from "date-fns";
import { Skeleton } from "@/components/dashboard/ui/skeleton";

export const METRIC_COLORS = {
  activeUsers: {
    color: "#8b5cf6",
    className: "text-purple-600 dark:text-purple-400",
  },
  pages: {
    color: "#10b981",
    className: "text-emerald-600 dark:text-emerald-400",
  },
  sources: {
    color: "#f59e0b",
    className: "text-amber-600 dark:text-amber-400",
  },
};

export const summaryCard = (label, sublabel, value, options = {}) => {
  const {
    colorClass = "text-gray-900 dark:text-gray-100",
    titleClass = "text-sm font-medium text-gray-500 dark:text-gray-400",
    descriptionClass = "text-sm text-gray-600 dark:text-gray-300",
    background = "bg-white dark:bg-gray-900/60",
    icon: Icon,
    iconColor,
    iconBackground
  } = options;

  return (
    <Card className={`w-full ${background} backdrop-blur-sm`}>
      <CardHeader className="flex flex-row items-center justify-between space-y-0 px-4 py-2">
        <CardTitle className={titleClass}>
          {label}
        </CardTitle>
        {Icon && (
          <div className="relative p-2">
            <div className={`absolute inset-0 rounded-full ${iconBackground}`} />
            <Icon className={`h-5 w-5 ${iconColor} relative`} />
          </div>
        )}
      </CardHeader>
      <CardContent className="px-4 pt-0 pb-2">
        <div className="space-y-2">
          <div>
            <div className={`text-3xl font-extrabold ${colorClass}`}>
              {value.toLocaleString()}
            </div>
            <div className={descriptionClass}>
              {sublabel}
            </div>
          </div>
        </div>
      </CardContent>
    </Card>
  );
};

export const SkeletonSummaryCard = () => (
  <Card className="bg-white dark:bg-gray-900/60 backdrop-blur-sm">
    <CardHeader className="flex flex-row items-center justify-between space-y-0 px-4 py-2">
      <Skeleton className="h-4 w-24 bg-muted" />
    </CardHeader>
    <CardContent className="px-4 pt-0 pb-2">
      <Skeleton className="h-8 w-20 mb-1 bg-muted" />
      <Skeleton className="h-4 w-32 bg-muted" />
    </CardContent>
  </Card>
);

export const SkeletonBarChart = () => (
  <div className="h-[235px] bg-white dark:bg-gray-900/60 backdrop-blur-sm rounded-lg p-4">
    <div className="h-full relative">
      {/* Grid lines */}
      {[...Array(5)].map((_, i) => (
        <div
          key={i}
          className="absolute w-full h-px bg-muted"
          style={{ top: `${(i + 1) * 20}%` }}
        />
      ))}
      {/* Y-axis labels */}
      <div className="absolute left-0 top-0 bottom-0 w-8 flex flex-col justify-between py-4">
        {[...Array(5)].map((_, i) => (
          <Skeleton key={i} className="h-3 w-6 bg-muted" />
        ))}
      </div>
      {/* X-axis labels */}
      <div className="absolute left-8 right-4 bottom-0 flex justify-between">
        {[...Array(6)].map((_, i) => (
          <Skeleton key={i} className="h-3 w-8 bg-muted" />
        ))}
      </div>
      {/* Bars */}
      <div className="absolute inset-x-8 bottom-6 top-4 flex items-end justify-between">
        {[...Array(30)].map((_, i) => (
          <div
            key={i}
            className="w-1.5 bg-muted"
            style={{
              height: `${Math.random() * 80 + 10}%`,
            }}
          />
        ))}
      </div>
    </div>
  </div>
);

export const SkeletonTable = () => (
  <div className="space-y-2 h-[230px] overflow-y-auto">
    <Table>
      <TableHeader>
        <TableRow className="dark:border-gray-800">
          <TableHead>
            <Skeleton className="h-4 w-32 bg-muted" />
          </TableHead>
          <TableHead className="text-right">
            <Skeleton className="h-4 w-24 ml-auto bg-muted" />
          </TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {[...Array(8)].map((_, i) => (
          <TableRow key={i} className="dark:border-gray-800">
            <TableCell>
              <Skeleton className="h-4 w-48 bg-muted" />
            </TableCell>
            <TableCell className="text-right">
              <Skeleton className="h-4 w-12 ml-auto bg-muted" />
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  </div>
);

export const processBasicData = (data) => {
  const last30MinUsers = parseInt(
    data.userResponse?.rows?.[0]?.metricValues?.[0]?.value || 0
  );
  const last5MinUsers = parseInt(
    data.fiveMinResponse?.rows?.[0]?.metricValues?.[0]?.value || 0
  );

  const byMinute = Array.from({ length: 30 }, (_, i) => {
    const matchingRow = data.timeSeriesResponse?.rows?.find(
      (row) => parseInt(row.dimensionValues[0].value) === i
    );
    const users = matchingRow
      ? parseInt(matchingRow.metricValues[0].value)
      : 0;
    const timestamp = new Date(Date.now() - i * 60000);
    return {
      minute: -i,
      users,
      timestamp: timestamp.toLocaleTimeString([], {
        hour: "2-digit",
        minute: "2-digit",
      }),
    };
  }).reverse();

  const tokenQuota = data.quotaInfo
    ? {
        projectHourly: data.quotaInfo.projectHourly || {},
        daily: data.quotaInfo.daily || {},
        serverErrors: data.quotaInfo.serverErrors || {},
        thresholdedRequests: data.quotaInfo.thresholdedRequests || {},
      }
    : null;

  return {
    last30MinUsers,
    last5MinUsers,
    byMinute,
    tokenQuota,
    lastUpdated: new Date().toISOString(),
  };
};

export const QuotaInfo = ({ tokenQuota }) => {
  if (!tokenQuota || typeof tokenQuota !== "object") return null;

  const {
    projectHourly = {},
    daily = {},
    serverErrors = {},
    thresholdedRequests = {},
  } = tokenQuota;

  const {
    remaining: projectHourlyRemaining = 0,
    consumed: projectHourlyConsumed = 0,
  } = projectHourly;

  const { remaining: dailyRemaining = 0, consumed: dailyConsumed = 0 } = daily;

  const { remaining: errorsRemaining = 10, consumed: errorsConsumed = 0 } =
    serverErrors;

  const {
    remaining: thresholdRemaining = 120,
    consumed: thresholdConsumed = 0,
  } = thresholdedRequests;

  const hourlyPercentage = ((projectHourlyRemaining / 14000) * 100).toFixed(1);
  const dailyPercentage = ((dailyRemaining / 200000) * 100).toFixed(1);
  const errorPercentage = ((errorsRemaining / 10) * 100).toFixed(1);
  const thresholdPercentage = ((thresholdRemaining / 120) * 100).toFixed(1);

  const getStatusColor = (percentage) => {
    const numericPercentage = parseFloat(percentage);
    if (isNaN(numericPercentage) || numericPercentage < 20)
      return "text-red-500 dark:text-red-400";
    if (numericPercentage < 40) return "text-yellow-500 dark:text-yellow-400";
    return "text-green-500 dark:text-green-400";
  };

  return (
    <>
      <div className="flex items-center font-semibold rounded-md space-x-1">
        <span>Quota:</span>
        <span className={`font-medium ${getStatusColor(hourlyPercentage)}`}>
          {hourlyPercentage}%
        </span>
      </div>

      <div className="dark:border-gray-700">
        <div className="space-y-3 mt-2">
          <div>
            <div className="font-semibold text-gray-100">
              Project Hourly
            </div>
            <div className={`${getStatusColor(hourlyPercentage)}`}>
              {projectHourlyRemaining.toLocaleString()} / 14,000 remaining
            </div>
          </div>
          <div>
            <div className="font-semibold text-gray-100">
              Daily
            </div>
            <div className={`${getStatusColor(dailyPercentage)}`}>
              {dailyRemaining.toLocaleString()} / 200,000 remaining
            </div>
          </div>
          <div>
            <div className="font-semibold text-gray-100">
              Server Errors
            </div>
            <div className={`${getStatusColor(errorPercentage)}`}>
              {errorsConsumed} / 10 used this hour
            </div>
          </div>
          <div>
            <div className="font-semibold text-gray-100">
              Thresholded Requests
            </div>
            <div className={`${getStatusColor(thresholdPercentage)}`}>
              {thresholdConsumed} / 120 used this hour
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export const RealtimeAnalytics = () => {
  const [basicData, setBasicData] = useState({
    last30MinUsers: 0,
    last5MinUsers: 0,
    byMinute: [],
    tokenQuota: null,
    lastUpdated: null,
  });

  const [detailedData, setDetailedData] = useState({
    currentPages: [],
    sources: [],
    recentEvents: [],
    lastUpdated: null,
  });
  const [loading, setLoading] = useState(true);
  const [isPaused, setIsPaused] = useState(false);
  const [error, setError] = useState(null);

  const processDetailedData = (data) => {
    return {
      currentPages:
        data.pageResponse?.rows?.map((row) => ({
          path: row.dimensionValues[0].value,
          activeUsers: parseInt(row.metricValues[0].value),
        })) || [],

      sources:
        data.sourceResponse?.rows?.map((row) => ({
          source: row.dimensionValues[0].value,
          activeUsers: parseInt(row.metricValues[0].value),
        })) || [],

      recentEvents:
        data.eventResponse?.rows
          ?.filter(
            (row) =>
              !["session_start", "(other)"].includes(
                row.dimensionValues[0].value
              )
          )
          .map((row) => ({
            event: row.dimensionValues[0].value,
            count: parseInt(row.metricValues[0].value),
          })) || [],
      lastUpdated: new Date().toISOString(),
    };
  };

  useEffect(() => {
    let basicInterval;
    let detailedInterval;

    const fetchBasicData = async () => {
      if (isPaused) return;
      try {
        const response = await fetch("/api/dashboard-analytics/realtime/basic", {
          credentials: "include",
        });

        if (!response.ok) {
          throw new Error("Failed to fetch basic realtime data");
        }

        const result = await response.json();
        const processed = processBasicData(result.data);
        setBasicData(processed);
        setError(null);
      } catch (error) {
        console.error("Error details:", {
          message: error.message,
          stack: error.stack,
          response: error.response,
        });
        if (error.message === "QUOTA_EXCEEDED") {
          setError("Quota exceeded. Analytics paused until manually resumed.");
          setIsPaused(true);
        } else {
          setError("Failed to fetch analytics data");
        }
      }
    };

    const fetchDetailedData = async () => {
      if (isPaused) return;
      try {
        const response = await fetch("/api/dashboard-analytics/realtime/detailed", {
          credentials: "include",
        });

        if (!response.ok) {
          throw new Error("Failed to fetch detailed realtime data");
        }

        const result = await response.json();
        const processed = processDetailedData(result.data);
        setDetailedData(processed);
      } catch (error) {
        console.error("Failed to fetch detailed realtime data:", error);
        if (error.message === "QUOTA_EXCEEDED") {
          setError("Quota exceeded. Analytics paused until manually resumed.");
          setIsPaused(true);
        } else {
          setError("Failed to fetch analytics data");
        }
      } finally {
        setLoading(false);
      }
    };

    // Initial fetches
    fetchBasicData();
    fetchDetailedData();

    // Set up intervals
    basicInterval = setInterval(fetchBasicData, 30000); // 30 seconds
    detailedInterval = setInterval(fetchDetailedData, 300000); // 5 minutes

    return () => {
      clearInterval(basicInterval);
      clearInterval(detailedInterval);
    };
  }, [isPaused]);

  const togglePause = () => {
    setIsPaused(!isPaused);
  };

  if (loading && !basicData && !detailedData) {
    return (
      <Card className="w-full bg-white dark:bg-gray-900/60 backdrop-blur-sm h-full">
        <CardHeader className="p-6 pb-2">
          <div className="flex justify-between items-center">
            <CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">
              Real-Time Analytics
            </CardTitle>
            <Skeleton className="h-4 w-32 bg-muted" />
          </div>
        </CardHeader>

        <CardContent className="p-6 pt-0">
          <div className="grid grid-cols-2 gap-2 md:gap-3 mt-1 mb-3">
            <SkeletonSummaryCard />
            <SkeletonSummaryCard />
          </div>

          <div className="space-y-4">
            <div className="flex gap-2">
              {[...Array(3)].map((_, i) => (
                <Skeleton key={i} className="h-8 w-20 bg-muted rounded-md" />
              ))}
            </div>
            <SkeletonBarChart />
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className="w-full bg-white dark:bg-gray-900/60 backdrop-blur-sm h-full">
      <CardHeader className="p-6 pb-2">
        <div className="flex justify-between items-center">
          <CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">
            Real-Time Analytics
          </CardTitle>
          <div className="flex items-end">
            <TooltipProvider>
              <UITooltip>
                <TooltipTrigger>
                  <div className="text-xs text-muted-foreground">
                    Last updated:{" "}
                    {format(new Date(basicData.lastUpdated), "h:mm a")}
                  </div>
                </TooltipTrigger>
                <TooltipContent className="p-3">
                  <QuotaInfo tokenQuota={basicData.tokenQuota} />
                </TooltipContent>
              </UITooltip>
            </TooltipProvider>
          </div>
        </div>
      </CardHeader>

      <CardContent className="p-6 pt-0">
        {error && (
          <Alert variant="destructive" className="mb-4">
            <AlertTriangle className="h-4 w-4" />
            <AlertDescription>{error}</AlertDescription>
          </Alert>
        )}

        <div className="grid grid-cols-2 gap-4 mt-1 mb-3">
          {summaryCard(
            "Last 30 minutes",
            "Active users",
            basicData.last30MinUsers,
            { colorClass: METRIC_COLORS.activeUsers.className }
          )}
          {summaryCard(
            "Last 5 minutes",
            "Active users",
            basicData.last5MinUsers,
            { colorClass: METRIC_COLORS.activeUsers.className }
          )}
        </div>

        <Tabs defaultValue="activity" className="w-full">
          <TabsList className="mb-4">
            <TabsTrigger value="activity">Activity</TabsTrigger>
            <TabsTrigger value="pages">Current Pages</TabsTrigger>
            <TabsTrigger value="sources">Traffic Sources</TabsTrigger>
          </TabsList>

          <TabsContent value="activity">
            <div className="h-[235px] bg-card rounded-lg">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart
                  data={basicData.byMinute}
                  margin={{ top: 5, right: 5, left: -35, bottom: -5 }}
                >
                  <XAxis
                    dataKey="minute"
                    tickFormatter={(value) => value + "m"}
                    className="text-xs"
                    tick={{ fill: "currentColor" }}
                  />
                  <YAxis className="text-xs" tick={{ fill: "currentColor" }} />
                  <Tooltip
                    content={({ active, payload }) => {
                      if (active && payload && payload.length) {
                        const timestamp = new Date(
                          Date.now() + payload[0].payload.minute * 60000
                        );
                        return (
                          <Card className="p-3 shadow-lg bg-white dark:bg-gray-800 border-none">
                            <CardContent className="p-0 space-y-2">
                              <p className="font-medium text-sm border-b pb-1 mb-2">
                                {format(timestamp, "h:mm a")}
                              </p>
                              <div className="flex justify-between items-center text-sm">
                                <span
                                  style={{
                                    color: METRIC_COLORS.activeUsers.color,
                                  }}
                                >
                                  Active Users:
                                </span>
                                <span className="font-medium ml-4">
                                  {payload[0].value.toLocaleString()}
                                </span>
                              </div>
                            </CardContent>
                          </Card>
                        );
                      }
                      return null;
                    }}
                  />
                  <Bar dataKey="users" fill={METRIC_COLORS.activeUsers.color} />
                </BarChart>
              </ResponsiveContainer>
            </div>
          </TabsContent>

          <TabsContent value="pages">
            <div className="space-y-2 h-[230px] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-200 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent hover:scrollbar-thumb-gray-300 dark:hover:scrollbar-thumb-gray-600">
              <Table>
                <TableHeader>
                  <TableRow className="dark:border-gray-800">
                    <TableHead className="text-gray-900 dark:text-gray-100">
                      Page
                    </TableHead>
                    <TableHead className="text-right text-gray-900 dark:text-gray-100">
                      Active Users
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {detailedData.currentPages.map((page, index) => (
                    <TableRow key={index} className="dark:border-gray-800">
                      <TableCell className="font-medium text-gray-900 dark:text-gray-100">
                        {page.path}
                      </TableCell>
                      <TableCell
                        className={`text-right ${METRIC_COLORS.pages.className}`}
                      >
                        {page.activeUsers}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </TabsContent>

          <TabsContent value="sources">
            <div className="space-y-2 h-[230px] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-200 dark:scrollbar-thumb-gray-700 scrollbar-track-transparent hover:scrollbar-thumb-gray-300 dark:hover:scrollbar-thumb-gray-600">
              <Table>
                <TableHeader>
                  <TableRow className="dark:border-gray-800">
                    <TableHead className="text-gray-900 dark:text-gray-100">
                      Source
                    </TableHead>
                    <TableHead className="text-right text-gray-900 dark:text-gray-100">
                      Active Users
                    </TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {detailedData.sources.map((source, index) => (
                    <TableRow key={index} className="dark:border-gray-800">
                      <TableCell className="font-medium text-gray-900 dark:text-gray-100">
                        {source.source}
                      </TableCell>
                      <TableCell
                        className={`text-right ${METRIC_COLORS.sources.className}`}
                      >
                        {source.activeUsers}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          </TabsContent>
        </Tabs>
      </CardContent>
    </Card>
  );
};

export default RealtimeAnalytics;
