import React, { useState, useEffect, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Table,
  TableHeader,
  TableHead,
  TableRow,
  TableBody,
  TableCell,
} from "@/components/ui/table";
import {
  LineChart,
  Line,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ReferenceLine,
} from "recharts";
import { DateTime } from "luxon";
import { TimeRangeSelect } from "@/components/dashboard/TimeRangeSelect";
import { Info, TrendingUp, TrendingDown } from "lucide-react";

const formatCurrency = (value) => {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  }).format(value);
};

const formatPercent = (value) => {
  return new Intl.NumberFormat("en-US", {
    style: "percent",
    minimumFractionDigits: 1,
    maximumFractionDigits: 1,
  }).format(value / 100);
};

const StatCard = ({
  title,
  value,
  subtitle,
  previousValue,
  formatter = (v) => v.toLocaleString(),
  info,
}) => {
  const percentChange = previousValue
    ? ((value - previousValue) / previousValue) * 100
    : 0;

  return (
    <div className="p-4 border rounded-lg">
      <div className="flex justify-between items-start mb-2">
        <span className="text-sm text-muted-foreground">{title}</span>
        {info && (
          <Info
            className="w-4 h-4 text-muted-foreground cursor-help"
            title={info}
          />
        )}
      </div>
      <div className="text-2xl font-bold mb-1">{formatter(value)}</div>
      {subtitle && (
        <div className="text-sm text-muted-foreground">{subtitle}</div>
      )}
      {previousValue && (
        <div
          className={`text-sm flex items-center gap-1 
          ${percentChange > 0 ? "text-green-600" : "text-red-600"}`}
        >
          {percentChange > 0 ? (
            <TrendingUp className="w-4 h-4" />
          ) : (
            <TrendingDown className="w-4 h-4" />
          )}
          {Math.abs(percentChange).toFixed(1)}% vs prev
        </div>
      )}
    </div>
  );
};

const formatChartDate = (value) => {
  if (!value) return '';
  try {
    return DateTime.fromISO(value).setZone('America/New_York').toFormat('LLL d');
  } catch (error) {
    console.error("[KLAVIYO SALES] Date formatting error:", error);
    return value;
  }
};

const CustomTooltip = ({ active, payload, label }) => {
  if (active && payload && payload.length) {
    return (
      <Card className="p-2 shadow-lg bg-white dark:bg-gray-800">
        <CardContent className="p-0">
          <p className="font-medium">{formatChartDate(label)}</p>
          {payload.map((entry, index) => (
            <p key={index} className="text-sm text-muted-foreground">
              {entry.name}:{" "}
              {entry.dataKey.toLowerCase().includes("revenue") ||
              entry.dataKey === "movingAverage"
                ? formatCurrency(entry.value)
                : entry.value.toLocaleString()}
            </p>
          ))}
        </CardContent>
      </Card>
    );
  }
  return null;
};

const KlaviyoSalesChart = ({ className }) => {
  const [timeRange, setTimeRange] = useState("last7days");
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [showDailyTable, setShowDailyTable] = useState(false);
  const [visibleLines, setVisibleLines] = useState({
    revenue: true,
    orders: true,
    movingAverage: true,
    previousRevenue: false,
    previousOrders: false,
  });

  const calculate7DayAverage = useCallback((data) => {
    return data.map((day, index, array) => {
      const startIndex = Math.max(0, index - 6);
      const window = array.slice(startIndex, index + 1);
      const sum = window.reduce((acc, curr) => acc + (curr.revenue || 0), 0);
      const average = window.length > 0 ? sum / window.length : 0;
      
      return {
        ...day,
        movingAverage: Number(average.toFixed(2))
      };
    });
  }, []);

  const validateMetricsData = (data) => {
    if (!data) {
      console.warn("[KLAVIYO SALES] No data received");
      return false;
    }

    // Log the actual structure we're receiving
    console.log("[KLAVIYO SALES] Validating data structure:", {
      keys: Object.keys(data),
      revenueKeys: Object.keys(data.revenue || {}),
      ordersKeys: Object.keys(data.orders || {}),
      sampleDaily: data.revenue?.daily?.[0]
    });

    // Check if we have the minimum required data
    const hasMinimumData = data.revenue?.daily && 
                          Array.isArray(data.revenue.daily) && 
                          data.revenue.daily.length > 0;

    if (!hasMinimumData) {
      console.warn("[KLAVIYO SALES] Missing minimum required data");
      return false;
    }

    return true;
  };
  

  const getPreviousPeriod = (timeRange) => {
    switch (timeRange) {
      case "today":
        return "yesterday";
      case "yesterday":
        return "last2days";
      case "last7days":
        return "previous7days";
      case "last30days":
        return "previous30days";
      case "last90days":
        return "previous90days";
      default:
        return timeRange;
    }
  };

  const fetchData = useCallback(async () => {
    try {
      setIsLoading(true);
      const previousTimeRange = getPreviousPeriod(timeRange);
      
      console.log("[KLAVIYO SALES] Fetching data for:", {
        current: timeRange,
        previous: previousTimeRange
      });
  
      // Fetch both current and previous period data
      const [currentResponse, previousResponse] = await Promise.all([
        fetch(`/api/klaviyo/sales/${timeRange}`),
        fetch(`/api/klaviyo/sales/${previousTimeRange}`)
      ]);
  
      if (!currentResponse.ok || !previousResponse.ok) {
        throw new Error(`Failed to fetch data: ${currentResponse.status}, ${previousResponse.status}`);
      }
  
      const [currentData, previousData] = await Promise.all([
        currentResponse.json(),
        previousResponse.json()
      ]);
  
      // Log the raw data received from the API
      console.log("[KLAVIYO SALES] Raw data received:", {
        current: currentData,
        previous: previousData
      });
  
      if (!validateMetricsData(currentData)) {
        throw new Error('Invalid metrics data structure received');
      }
  
      // Process the daily data
      const processedDaily = currentData.revenue.daily.map((day, index) => {
        const previousDay = previousData?.revenue?.daily?.[index] || {};
        
        const hourlyTotal = (day.hourly_orders || []).reduce((sum, count) => sum + count, 0);
        const revenue = day.value || 0;
        const orders = day.orders || 0;
  
        return {
          date: day.date,
          revenue,
          orders,
          items: day.items || 0,
          avgOrderValue: orders > 0 ? revenue / orders : 0,
          preOrders: day.pre_orders || 0,
          refunds: day.refunds?.total || 0,
          cancellations: day.cancellations?.total || 0,
          previousRevenue: previousDay.value || 0,
          previousOrders: previousDay.orders || 0,
          hourly_orders: day.hourly_orders || Array(24).fill(0),
          hourly_total: hourlyTotal
        };
      });
  
      // Calculate 7-day moving average
      const withMovingAverage = calculate7DayAverage(processedDaily);
  
      // Prepare the complete data structure
      const processedData = {
        daily: withMovingAverage,
        totals: {
          revenue: currentData.revenue.total || 0,
          orders: currentData.orders.total || 0,
          items: currentData.orders.items_total || 0,
          avgOrderValue: currentData.orders.total > 0 
            ? currentData.revenue.total / currentData.orders.total 
            : 0,
          previousRevenue: previousData?.revenue?.total || 0,
          previousOrders: previousData?.orders?.total || 0,
          refunds: currentData.refunds || { count: 0, total: 0 },
          cancellations: currentData.cancellations || { count: 0, total: 0 },
          preOrders: currentData.orders?.pre_orders || 0,
          localPickup: currentData.orders?.local_pickup || 0,
          revenue_best_day: currentData.revenue.best_day || {
            date: null,
            value: 0,
            orders: 0
          }
        },
        hourly_distribution: currentData.hourly_distribution || Array(24).fill(0),
        metadata: {
          brands: Object.keys(currentData.orders?.brands || {}).length,
          categories: Object.keys(currentData.orders?.categories || {}).length,
          shipping_states: Object.keys(currentData.orders?.shipping_states || {}).length
        }
      };
  
      // Log the processed data before setting the state
      console.log("[KLAVIYO SALES] Processed data:", {
        dailyCount: processedData.daily.length,
        totalRevenue: processedData.totals.revenue,
        totalOrders: processedData.totals.orders
      });
  
      setData(processedData);
      setError(null);
    } catch (err) {
      console.error('[KLAVIYO SALES] Error:', err);
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  }, [timeRange, calculate7DayAverage]);
  

useEffect(() => {
  let isSubscribed = true;
  
  const loadData = async () => {
    await fetchData();
    if (!isSubscribed) return;
  };

  loadData();

  // Set up refresh interval only for active time ranges
  const shouldAutoRefresh = ['today', 'last7days'].includes(timeRange);
  let interval;
  
  if (shouldAutoRefresh) {
    interval = setInterval(() => {
      if (isSubscribed) loadData();
    }, 5 * 60 * 1000); // 5 minutes
  }

  return () => {
    isSubscribed = false;
    if (interval) clearInterval(interval);
  };
}, [timeRange, fetchData]);

  if (error) {
    return (
      <Card className={className}>
        <CardContent className="pt-6">
          <div className="text-red-600 dark:text-red-400">
            Error loading sales data: {error}
          </div>
        </CardContent>
      </Card>
    );
  }

  const LoadingState = () => (
    <div className="space-y-4">
      <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
        {[...Array(4)].map((_, i) => (
          <Skeleton key={i} className="h-24 rounded-lg" />
        ))}
      </div>
      <Skeleton className="h-[400px] rounded-lg" />
    </div>
  );

  if (isLoading || !data) {
    return (
      <Card className={className}>
        <CardHeader>
          <div className="flex justify-between items-center">
            <div>
              <CardTitle>Sales & Orders</CardTitle>
              <p className="text-sm text-muted-foreground mt-1">
                {timeRange === "today" ? (
                  `Today (${DateTime.now().setZone('America/New_York').toFormat('M/d h:mm a')} ET)`
                ) : timeRange === "yesterday" ? (
                  `Yesterday (${DateTime.now().setZone('America/New_York').minus({ days: 1 }).toFormat('M/d')} 1:00 AM - 12:59 AM ET)`
                ) : (
                  `${DateTime.now().setZone('America/New_York').minus({ 
                    days: timeRange === "last7days" ? 6 : 
                          timeRange === "last30days" ? 29 : 89
                  }).toFormat('M/d')} - ${DateTime.now().setZone('America/New_York').toFormat('M/d h:mm a')} ET`
                )}
              </p>
            </div>
            <TimeRangeSelect
              value={timeRange}
              onChange={setTimeRange}
              className="w-40"
              allowedRanges={["last7days", "last30days", "last90days"]}
            />
          </div>
        </CardHeader>
        <CardContent>
          <LoadingState />
        </CardContent>
      </Card>
    );
  }

  const averageRevenue =
    data.daily.reduce((sum, day) => sum + day.revenue, 0) / data.daily.length;

  return (
    <Card className={className}>
      <CardHeader>
        <div className="flex justify-between items-center">
          <div>
            <CardTitle>Sales & Orders</CardTitle>
            <p className="text-sm text-muted-foreground mt-1">
              {timeRange === "today" ? (
                `Today (${DateTime.now().setZone('America/New_York').toFormat('M/d h:mm a')} ET)`
              ) : timeRange === "yesterday" ? (
                `Yesterday (${DateTime.now().setZone('America/New_York').minus({ days: 1 }).toFormat('M/d')} 1:00 AM - 12:59 AM ET)`
              ) : (
                `${DateTime.now().setZone('America/New_York').minus({ 
                  days: timeRange === "last7days" ? 6 : 
                        timeRange === "last30days" ? 29 : 89
                }).toFormat('M/d')} - ${DateTime.now().setZone('America/New_York').toFormat('M/d h:mm a')} ET`
              )}
            </p>
          </div>
          <TimeRangeSelect
            value={timeRange}
            onChange={setTimeRange}
            className="w-40"
            allowedRanges={["last7days", "last30days", "last90days"]}
          />
        </div>
      </CardHeader>
      <CardContent>
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
          <StatCard
            title="Total Revenue"
            value={data?.totals?.revenue ?? 0}
            previousValue={data?.totals?.previousRevenue}
            formatter={formatCurrency}
          />

          <StatCard
            title="Total Orders"
            value={data?.totals?.orders ?? 0}
            previousValue={data?.totals?.previousOrders}
          />

          <StatCard
            title="Average Order Value"
            value={data?.totals?.avgOrderValue ?? 0}
            formatter={formatCurrency}
          />

          <StatCard
            title="Best Day"
            value={data?.totals?.revenue_best_day?.value ?? 0}
            formatter={formatCurrency}
            subtitle={
              data?.totals?.revenue_best_day?.date
                ? DateTime.fromISO(data.totals.revenue_best_day.date).toFormat(
                    "LLL d"
                  )
                : "No data"
            }
          />
        </div>

        <div className="h-[400px]">
          <div className="mb-4 flex flex-wrap gap-4">
            {Object.entries({
              revenue: "Revenue",
              orders: "Orders",
              movingAverage: "7-Day Average",
              previousRevenue: "Previous Revenue",
              previousOrders: "Previous Orders",
            }).map(([key, label]) => (
              <label key={key} className="flex items-center space-x-2">
                <input
                  type="checkbox"
                  checked={visibleLines[key]}
                  onChange={(e) =>
                    setVisibleLines((prev) => ({
                      ...prev,
                      [key]: e.target.checked,
                    }))
                  }
                  className="rounded border-gray-300 text-primary"
                />
                <span>{label}</span>
              </label>
            ))}
          </div>

          <ResponsiveContainer width="100%" height="100%">
            <LineChart
              data={data.daily}
              margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
            >
              <CartesianGrid
                strokeDasharray="3 3"
                className="stroke-gray-200"
              />
              <XAxis
                dataKey="date"
                className="text-xs"
                tick={{ fill: "currentColor" }}
              />
              <YAxis
                yAxisId="left"
                className="text-xs"
                tickFormatter={(value) => formatCurrency(value)}
                tick={{ fill: "currentColor" }}
              />
              <YAxis
                yAxisId="right"
                orientation="right"
                className="text-xs"
                tickFormatter={(value) => value.toLocaleString()}
                tick={{ fill: "currentColor" }}
              />
              <Tooltip content={<CustomTooltip />} />
              <Legend />
              <ReferenceLine
                y={averageRevenue}
                yAxisId="left"
                stroke="#666"
                strokeDasharray="3 3"
                label={{
                  value: `Avg Revenue: ${formatCurrency(averageRevenue)}`,
                  fill: "currentColor",
                  fontSize: 12,
                }}
              />
              {visibleLines.revenue && (
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="revenue"
                  name="Revenue"
                  stroke="#8b5cf6" // Purple for current revenue
                  strokeWidth={2}
                  dot={false}
                />
              )}
              {visibleLines.previousRevenue && (
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="previousRevenue"
                  name="Previous Revenue"
                  stroke="#f97316" // Orange for previous revenue
                  strokeWidth={2}
                  dot={false}
                />
              )}
              {visibleLines.orders && (
                <Line
                  yAxisId="right"
                  type="monotone"
                  dataKey="orders"
                  name="Orders"
                  stroke="#10b981" // Green for current orders
                  strokeWidth={2}
                  dot={false}
                />
              )}
              {visibleLines.previousOrders && (
                <Line
                  yAxisId="right"
                  type="monotone"
                  dataKey="previousOrders"
                  name="Previous Orders"
                  stroke="#0ea5e9" // Blue for previous orders
                  strokeWidth={2}
                  dot={false}
                />
              )}
              {visibleLines.movingAverage && (
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="movingAverage"
                  name="7-Day Average"
                  stroke="#f59e0b"
                  strokeWidth={2}
                  dot={false}
                  strokeDasharray="5 5"
                />
              )}
            </LineChart>
          </ResponsiveContainer>
        </div>

        <div className="mt-4 flex justify-end">
          <Button
            variant="outline"
            onClick={() => setShowDailyTable(!showDailyTable)}
          >
            {showDailyTable ? "Hide" : "Show"} Daily Details
          </Button>
        </div>

        {showDailyTable && (
          <div className="mt-4 overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Date</TableHead>
                  <TableHead className="text-right">Orders</TableHead>
                  <TableHead className="text-right">Items</TableHead>
                  <TableHead className="text-right">Revenue</TableHead>
                  <TableHead className="text-right">Avg Order</TableHead>
                  <TableHead className="text-right">Pre-Orders</TableHead>
                  <TableHead className="text-right">Refunds</TableHead>
                  <TableHead className="text-right">Cancellations</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.daily.map((day) => (
                  <TableRow key={day.date}>
                    <TableCell>{day.date}</TableCell>
                    <TableCell className="text-right">
                      {day.orders.toLocaleString()}
                    </TableCell>
                    <TableCell className="text-right">
                      {day.items.toLocaleString()}
                    </TableCell>
                    <TableCell className="text-right">
                      {formatCurrency(day.revenue)}
                    </TableCell>
                    <TableCell className="text-right">
                      {formatCurrency(day.avgOrderValue)}
                    </TableCell>
                    <TableCell className="text-right">
                      {day.preOrders.toLocaleString()}
                    </TableCell>
                    <TableCell className="text-right text-red-600">
                      {day.refunds > 0
                        ? `-${formatCurrency(day.refunds)}`
                        : "-"}
                    </TableCell>
                    <TableCell className="text-right text-red-600">
                      {day.cancelations > 0
                        ? `-${formatCurrency(day.cancelations)}`
                        : "-"}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        )}
      </CardContent>
    </Card>
  );
};

export default KlaviyoSalesChart;
