import React, { useState, useEffect, useRef } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/dashboard/ui/card";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/dashboard/ui/tooltip";
import { DateTime } from "luxon";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/dashboard/ui/select";
import { Button } from "@/components/dashboard/ui/button";
import { TIME_RANGES } from "@/lib/dashboard/constants";
import { Mail, MessageSquare, ArrowUpDown, BookOpen } from "lucide-react";
import { Skeleton } from "@/components/dashboard/ui/skeleton";

// Helper functions for formatting
const formatRate = (value, isSMS = false, hideForSMS = false) => {
  if (isSMS && hideForSMS) return "N/A";
  if (typeof value !== "number") return "0.0%";
  return `${(value * 100).toFixed(1)}%`;
};

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

// Loading skeleton component
const TableSkeleton = () => (
  <table className="w-full">
    <thead>
      <tr>
        <th className="p-2 text-left font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-24 bg-muted" />
        </th>
        <th className="p-2 text-center font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-20 mx-auto bg-muted" />
        </th>
        <th className="p-2 text-center font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-20 mx-auto bg-muted" />
        </th>
        <th className="p-2 text-center font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-20 mx-auto bg-muted" />
        </th>
        <th className="p-2 text-center font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-20 mx-auto bg-muted" />
        </th>
        <th className="p-2 text-center font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10">
          <Skeleton className="h-8 w-20 mx-auto bg-muted" />
        </th>
      </tr>
    </thead>
    <tbody className="divide-y divide-gray-200 dark:divide-gray-800">
      {[...Array(15)].map((_, i) => (
        <tr key={i} className="hover:bg-muted/50 transition-colors">
          <td className="p-2">
            <div className="flex items-center gap-2">
              <Skeleton className="h-4 w-4 bg-muted" />
              <div className="space-y-2">
                <Skeleton className="h-4 w-48 bg-muted" />
                <Skeleton className="h-3 w-64 bg-muted" />
                <Skeleton className="h-3 w-32 bg-muted" />
              </div>
            </div>
          </td>
          <td className="p-2 text-center">
            <div className="flex flex-col items-center gap-1">
              <Skeleton className="h-4 w-16 bg-muted" />
              <Skeleton className="h-3 w-24 bg-muted" />
            </div>
          </td>
          <td className="p-2 text-center">
            <div className="flex flex-col items-center gap-1">
              <Skeleton className="h-4 w-16 bg-muted" />
              <Skeleton className="h-3 w-24 bg-muted" />
            </div>
          </td>
          <td className="p-2 text-center">
            <div className="flex flex-col items-center gap-1">
              <Skeleton className="h-4 w-16 bg-muted" />
              <Skeleton className="h-3 w-24 bg-muted" />
            </div>
          </td>
          <td className="p-2 text-center">
            <div className="flex flex-col items-center gap-1">
              <Skeleton className="h-4 w-16 bg-muted" />
              <Skeleton className="h-3 w-24 bg-muted" />
            </div>
          </td>
          <td className="p-2 text-center">
            <div className="flex flex-col items-center gap-1">
              <Skeleton className="h-4 w-16 bg-muted" />
              <Skeleton className="h-3 w-24 bg-muted" />
            </div>
          </td>
        </tr>
      ))}
    </tbody>
  </table>
);

// Error alert component
const ErrorAlert = ({ description }) => (
  <div className="p-4 m-6 text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/10 rounded-lg border border-red-200 dark:border-red-900/20">
    {description}
  </div>
);

// MetricCell component for displaying campaign metrics
const MetricCell = ({
  value,
  count,
  isMonetary = false,
  showConversionRate = false,
  totalRecipients = 0,
  isSMS = false,
  hideForSMS = false,
}) => {
  if (isSMS && hideForSMS) {
    return (
      <td className="p-2 text-center">
        <div className="text-muted-foreground text-lg font-semibold">N/A</div>
        <div className="text-muted-foreground text-sm">-</div>
      </td>
    );
  }

  return (
    <td className="p-2 text-center">
      <div className="text-blue-600 dark:text-blue-400 text-lg font-semibold">
        {isMonetary ? formatCurrency(value) : formatRate(value, isSMS, hideForSMS)}
      </div>
      <div className="text-muted-foreground text-sm">
        {count?.toLocaleString() || 0} {count === 1 ? "recipient" : "recipients"}
        {showConversionRate &&
          totalRecipients > 0 &&
          ` (${((count / totalRecipients) * 100).toFixed(2)}%)`}
      </div>
    </td>
  );
};

const KlaviyoCampaigns = ({ className }) => {
  const [campaigns, setCampaigns] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedChannels, setSelectedChannels] = useState({ email: true, sms: true, blog: true });
  const [selectedTimeRange, setSelectedTimeRange] = useState("last7days");
  const [sortConfig, setSortConfig] = useState({
    key: "send_time",
    direction: "desc",
  });

  const handleSort = (key) => {
    setSortConfig((prev) => ({
      key,
      direction: prev.key === key && prev.direction === "desc" ? "asc" : "desc",
    }));
  };

  const fetchCampaigns = async () => {
    try {
      setIsLoading(true);
      const response = await fetch(
        `/api/klaviyo/reporting/campaigns/${selectedTimeRange}`
      );
      
      if (!response.ok) {
        throw new Error(`Failed to fetch campaigns: ${response.status}`);
      }
      
      const data = await response.json();
      setCampaigns(data.data || []);
      setError(null);
    } catch (err) {
      console.error("Error fetching campaigns:", err);
      setError(err.message);
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => {
    fetchCampaigns();
    const interval = setInterval(fetchCampaigns, 10 * 60 * 1000); // Refresh every 10 minutes
    return () => clearInterval(interval);
  }, [selectedTimeRange]); // Only refresh when time range changes

  // Sort campaigns
  const sortedCampaigns = [...campaigns].sort((a, b) => {
    const direction = sortConfig.direction === "desc" ? -1 : 1;
    
    switch (sortConfig.key) {
      case "send_time":
        return direction * (DateTime.fromISO(a.send_time) - DateTime.fromISO(b.send_time));
      case "delivery_rate":
        return direction * ((a.stats.delivery_rate || 0) - (b.stats.delivery_rate || 0));
      case "open_rate":
        return direction * ((a.stats.open_rate || 0) - (b.stats.open_rate || 0));
      case "click_rate":
        return direction * ((a.stats.click_rate || 0) - (b.stats.click_rate || 0));
      case "click_to_open_rate":
        return direction * ((a.stats.click_to_open_rate || 0) - (b.stats.click_to_open_rate || 0));
      case "conversion_value":
        return direction * ((a.stats.conversion_value || 0) - (b.stats.conversion_value || 0));
      default:
        return 0;
    }
  });

  // Filter campaigns by search term and channels
  const filteredCampaigns = sortedCampaigns.filter(
    (campaign) => {
      const isBlog = campaign?.name?.includes("_Blog");
      const channelType = isBlog ? "blog" : campaign?.channel;
      return campaign?.name?.toLowerCase().includes((searchTerm || "").toLowerCase()) &&
        selectedChannels[channelType];
    }
  );

  if (isLoading) {
    return (
      <Card className="h-full bg-white dark:bg-gray-900/60 backdrop-blur-sm">
        <CardHeader className="pb-2">
          <div className="flex justify-between items-center">
            <CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">
              <Skeleton className="h-6 w-48 bg-muted" />
            </CardTitle>
            <div className="flex gap-2">
              <div className="flex ml-1 gap-1 items-center">
                <Skeleton className="h-8 w-20 bg-muted" />
                <Skeleton className="h-8 w-20 bg-muted" />
              </div>
              <Skeleton className="h-8 w-[130px] bg-muted" />
            </div>
          </div>
        </CardHeader>
        <CardContent className="overflow-y-auto pl-4 max-h-[400px] mb-4">
          <TableSkeleton />
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className="h-full bg-white dark:bg-gray-900/60 backdrop-blur-sm">
      {error && <ErrorAlert description={error} />}
      <CardHeader className="pb-2">
        <div className="flex justify-between items-center">
          <CardTitle className="text-xl font-semibold text-gray-900 dark:text-gray-100">
            Klaviyo Campaigns
          </CardTitle>
          <div className="flex gap-2">
            <div className="flex ml-1 gap-1 items-center">
              <Button
                variant={selectedChannels.email ? "default" : "outline"}
                size="sm"
                onClick={() => setSelectedChannels(prev => {
                  if (prev.email && Object.values(prev).filter(Boolean).length === 1) {
                    // If only email is selected, show all
                    return { email: true, sms: true, blog: true };
                  }
                  // Show only email
                  return { email: true, sms: false, blog: false };
                })}
              >
                <Mail className="h-4 w-4" />
                <span className="hidden sm:inline">Email</span>
              </Button>
              <Button
                variant={selectedChannels.sms ? "default" : "outline"}
                size="sm"
                onClick={() => setSelectedChannels(prev => {
                  if (prev.sms && Object.values(prev).filter(Boolean).length === 1) {
                    // If only SMS is selected, show all
                    return { email: true, sms: true, blog: true };
                  }
                  // Show only SMS
                  return { email: false, sms: true, blog: false };
                })}
              >
                <MessageSquare className="h-4 w-4" />
                <span className="hidden sm:inline">SMS</span>
              </Button>
              <Button
                variant={selectedChannels.blog ? "default" : "outline"}
                size="sm"
                onClick={() => setSelectedChannels(prev => {
                  if (prev.blog && Object.values(prev).filter(Boolean).length === 1) {
                    // If only blog is selected, show all
                    return { email: true, sms: true, blog: true };
                  }
                  // Show only blog
                  return { email: false, sms: false, blog: true };
                })}
              >
                <BookOpen className="h-4 w-4" />
                <span className="hidden sm:inline">Blog</span>
              </Button>
            </div>
            <Select value={selectedTimeRange} onValueChange={setSelectedTimeRange}>
              <SelectTrigger className="w-[130px]">
                <SelectValue placeholder="Select time range" />
              </SelectTrigger>
              <SelectContent>
                {TIME_RANGES.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    {option.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>
      </CardHeader>
      <CardContent className="overflow-y-auto pl-4 max-h-[400px] mb-4">
        <table className="w-full">
          <thead>
            <tr>
              <th className="p-2 text-left font-medium sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant="ghost"
                  onClick={() => handleSort("send_time")}
                  className="w-full justify-start h-8"
                >
                  Campaign
                </Button>
              </th>
              <th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant={sortConfig.key === "delivery_rate" ? "default" : "ghost"}
                  onClick={() => handleSort("delivery_rate")}
                  className="w-full justify-center h-8"
                >
                  Delivery
                </Button>
              </th>
              <th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant={sortConfig.key === "open_rate" ? "default" : "ghost"}
                  onClick={() => handleSort("open_rate")}
                  className="w-full justify-center h-8"
                >
                  Opens
                </Button>
              </th>
              <th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant={sortConfig.key === "click_rate" ? "default" : "ghost"}
                  onClick={() => handleSort("click_rate")}
                  className="w-full justify-center h-8"
                >
                  Clicks
                </Button>
              </th>
              <th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant={sortConfig.key === "click_to_open_rate" ? "default" : "ghost"}
                  onClick={() => handleSort("click_to_open_rate")}
                  className="w-full justify-center h-8"
                >
                  CTR
                </Button>
              </th>
              <th className="p-2 font-medium text-center sticky top-0 bg-white dark:bg-gray-900/60 backdrop-blur-sm z-10 text-gray-900 dark:text-gray-100">
                <Button
                  variant={sortConfig.key === "conversion_value" ? "default" : "ghost"}
                  onClick={() => handleSort("conversion_value")}
                  className="w-full justify-center h-8"
                >
                  Orders
                </Button>
              </th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 dark:divide-gray-800">
            {filteredCampaigns.map((campaign) => (
              <tr
                key={campaign.id}
                className="hover:bg-muted/50 transition-colors"
              >
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <td className="p-2 align-top">
                        <div className="flex items-center gap-2">
                          {campaign.name?.includes("_Blog") ? (
                            <BookOpen className="h-4 w-4 text-muted-foreground" />
                          ) : campaign.channel === 'sms' ? (
                            <MessageSquare className="h-4 w-4 text-muted-foreground" />
                          ) : (
                            <Mail className="h-4 w-4 text-muted-foreground" />
                          )}
                          <div className="font-medium text-gray-900 dark:text-gray-100">
                            {campaign.name}
                          </div>
                        </div>
                        <div className="text-sm text-muted-foreground truncate max-w-[300px]">
                          {campaign.subject}
                        </div>
                        <div className="text-xs text-muted-foreground">
                          {campaign.send_time
                            ? DateTime.fromISO(campaign.send_time).toLocaleString(DateTime.DATETIME_MED)
                            : "No date"}
                        </div>
                      </td>
                    </TooltipTrigger>
                    <TooltipContent
                      side="top"
                      className="break-words bg-white dark:bg-gray-900/60 backdrop-blur-sm text-gray-900 dark:text-gray-100 border dark:border-gray-800"
                    >
                      <p className="font-medium">{campaign.name}</p>
                      <p>{campaign.subject}</p>
                      <p className="text-xs text-muted-foreground">
                        {campaign.send_time
                          ? DateTime.fromISO(campaign.send_time).toLocaleString(DateTime.DATETIME_MED)
                          : "No date"}
                      </p>
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
                <MetricCell
                  value={campaign.stats.delivery_rate}
                  count={campaign.stats.delivered}
                  totalRecipients={campaign.stats.recipients}
                  isSMS={campaign.channel === 'sms'}
                />
                <MetricCell
                  value={campaign.stats.open_rate}
                  count={campaign.stats.opens_unique}
                  totalRecipients={campaign.stats.recipients}
                  isSMS={campaign.channel === 'sms'}
                  hideForSMS={true}
                />
                <MetricCell
                  value={campaign.stats.click_rate}
                  count={campaign.stats.clicks_unique}
                  totalRecipients={campaign.stats.recipients}
                  isSMS={campaign.channel === 'sms'}
                />
                <MetricCell
                  value={campaign.stats.click_to_open_rate}
                  count={campaign.stats.clicks_unique}
                  totalRecipients={campaign.stats.opens_unique}
                  isSMS={campaign.channel === 'sms'}
                  hideForSMS={true}
                />
                <MetricCell
                  value={campaign.stats.conversion_value}
                  count={campaign.stats.conversion_uniques}
                  isMonetary={true}
                  showConversionRate={true}
                  totalRecipients={campaign.stats.recipients}
                  isSMS={campaign.channel === 'sms'}
                />
              </tr>
            ))}
          </tbody>
        </table>
      </CardContent>
    </Card>
  );
};

export default KlaviyoCampaigns; 