import React, { useState, useEffect } from "react";
import { apiFetch } from "@/utils/api";
import { Card, CardContent } from "@/components/ui/card";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { DateTime } from "luxon";
import { BusinessRangeSelect } from "@/components/dashboard/shared/BusinessRangeSelect";
import { Button } from "@/components/ui/button";
import { Mail, MessageSquare, BookOpen } from "lucide-react";
import { CARD_STYLES } from "@/lib/dashboard/designTokens";
import {
  DashboardSectionHeader,
  DashboardErrorState,
  DashboardTable,
  TableSkeleton,
} from "@/components/dashboard/shared";

// 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);
};

// MetricCell content component for displaying campaign metrics (returns content, not <td>)
const MetricCellContent = ({
  value,
  count,
  isMonetary = false,
  showConversionRate = false,
  totalRecipients = 0,
  isSMS = false,
  hideForSMS = false,
}) => {
  if (isSMS && hideForSMS) {
    return (
      <div className="text-center">
        <div className="text-[13px] font-bold text-[#d8d4cd]">N/A</div>
        <div className="text-[10.5px] text-[#a09b92]">-</div>
      </div>
    );
  }

  return (
    <div className="text-center">
      <div className="text-[13px] font-bold tabular-nums text-[#2b2925]">
        {isMonetary ? formatCurrency(value) : formatRate(value, isSMS, hideForSMS)}
      </div>
      <div className="text-[10.5px] text-[#a09b92]">
        {count?.toLocaleString() || 0} {count === 1 ? "recipient" : "recipients"}
        {showConversionRate &&
          totalRecipients > 0 &&
          ` (${((count / totalRecipients) * 100).toFixed(2)}%)`}
      </div>
    </div>
  );
};

// Campaign name cell with tooltip
const CampaignCell = ({ campaign }) => {
  const isBlog = campaign.name?.includes("_Blog");
  const isSMS = campaign.channel === 'sms';

  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger asChild>
          <div className="cursor-default">
            <div className="flex items-center gap-2">
              {isBlog ? (
                <BookOpen className="h-4 w-4 text-muted-foreground flex-shrink-0" />
              ) : isSMS ? (
                <MessageSquare className="h-4 w-4 text-muted-foreground flex-shrink-0" />
              ) : (
                <Mail className="h-4 w-4 text-muted-foreground flex-shrink-0" />
              )}
              <div className="font-medium text-foreground">
                {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>
          </div>
        </TooltipTrigger>
        <TooltipContent
          side="top"
          className="break-words bg-card text-foreground 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>
  );
};

const KlaviyoCampaigns = ({ className }) => {
  const [campaigns, setCampaigns] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  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, direction) => {
    setSortConfig({ key, direction });
  };

  const fetchCampaigns = async () => {
    try {
      setIsLoading(true);
      const response = await apiFetch(
        `/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);
    return () => clearInterval(interval);
  }, [selectedTimeRange]);

  // 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 channels
  const filteredCampaigns = sortedCampaigns.filter(
    (campaign) => {
      const isBlog = campaign?.name?.includes("_Blog");
      const channelType = isBlog ? "blog" : campaign?.channel;
      return selectedChannels[channelType];
    }
  );

  // Column definitions for DashboardTable
  const columns = [
    {
      key: "name",
      header: "Campaign",
      sortable: true,
      sortKey: "send_time",
      render: (_, campaign) => <CampaignCell campaign={campaign} />,
    },
    {
      key: "delivery_rate",
      header: "Delivery",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.stats.delivery_rate}
          count={campaign.stats.delivered}
          totalRecipients={campaign.stats.recipients}
          isSMS={campaign.channel === 'sms'}
        />
      ),
    },
    {
      key: "open_rate",
      header: "Opens",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.stats.open_rate}
          count={campaign.stats.opens_unique}
          totalRecipients={campaign.stats.recipients}
          isSMS={campaign.channel === 'sms'}
          hideForSMS={true}
        />
      ),
    },
    {
      key: "click_rate",
      header: "Clicks",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.stats.click_rate}
          count={campaign.stats.clicks_unique}
          totalRecipients={campaign.stats.recipients}
          isSMS={campaign.channel === 'sms'}
        />
      ),
    },
    {
      key: "conversion_value",
      header: "Orders",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.stats.conversion_value}
          count={campaign.stats.conversion_uniques}
          isMonetary={true}
          showConversionRate={true}
          totalRecipients={campaign.stats.recipients}
          isSMS={campaign.channel === 'sms'}
        />
      ),
    },
  ];

  if (isLoading) {
    return (
      <Card className={`h-full ${CARD_STYLES.base}`}>
        <DashboardSectionHeader
          title="Klaviyo Campaigns"
          loading={true}
          size="large"
          actions={<div className="w-[200px]" />}
          timeSelector={<div className="w-[130px]" />}
        />
        <CardContent className="overflow-y-auto p-4 pt-3 max-h-[400px]">
          <TableSkeleton rows={15} columns={6} variant="detailed" />
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className={`h-full ${CARD_STYLES.base}`}>
      {error && (
        <DashboardErrorState
          title="Failed to load campaigns"
          message={error}
          className="mx-4 mt-3"
        />
      )}
      <DashboardSectionHeader
        title="Klaviyo Campaigns"
        size="large"
        actions={
          <div className="flex items-center gap-0.5">
            {/* When all channels are on, "active" reads as the default state so
                all three highlight; clicking one isolates it, clicking again
                resets to all. Only the isolated channel highlights then. */}
            {(() => {
              const allOn = selectedChannels.email && selectedChannels.sms && selectedChannels.blog;
              const toggle = (channel) =>
                setSelectedChannels((prev) => {
                  const onlyThis = prev[channel] && Object.values(prev).filter(Boolean).length === 1;
                  if (onlyThis) return { email: true, sms: true, blog: true };
                  return {
                    email: channel === "email",
                    sms: channel === "sms",
                    blog: channel === "blog",
                  };
                });
              return [
                { key: "email", label: "Email" },
                { key: "sms", label: "SMS" },
                { key: "blog", label: "Blog" },
              ].map(({ key, label }) => {
                const active = !allOn && selectedChannels[key];
                return (
                  <button
                    key={key}
                    type="button"
                    onClick={() => toggle(key)}
                    className={`h-7 shrink-0 rounded-full px-2.5 text-xs font-medium transition-colors ${
                      active
                        ? "bg-[#f0eeea] text-[#2b2925] hover:bg-[#eae7e2]"
                        : "text-[#a09b92] hover:bg-[#f5f3f0] hover:text-[#2b2925]"
                    }`}
                  >
                    {label}
                  </button>
                );
              });
            })()}
          </div>
        }
        timeSelector={
          <BusinessRangeSelect value={selectedTimeRange} onValueChange={setSelectedTimeRange} />
        }
      />
      <CardContent className="p-4 pt-3">
        <DashboardTable
          columns={columns}
          data={filteredCampaigns}
          getRowKey={(campaign) => campaign.id}
          sortConfig={sortConfig}
          onSort={handleSort}
          maxHeight="md"
          stickyHeader
          bordered
        />
      </CardContent>
    </Card>
  );
};

export default KlaviyoCampaigns;
