TypeError: Cannot read properties of undefined (reading 'toFixed')
    at StatisticsCards (webpack-internal:///(app-pages-browser)/./components/StatisticsCards.tsx:62:60)
    at react-stack-bottom-frame (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:22339:20)
    at renderWithHooks (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:5731:22)
    at updateFunctionComponent (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:7992:19)
    at updateSimpleMemoComponent (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:7843:14)
    at updateMemoComponent (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:7776:13)
    at beginWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:10077:18)
    at runWithFiberInDEV (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:544:16)
    at performUnitOfWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14986:22)
    at workLoopSync (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14816:41)
    at renderRootSync (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14794:11)
    at performWorkOnRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14329:46)
    at performWorkOnRootViaSchedulerTask (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15843:7)
    at MessagePort.performWorkUntilDeadline (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:44:48)
"""
// components/AdvancedAnalyticsDashboard.tsx

'use client';

import React, { useState, useEffect, useMemo, useCallback } from 'react';
import StatisticsCards from './StatisticsCards';
import Filters from './Filters';
import ChecksOverTimeChart from './Charts/ChecksOverTimeChart';
import StatusCodeDistributionChart from './Charts/StatusCodeDistributionChart';
import UptimePerUrlChart from './Charts/UptimePerUrlChart';
import ResponseTimeDistributionChart from './Charts/ResponseTimeDistributionChart';
import TopSlowestUrlsTable from './Tables/TopSlowestUrlsTable';
import RecentIssuesTable from './Tables/RecentIssuesTable';
import LoadingIndicator from './LoadingIndicator';
import { useToast } from "../hooks/use-toast";
import { Button } from "@/components/ui/button";
import { RefreshCw, Loader2 } from 'lucide-react';
import { DateRange } from 'react-day-picker';
import { analyticsService } from '../app/services/analytics.service';
import { AnalyticsData } from '../app/types/api.types';
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

const AdvancedAnalyticsDashboard: React.FC = () => {
  // State
  const [analytics, setAnalytics] = useState<AnalyticsData | null>(null);
  const [dateRange, setDateRange] = useState<DateRange | undefined>({
    from: new Date(new Date().setDate(new Date().getDate() - 30)),
    to: new Date(),
  });
  const [groupBy, setGroupBy] = useState<string>('day');
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [isRealtime, setIsRealtime] = useState<boolean>(false);
  const [urlFilter, setUrlFilter] = useState<string>('');
  const [statusCodeFilter, setStatusCodeFilter] = useState<string>('');
  const [responseTimeRange, setResponseTimeRange] = useState<number[]>([0, 5000]);
  const { toast } = useToast();

  // Helper function to convert the react-day-picker DateRange to your custom DateRange
  const mapDateRange = (
    range: DateRange | undefined
  ): import('../app/types/api.types').DateRange | undefined => {
    if (!range) return undefined;
    return {
      from: range.from || new Date(), // Default date if undefined
      to: range.to || new Date(),
    };
  };
  // Fetch Analytics Data
  const loadAnalytics = useCallback(async () => {
    setIsLoading(true);
    try {
      const data = await analyticsService.getAnalytics();
      setAnalytics(data);
    } catch (error: any) {
      console.error('Failed to fetch analytics:', error);
      // Display a toast notification for errors other than unauthorized access
      if (error.response && error.response.status !== 401 && error.response.status !== 403) {
        toast({
          title: "Error",
          description: "Failed to fetch analytics data. Please try again.",
          variant: "destructive",
        });
      }
      // Unauthorized access is handled within the service by redirecting to login
    } finally {
      setIsLoading(false);
    }
  }, [toast]);

  // Initial Load
  useEffect(() => {
    loadAnalytics();
  }, [loadAnalytics]);

  // Realtime Updates
  useEffect(() => {
    if (isRealtime) {
      const interval = setInterval(() => {
        loadAnalytics();
      }, 5000); // Refresh every 5 seconds in realtime mode
      return () => clearInterval(interval);
    }
  }, [isRealtime, loadAnalytics]);

  // Filtered Checks Over Time (if needed)
  const filteredChecksOverTime = useMemo(() => {
    if (!analytics) return [];
    return analytics.checksOverTime.filter(check => {
      const checkDate = new Date(check.date);
      return (!dateRange?.from || checkDate >= dateRange.from) && (!dateRange?.to || checkDate <= dateRange.to);
    });
  }, [analytics, dateRange]);

  if (isLoading && !analytics) {
    return <LoadingIndicator />;
  }

  return (
    <div className="container mx-auto p-4 space-y-8">
      {/* Header */}
      <div className="flex flex-col md:flex-row md:justify-between md:items-center gap-4">
        <h1 className="text-4xl font-bold">Advanced Analytics Dashboard</h1>
        <div className="flex items-center space-x-4">
          <Switch
            checked={isRealtime}
            onCheckedChange={setIsRealtime}
            id="realtime-mode"
          />
          <Label htmlFor="realtime-mode">Realtime Updates</Label>
          <Button onClick={loadAnalytics} disabled={isLoading} variant="secondary">
            {isLoading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <RefreshCw className="mr-2 h-4 w-4" />}
            Refresh Data
          </Button>
        </div>
      </div>

      {/* Statistics Cards */}
      {analytics && <StatisticsCards analytics={analytics} />}

      {/* Filters */}
      <Filters
        dateRange={mapDateRange(dateRange)} // Apply mapping here
        setDateRange={(range) => setDateRange(range)}
        groupBy={groupBy}
        setGroupBy={setGroupBy}
        urlFilter={urlFilter}
        setUrlFilter={setUrlFilter}
        statusCodeFilter={statusCodeFilter}
        setStatusCodeFilter={setStatusCodeFilter}
        responseTimeRange={responseTimeRange}
        setResponseTimeRange={setResponseTimeRange}
      />

      {/* Charts and Tables */}
      <div className="space-y-8">
        {/* Checks Over Time */}
        <Card>
          <CardHeader>
            <CardTitle>Checks Over Time</CardTitle>
          </CardHeader>
          <CardContent className="h-[400px]">
            {analytics && <ChecksOverTimeChart data={filteredChecksOverTime} />}
          </CardContent>
        </Card>

        {/* Status Code Distribution and Uptime Per URL */}
        <div className="grid gap-4 md:grid-cols-2">
          <Card>
            <CardHeader>
              <CardTitle>Status Code Distribution</CardTitle>
            </CardHeader>
            <CardContent className="h-[300px]">
              {analytics && <StatusCodeDistributionChart data={analytics.statusCodeDistribution} />}
            </CardContent>
          </Card>
          <Card>
            <CardHeader>
              <CardTitle>Uptime Per URL</CardTitle>
            </CardHeader>
            <CardContent className="h-[300px]">
              {analytics && <UptimePerUrlChart data={analytics.uptimePerUrl} />}
            </CardContent>
          </Card>
        </div>

        {/* Response Time Distribution */}
        <Card>
          <CardHeader>
            <CardTitle>Response Time Distribution</CardTitle>
          </CardHeader>
          <CardContent className="h-[400px]">
            {analytics && <ResponseTimeDistributionChart data={analytics.responseTimeDistribution} />}
          </CardContent>
        </Card>

        {/* Top Slowest URLs */}
        <Card>
          <CardHeader>
            <CardTitle>Top Slowest URLs</CardTitle>
          </CardHeader>
          <CardContent>
            {analytics && <TopSlowestUrlsTable data={analytics.topSlowestUrls} />}
          </CardContent>
        </Card>

        {/* Recent Issues */}
        <Card>
          <CardHeader>
            <CardTitle>Recent Issues</CardTitle>
          </CardHeader>
          <CardContent>
            {analytics && <RecentIssuesTable data={analytics.recentIssues} />}
          </CardContent>
        </Card>
      </div>
    </div>
  );
};

export default AdvancedAnalyticsDashboard;
"""
fix it completely 
i am giving you the backend logic too ensure it is working perfectly in al cases and best
"""
exports.getAnalytics = async (req, res) => {
    try {
        const userId = req.user.id;

        // Validate and parse query parameters
        const parsed = analyticsSchema.parse(req.query);
        const { startDate, endDate, urls, statusCodes, minResponseTime, maxResponseTime, groupBy, page, limit } = parsed;

        // Build the match criteria for MongoDB aggregation
        const matchCriteria = { user: new mongoose.Types.ObjectId(userId) };

        if (startDate || endDate) {
            matchCriteria.checkedAt = {};
            if (startDate) {
                matchCriteria.checkedAt.$gte = new Date(startDate);
            }
            if (endDate) {
                matchCriteria.checkedAt.$lte = new Date(endDate);
            }
        }

        if (urls) {
            const urlsArray = urls.split(',').map(url => url.trim());
            matchCriteria.url = { $in: urlsArray };
        }

        if (statusCodes) {
            const statusCodesArray = statusCodes.split(',').map(code => parseInt(code.trim()));
            matchCriteria.statusCode = { $in: statusCodesArray };
        }

        if (minResponseTime || maxResponseTime) {
            matchCriteria.responseTime = {};
            if (minResponseTime) {
                matchCriteria.responseTime.$gte = parseInt(minResponseTime, 10);
            }
            if (maxResponseTime) {
                matchCriteria.responseTime.$lte = parseInt(maxResponseTime, 10);
            }
        }

        /**
         * Aggregation Pipelines
         */

        // Total Checks
        const totalChecksPromise = Log.countDocuments(matchCriteria).exec();

        // Successful Checks (2xx)
        const successfulChecksPromise = Log.countDocuments({
            ...matchCriteria,
            statusCode: { $gte: 200, $lt: 300 },
        }).exec();

        // Failed Checks (4xx and 5xx)
        const failedChecksPromise = Log.countDocuments({
            ...matchCriteria,
            statusCode: { $gte: 400 },
        }).exec();

        // Status Code Distribution
        const statusCodeDistributionPromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $group: {
                    _id: '$statusCode',
                    count: { $sum: 1 },
                },
            },
            { $sort: { count: -1 } },
        ]).exec();

        // Uptime Percentage per URL
        const uptimePerUrlPromise = Log.aggregate([
            { $match: { ...matchCriteria, statusCode: { $gte: 200, $lt: 300 } } },
            {
                $group: {
                    _id: '$url',
                    successCount: { $sum: 1 },
                },
            },
            {
                $lookup: {
                    from: 'logs',
                    let: { url: '$_id' },
                    pipeline: [
                        { $match: { 
                            $expr: { $eq: ['$url', '$$url'] },
                            ...(startDate || endDate ? {
                                ...(startDate ? { $gte: ['$checkedAt', new Date(startDate)] } : {}),
                                ...(endDate ? { $lte: ['$checkedAt', new Date(endDate)] } : {}),
                            } : {})
                        } },
                        { $count: 'totalCount' },
                    ],
                    as: 'total',
                },
            },
            {
                $addFields: {
                    totalCount: { $ifNull: [{ $arrayElemAt: ['$total.totalCount', 0] }, 0] },
                },
            },
            {
                $project: {
                    _id: 1,
                    successCount: 1,
                    totalCount: 1,
                    uptimePercentage: {
                        $cond: [
                            { $eq: ['$totalCount', 0] },
                            0,
                            { $multiply: [{ $divide: ['$successCount', '$totalCount'] }, 100] },
                        ],
                    },
                },
            },
        ]).exec();

        // Checks Over Time with Average Response Time
        const checksOverTimePromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $group: {
                    _id: {
                        year: { $year: '$checkedAt' },
                        month: { $month: '$checkedAt' },
                        week: { $week: '$checkedAt' },
                        day: { $dayOfMonth: '$checkedAt' },
                        hour: { $hour: '$checkedAt' },
                    },
                    count: { $sum: 1 },
                    averageResponseTime: { $avg: '$responseTime' },
                },
            },
            {
                $project: {
                    _id: 0,
                    period: getPeriodExpression(groupBy),
                    count: 1,
                    averageResponseTime: 1,
                },
            },
            {
                $group: {
                    _id: '$period',
                    total: { $sum: '$count' },
                    averageResponseTime: { $avg: '$averageResponseTime' },
                },
            },
            { $sort: { '_id': 1 } },
        ]).exec();

        // Response Time Distribution
        const responseTimeDistributionPromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $bucket: {
                    groupBy: '$responseTime',
                    boundaries: [0, 100, 300, 500, 1000, 3000, 5000, Infinity],
                    default: '5000+',
                    output: {
                        count: { $sum: 1 },
                        averageResponseTime: { $avg: '$responseTime' },
                    },
                },
            },
            { $sort: { _id: 1 } },
        ]).exec();

        // Top Slowest URLs
        const topSlowestUrlsPromise = Log.aggregate([
            { $match: matchCriteria },
            {
                $group: {
                    _id: '$url',
                    averageResponseTime: { $avg: '$responseTime' },
                    totalChecks: { $sum: 1 },
                },
            },
            { $sort: { averageResponseTime: -1 } },
            { $limit: 10 },
        ]).exec();

        // Recent Issues
        const recentIssuesPromise = Log.find({
            ...matchCriteria,
            statusCode: { $gte: 400 }, // Client and Server errors
        })
            .sort({ checkedAt: -1 })
            .limit(10)
            .select('url statusCode checkedAt screenshotUrl responseTime')
            .exec();

        // Execute all aggregation promises concurrently
        const [
            totalChecks,
            successfulChecks,
            failedChecks,
            statusCodeDistribution,
            uptimePerUrl,
            checksOverTime,
            responseTimeDistribution,
            topSlowestUrls,
            recentIssues,
        ] = await Promise.all([
            totalChecksPromise,
            successfulChecksPromise,
            failedChecksPromise,
            statusCodeDistributionPromise,
            uptimePerUrlPromise,
            checksOverTimePromise,
            responseTimeDistributionPromise,
            topSlowestUrlsPromise,
            recentIssuesPromise,
        ]);

        // Calculate success and failure percentages with safe defaults
        const successPercentage = totalChecks > 0 ? (((successfulChecks / totalChecks) * 100) || 0).toFixed(2) : '0.00';
        const failurePercentage = totalChecks > 0 ? (((failedChecks / totalChecks) * 100) || 0).toFixed(2) : '0.00';

        // Structure the analytics response
        const analytics = {
            totalChecks,
            successfulChecks,
            successPercentage: `${successPercentage}%`,
            failedChecks,
            failurePercentage: `${failurePercentage}%`,
            statusCodeDistribution: statusCodeDistribution.map(item => ({
                statusCode: item._id,
                count: item.count,
                percentage: totalChecks > 0 ? `${(((item.count / totalChecks) * 100) || 0).toFixed(2)}%` : '0.00%',
            })),
            uptimePerUrl: uptimePerUrl.map(item => ({
                url: item._id,
                successCount: item.successCount,
                totalCount: item.totalCount,
                uptimePercentage: `${(item.uptimePercentage || 0).toFixed(2)}%`,
            })),
            checksOverTime: checksOverTime.map(item => ({
                period: formatPeriod(item._id, groupBy),
                count: item.total,
                averageResponseTime: `${(item.averageResponseTime || 0).toFixed(2)}ms`,
            })),
            responseTimeDistribution: responseTimeDistribution.map(item => ({
                range: formatResponseTimeRange(item._id),
                count: item.count,
                averageResponseTime: item.averageResponseTime ? `${item.averageResponseTime.toFixed(2)}ms` : 'N/A',
            })),
            topSlowestUrls: topSlowestUrls.map(item => ({
                url: item._id,
                averageResponseTime: `${(item.averageResponseTime || 0).toFixed(2)}ms`,
                totalChecks: item.totalChecks,
            })),
            recentIssues,
        };

        // Send the analytics data as a JSON response
        res.status(200).json({ analytics });
    } catch (error) {
        if (error instanceof z.ZodError) {
            // If validation fails, send a 400 response with error details
            return res.status(400).json({
                message: 'Invalid query parameters',
                errors: error.errors.map((err) => ({
                    field: err.path.join('.'),
                    message: err.message,
                })),
            });
        }

        // Log unexpected errors and send a 500 response
        logger.error('Get Analytics Error:', error);
        res.status(500).json({ message: 'Internal server error' });
    }
};

/**
 * Helper functions for formatting
 */

/**
 * Formats the period string based on the groupBy parameter.
 *
 * @param {Object} periodObj - Object containing date parts.
 * @param {string} groupBy - Grouping parameter ('hour', 'day', 'week', 'month').
 * @returns {string} - Formatted period string.
 */
const formatPeriod = (periodObj, groupBy) => {
    const { year, month, week, day, hour } = periodObj;
    switch (groupBy) {
        case 'hour':
            return `${month}/${day}/${year} ${hour}:00`;
        case 'day':
            return `${month}/${day}/${year}`;
        case 'week':
            return `Week ${week}, ${year}`;
        case 'month':
            return `${month}/${year}`;
        default:
            return `${month}/${day}/${year}`;
    }
};

/**
 * Formats the response time range for distribution buckets.
 *
 * @param {string|number} range - The range identifier from the aggregation.
 * @returns {string} - Formatted range string.
 */
const formatResponseTimeRange = (range) => {
    if (range === '5000+') return '5000+ms';
    return `${range[0]}-${range[1]}ms`;
};

/**
 * Returns the MongoDB aggregation expression based on the groupBy parameter.
 *
 * @param {string} groupBy - Grouping parameter ('hour', 'day', 'week', 'month').
 * @returns {Object} - Aggregation expression.
 */
const getPeriodExpression = (groupBy) => ({
    hour: {
        year: { $year: '$checkedAt' },
        month: { $month: '$checkedAt' },
        day: { $dayOfMonth: '$checkedAt' },
        hour: { $hour: '$checkedAt' },
    },
    day: {
        year: { $year: '$checkedAt' },
        month: { $month: '$checkedAt' },
        day: { $dayOfMonth: '$checkedAt' },
    },
    week: {
        year: { $year: '$checkedAt' },
        week: { $week: '$checkedAt' },
    },
    month: {
        year: { $year: '$checkedAt' },
        month: { $month: '$checkedAt' },
    },
}[groupBy]);
"""