import React, { useState, useEffect } from "react";
import { apiFetch } from "@/utils/api";
import { Card, CardContent } from "@/components/ui/card";
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  Tooltip,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
} from "recharts";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { format } from "date-fns";
import { Radio, Users } from "lucide-react";

// Import shared components and tokens
import {
  DashboardChartTooltip,
  DashboardSectionHeader,
  DashboardTable,
  ChartSkeleton,
  TableSkeleton,
  DashboardErrorState,
  CARD_STYLES,
  TYPOGRAPHY,
  METRIC_COLORS,
} from "@/components/dashboard/shared";

// Realtime-specific colors using the standardized palette
const REALTIME_COLORS = {
  activeUsers: {
    color: METRIC_COLORS.revenue,  // Studio coral — realtime is a headline metric
    className: "text-chart-revenue",
  },
  pages: {
    color: METRIC_COLORS.orders,  // Studio violet
    className: "text-chart-orders",
  },
  sources: {
    color: METRIC_COLORS.comparison,  // Studio teal
    className: "text-chart-comparison",
  },
};

// Export for backwards compatibility
export { REALTIME_COLORS as METRIC_COLORS };

export const SkeletonBarChart = () => (
  <ChartSkeleton type="bar" height="sm" withCard={false} />
);

export const SkeletonTable = () => (
  <TableSkeleton rows={8} columns={2} scrollable maxHeight="sm" />
);

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,
  } = projectHourly;

  const { remaining: dailyRemaining = 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-trend-negative";
    if (numericPercentage < 40) return "text-chart-comparison";
    return "text-trend-positive";
  };

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

// Traffic-sources donut — mirrors the Device Usage tab in UserBehavior:
// ring with a center total and a labeled legend column (no on-slice labels).
const SOURCE_COLORS = ["#e06a4e", "#6b5fc7", "#0f8f77", "#a87a24", "#3f7fae", "#c94f76"];

const SourcesDonut = ({ sources, loading }) => {
  if (loading) {
    return (
      <div className="flex h-full items-center gap-6">
        <div className="h-40 w-40 shrink-0 animate-pulse rounded-full bg-[#f0eeea]" />
        <div className="flex-1 space-y-2.5">
          {[...Array(4)].map((_, i) => (
            <div key={i} className="h-3.5 w-full animate-pulse rounded bg-[#f0eeea]" />
          ))}
        </div>
      </div>
    );
  }

  const top = [...(sources || [])]
    .sort((a, b) => b.activeUsers - a.activeUsers)
    .slice(0, 6);
  const total = top.reduce((sum, s) => sum + s.activeUsers, 0);

  if (!total) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-[#a09b92]">
        No active sources
      </div>
    );
  }

  return (
    <div className="flex h-full items-center gap-4 sm:gap-6">
      <div className="relative h-40 w-40 shrink-0">
        <ResponsiveContainer width="100%" height="100%">
          <PieChart>
            <Pie
              data={top}
              dataKey="activeUsers"
              nameKey="source"
              cx="50%"
              cy="50%"
              innerRadius={50}
              outerRadius={76}
              paddingAngle={2}
              stroke="#ffffff"
              strokeWidth={2}
              labelLine={false}
            >
              {top.map((entry, index) => (
                <Cell key={entry.source} fill={SOURCE_COLORS[index % SOURCE_COLORS.length]} />
              ))}
            </Pie>
          </PieChart>
        </ResponsiveContainer>
        <div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center">
          <span className="text-[19px] font-bold tabular-nums text-[#2b2925]">{total}</span>
          <span className="text-[10px] font-semibold text-[#a09b92]">active</span>
        </div>
      </div>
      <div className="min-w-0 flex-1 space-y-2 overflow-y-auto dashboard-scroll" style={{ maxHeight: 176 }}>
        {top.map((entry, index) => (
          <div key={entry.source} className="flex items-center gap-2.5">
            <span
              className="h-2 w-2 shrink-0 rounded-full"
              style={{ background: SOURCE_COLORS[index % SOURCE_COLORS.length] }}
            />
            <span className="min-w-0 flex-1 truncate text-xs font-medium text-[#2b2925]">
              {entry.source}
            </span>
            <span className="text-xs tabular-nums text-[#7c7870]">{entry.activeUsers}</span>
            <span className="w-10 text-right text-xs font-bold tabular-nums text-[#2b2925]">
              {Math.round((entry.activeUsers / total) * 100)}%
            </span>
          </div>
        ))}
      </div>
    </div>
  );
};

// Custom tooltip for the realtime chart
const RealtimeTooltip = ({ active, payload }) => {
  if (active && payload && payload.length) {
    const timestamp = new Date(
      Date.now() + payload[0].payload.minute * 60000
    );
    return (
      <DashboardChartTooltip
        active={active}
        payload={[{
          name: "Active Users",
          value: payload[0].value,
          color: REALTIME_COLORS.activeUsers.color,
        }]}
        label={format(timestamp, "h:mm a")}
      />
    );
  }
  return null;
};

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 apiFetch("/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 apiFetch("/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]);

  // Column definitions for pages table
  const pagesColumns = [
    {
      key: "path",
      header: "Page",
      // GA4's realtime API only exposes unifiedScreenName (page TITLE), not
      // pagePath — so these can't be linked, unlike the 30-day Top Pages table.
      render: (value) => <span className="font-medium text-foreground">{value}</span>,
    },
    {
      key: "activeUsers",
      header: "Active Users",
      align: "right",
      width: "w-[110px] min-w-[110px] whitespace-nowrap",
      render: (value) => <span className={REALTIME_COLORS.pages.className}>{value}</span>,
    },
  ];


  if (loading && !basicData && !detailedData) {
    return (
      <Card className={`${CARD_STYLES.base} h-full`}>
        <DashboardSectionHeader title="Real-Time Analytics" size="large" />

        <CardContent className="p-4 pt-3">
          <div className="mb-3 h-[74px] animate-pulse rounded-xl bg-[#f0eeea]" />

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

  return (
    <Card className={`${CARD_STYLES.base} h-full`}>
      <DashboardSectionHeader
        title="Real-Time Analytics"
        size="large"
        actions={
          <span className={TYPOGRAPHY.label}>
            Updated{" "}
            {basicData.lastUpdated && format(new Date(basicData.lastUpdated), "h:mm a")}
          </span>
        }
      />

      <CardContent className="p-4 pt-3">
        {error && (
          <DashboardErrorState error={error} className="mx-0 mb-4" />
        )}

        <div className="mb-3 grid grid-cols-[1fr_auto] items-center gap-4 rounded-xl bg-[#e6f3ee] px-4 py-3">
          <div className="flex items-center gap-3">
            <div className="relative flex h-9 w-9 items-center justify-center rounded-full bg-white">
              <Radio className="h-4 w-4 text-[#1f8a67]" />
              <span className="absolute right-0 top-0 h-2 w-2 rounded-full bg-[#1f8a67] ring-2 ring-[#e6f3ee]" />
            </div>
            <div>
              <p className="text-[11px] font-semibold text-[#2b2925]/60">Active now</p>
              <p className="text-3xl font-bold leading-none tracking-tight tabular-nums text-[#2b2925]">
                {basicData.last5MinUsers}
              </p>
            </div>
          </div>
          <div className="border-l border-[#cfe5dc] pl-4 text-right">
            <div className="flex items-center justify-end gap-1.5 text-muted-foreground">
              <Users className="h-3.5 w-3.5" />
              <span className="text-[11px]">30 minutes</span>
            </div>
            <p className="text-lg font-semibold tabular-nums">{basicData.last30MinUsers}</p>
          </div>
        </div>

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

          <TabsContent value="activity">
            <div className="h-[176px] rounded-lg">
              <ResponsiveContainer width="100%" height="100%">
                <BarChart
                  data={basicData.byMinute}
                  margin={{ top: 8, right: 0, left: -28, bottom: -5 }}
                >
                  <XAxis
                    dataKey="minute"
                    tickFormatter={(value) => value + "m"}
                    className="text-xs fill-muted-foreground"
                    tickLine={false}
                    axisLine={false}
                  />
                  <YAxis
                    className="text-xs fill-muted-foreground"
                    tickLine={false}
                    axisLine={false}
                  />
                  <Tooltip content={<RealtimeTooltip />} />
                  <Bar
                    dataKey="users"
                    fill={REALTIME_COLORS.activeUsers.color}
                    radius={[4, 4, 0, 0]}
                  />
                </BarChart>
              </ResponsiveContainer>
            </div>
          </TabsContent>

          <TabsContent value="pages">
            <div className="h-[188px] overflow-y-auto dashboard-scroll">
              <DashboardTable
                columns={pagesColumns}
                data={detailedData.currentPages}
                loading={loading}
                getRowKey={(page, index) => `${page.path}-${index}`}
                compact
              />
            </div>
          </TabsContent>

          <TabsContent value="sources">
            <div className="h-[188px]">
              <SourcesDonut sources={detailedData.sources} loading={loading} />
            </div>
          </TabsContent>
        </Tabs>
      </CardContent>
    </Card>
  );
};

/**
 * RealtimeChip — compact live-visitors pill for the page header. The full
 * realtime panel (chart + pages + sources tabs) lives behind a popover, per
 * the Studio design: realtime is ambient chrome, not a standing section.
 */
export const RealtimeChip = () => {
  const [count, setCount] = useState(null);

  useEffect(() => {
    let cancelled = false;
    const load = async () => {
      try {
        const response = await apiFetch("/api/dashboard-analytics/realtime/basic", {
          credentials: "include",
        });
        if (!response.ok) return;
        const result = await response.json();
        if (!cancelled) setCount(processBasicData(result.data).last5MinUsers);
      } catch {
        // ambient chip — stay quiet on errors
      }
    };
    load();
    const t = setInterval(load, 30000);
    return () => {
      cancelled = true;
      clearInterval(t);
    };
  }, []);

  return (
    <Popover>
      <PopoverTrigger asChild>
        <button
          type="button"
          className="flex h-8 items-center gap-2 rounded-full bg-[#ddf0ea] px-3.5 text-xs font-semibold text-[#2b2925] transition-[filter] hover:brightness-[1.03]"
        >
          <span className="relative flex h-2 w-2">
            <span className="absolute inline-flex h-full w-full rounded-full bg-[#1f8a67] opacity-60 motion-safe:animate-ping" />
            <span className="relative inline-flex h-2 w-2 rounded-full bg-[#1f8a67]" />
          </span>
          {count != null ? `${count} on site` : "Live"}
        </button>
      </PopoverTrigger>
      <PopoverContent
        align="end"
        sideOffset={8}
        className="w-[460px] max-w-[92vw] rounded-[14px] border-0 p-0 shadow-xl"
        onOpenAutoFocus={(e) => e.preventDefault()}
      >
        <RealtimeAnalytics />
      </PopoverContent>
    </Popover>
  );
};

export default RealtimeAnalytics;
