import React, { useState, useEffect } from "react";
import { apiFetch } from "@/utils/api";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Instagram,
  Users,
  DollarSign,
  Eye,
  Repeat,
  MousePointer,
  BarChart,
  Target,
  ShoppingCart,
  MessageCircle,
} from "lucide-react";
import { CARD_STYLES } from "@/lib/dashboard/designTokens";
import {
  DashboardStatCard,
  DashboardStatCardSkeleton,
  DashboardSectionHeader,
  DashboardErrorState,
  DashboardTable,
  TableSkeleton,
} from "@/components/dashboard/shared";

// Helper functions for formatting
const formatCurrency = (value, decimalPlaces = 2) =>
  new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: decimalPlaces,
    maximumFractionDigits: decimalPlaces,
  }).format(value || 0);

const formatNumber = (value, decimalPlaces = 0) => {
  return new Intl.NumberFormat("en-US", {
    minimumFractionDigits: decimalPlaces,
    maximumFractionDigits: decimalPlaces,
  }).format(value || 0);
};

const formatPercent = (value, decimalPlaces = 2) =>
  `${(value || 0).toFixed(decimalPlaces)}%`;

// MetricCell content component (returns content, not <td>)
const MetricCellContent = ({ value, label, sublabel, isMonetary = false, isPercentage = false, decimalPlaces = 0 }) => {
  const formattedValue = isMonetary
    ? formatCurrency(value, decimalPlaces)
    : isPercentage
    ? formatPercent(value, decimalPlaces)
    : formatNumber(value, decimalPlaces);

  return (
    <div className="text-center">
      <div className="text-blue-600 dark:text-blue-400 text-lg font-semibold">
        {formattedValue}
      </div>
      {(label || sublabel) && (
        <div className="text-muted-foreground text-sm">
          {label || sublabel}
        </div>
      )}
    </div>
  );
};

const getActionValue = (campaign, actionType) => {
  if (actionType === "impressions" || actionType === "reach") {
    return campaign.metrics[actionType] || 0;
  }

  const actions = campaign.metrics.actions;
  if (Array.isArray(actions)) {
    const action = actions.find((a) => a.action_type === actionType);
    return action ? parseInt(action.value) || 0 : 0;
  }

  return 0;
};

const CampaignNameCell = ({ campaign }) => {
  const name = campaign.name;
  const isInstagram = name.startsWith("Instagram post: ");

  return (
    <div>
      <div className="font-medium text-foreground break-words min-w-[200px] max-w-[300px]">
        {isInstagram ? (
          <div className="flex items-center space-x-2">
            <Instagram className="w-4 h-4 flex-shrink-0" />
            <span>{name.replace("Instagram post: ", "")}</span>
          </div>
        ) : (
          <span>{name}</span>
        )}
      </div>
      <div className="text-sm text-muted-foreground">
        {campaign.objective}
      </div>
    </div>
  );
};

const getObjectiveAction = (campaignObjective) => {
  const objectiveMap = {
    OUTCOME_AWARENESS: { action_type: "impressions", label: "Impressions" },
    OUTCOME_ENGAGEMENT: { action_type: "post_engagement", label: "Post Engagements" },
    OUTCOME_TRAFFIC: { action_type: "link_click", label: "Link Clicks" },
    OUTCOME_LEADS: { action_type: "lead", label: "Leads" },
    OUTCOME_SALES: { action_type: "purchase", label: "Purchases" },
    MESSAGES: { action_type: "messages", label: "Messages" },
  };

  return objectiveMap[campaignObjective] || { action_type: "link_click", label: "Link Clicks" };
};

const calculateBudget = (campaign) => {
  if (campaign.daily_budget) {
    return { value: campaign.daily_budget / 100, type: "day" };
  }
  if (campaign.lifetime_budget) {
    return { value: campaign.lifetime_budget / 100, type: "lifetime" };
  }

  const adsets = campaign.adsets?.data || [];
  const dailyTotal = adsets.reduce((sum, adset) => sum + (adset.daily_budget || 0), 0);
  const lifetimeTotal = adsets.reduce((sum, adset) => sum + (adset.lifetime_budget || 0), 0);

  if (dailyTotal > 0) return { value: dailyTotal / 100, type: "day" };
  if (lifetimeTotal > 0) return { value: lifetimeTotal / 100, type: "lifetime" };

  return { value: 0, type: "day" };
};

const processMetrics = (campaign) => {
  const insights = campaign.insights?.data?.[0] || {};
  const spend = parseFloat(insights.spend || 0);
  const impressions = parseInt(insights.impressions || 0);
  const clicks = parseInt(insights.clicks || 0);
  const reach = parseInt(insights.reach || 0);
  const cpc = parseFloat(insights.cpc || 0);
  const ctr = parseFloat(insights.ctr || 0);
  const cpm = parseFloat(insights.cpm || 0);
  const frequency = parseFloat(insights.frequency || 0);

  const purchaseValue = (insights.action_values || [])
    .filter(({ action_type }) => action_type === "purchase")
    .reduce((sum, { value }) => sum + parseFloat(value || 0), 0);

  const totalPurchases = (insights.actions || [])
    .filter(({ action_type }) => action_type === "purchase")
    .reduce((sum, { value }) => sum + parseInt(value || 0), 0);

  const actionMap = new Map();
  (insights.actions || []).forEach(({ action_type, value }) => {
    const currentValue = actionMap.get(action_type) || 0;
    actionMap.set(action_type, currentValue + parseInt(value || 0));
  });

  const actions = Array.from(actionMap.entries()).map(([action_type, value]) => ({
    action_type,
    value,
  }));

  const costPerActionMap = new Map();
  (insights.cost_per_action_type || []).forEach(({ action_type, value }) => {
    costPerActionMap.set(action_type, parseFloat(value || 0));
  });

  const totalPostEngagements = actionMap.get("post_engagement") || 0;

  return {
    spend,
    impressions,
    clicks,
    reach,
    frequency,
    ctr,
    cpm,
    cpc,
    actions,
    costPerActionMap,
    purchaseValue,
    totalPurchases,
    totalPostEngagements,
  };
};

const processCampaignData = (campaign) => {
  const metrics = processMetrics(campaign);
  const budget = calculateBudget(campaign);
  const { action_type, label } = getObjectiveAction(campaign.objective);

  const costPerResult = metrics.costPerActionMap.get(action_type) || 0;

  return {
    id: campaign.id,
    name: campaign.name,
    status: campaign.status,
    objective: label,
    objectiveActionType: action_type,
    budget: budget.value,
    budgetType: budget.type,
    metrics: {
      ...metrics,
      costPerResult,
    },
  };
};

const MetaCampaigns = () => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [campaigns, setCampaigns] = useState([]);
  const [timeframe, setTimeframe] = useState("7");
  const [summaryMetrics, setSummaryMetrics] = useState(null);
  const [sortConfig, setSortConfig] = useState({
    key: "spend",
    direction: "desc",
  });

  const handleSort = (key, direction) => {
    setSortConfig({ key, direction });
  };

  const computeDateRange = (timeframe) => {
    const now = new Date();
    const easternTime = new Date(
      now.toLocaleString("en-US", { timeZone: "America/New_York" })
    );
    easternTime.setHours(0, 0, 0, 0);

    let sinceDate, untilDate;

    if (timeframe === "today") {
      sinceDate = untilDate = new Date(easternTime);
    } else {
      untilDate = new Date(easternTime);
      untilDate.setDate(untilDate.getDate() - 1);

      sinceDate = new Date(untilDate);
      sinceDate.setDate(sinceDate.getDate() - parseInt(timeframe) + 1);
    }

    return {
      since: sinceDate.toISOString().split("T")[0],
      until: untilDate.toISOString().split("T")[0],
    };
  };

  useEffect(() => {
    const fetchMetaAdsData = async () => {
      try {
        setLoading(true);
        setError(null);

        const { since, until } = computeDateRange(timeframe);

        const [campaignData, accountInsights] = await Promise.all([
          apiFetch(`/api/meta/campaigns?since=${since}&until=${until}`),
          apiFetch(`/api/meta/account-insights?since=${since}&until=${until}`)
        ]);

        const [campaignsJson, accountJson] = await Promise.all([
          campaignData.json(),
          accountInsights.json()
        ]);

        const processedCampaigns = campaignsJson.map(processCampaignData);
        const activeCampaigns = processedCampaigns.filter(c => c.metrics.spend > 0);
        setCampaigns(activeCampaigns);

        if (activeCampaigns.length > 0) {
          const totalSpend = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.spend, 0);
          const totalImpressions = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.impressions, 0);
          const totalReach = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.reach, 0);
          const totalPurchases = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.totalPurchases, 0);
          const totalPurchaseValue = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.purchaseValue, 0);
          const totalLinkClicks = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.clicks, 0);
          const totalPostEngagements = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.totalPostEngagements, 0);

          const numCampaigns = activeCampaigns.length;
          const avgFrequency = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.frequency, 0) / numCampaigns;
          const avgCpm = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.cpm, 0) / numCampaigns;
          const avgCtr = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.ctr, 0) / numCampaigns;
          const avgCpc = activeCampaigns.reduce((sum, camp) => sum + camp.metrics.cpc, 0) / numCampaigns;

          setSummaryMetrics({
            totalSpend,
            totalPurchaseValue,
            totalLinkClicks,
            totalImpressions,
            totalReach,
            totalPurchases,
            avgFrequency,
            avgCpm,
            avgCtr,
            avgCpc,
            totalPostEngagements,
            totalCampaigns: numCampaigns,
          });
        }
      } catch (err) {
        console.error("Meta Ads fetch error:", err);
        setError(`Failed to fetch Meta Ads data: ${err.message}`);
      } finally {
        setLoading(false);
      }
    };

    fetchMetaAdsData();
  }, [timeframe]);

  // Sort campaigns
  const sortedCampaigns = [...campaigns].sort((a, b) => {
    const direction = sortConfig.direction === "desc" ? -1 : 1;

    switch (sortConfig.key) {
      case "date":
        return direction * (parseInt(b.id) - parseInt(a.id));
      case "spend":
        return direction * ((a.metrics.spend || 0) - (b.metrics.spend || 0));
      case "reach":
        return direction * ((a.metrics.reach || 0) - (b.metrics.reach || 0));
      case "impressions":
        return direction * ((a.metrics.impressions || 0) - (b.metrics.impressions || 0));
      case "cpm":
        return direction * ((a.metrics.cpm || 0) - (b.metrics.cpm || 0));
      case "ctr":
        return direction * ((a.metrics.ctr || 0) - (b.metrics.ctr || 0));
      case "results":
        return direction * ((getActionValue(a, a.objectiveActionType) || 0) - (getActionValue(b, b.objectiveActionType) || 0));
      case "value":
        return direction * ((a.metrics.purchaseValue || 0) - (b.metrics.purchaseValue || 0));
      case "engagements":
        return direction * ((a.metrics.totalPostEngagements || 0) - (b.metrics.totalPostEngagements || 0));
      default:
        return 0;
    }
  });

  // Column definitions for DashboardTable
  const columns = [
    {
      key: "name",
      header: "Campaign",
      sortable: true,
      sortKey: "date",
      render: (_, campaign) => <CampaignNameCell campaign={campaign} />,
    },
    {
      key: "spend",
      header: "Spend",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.metrics.spend}
          isMonetary
          decimalPlaces={2}
          sublabel={
            campaign.budget
              ? `${formatCurrency(campaign.budget, 0)}/${campaign.budgetType}`
              : "Budget: Ad set"
          }
        />
      ),
    },
    {
      key: "reach",
      header: "Reach",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.metrics.reach}
          label={`${formatNumber(campaign.metrics.frequency, 2)}x freq`}
        />
      ),
    },
    {
      key: "impressions",
      header: "Impressions",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent value={campaign.metrics.impressions} />
      ),
    },
    {
      key: "cpm",
      header: "CPM",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.metrics.cpm}
          isMonetary
          decimalPlaces={2}
        />
      ),
    },
    {
      key: "ctr",
      header: "CTR",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.metrics.ctr}
          isPercentage
          decimalPlaces={2}
          label={`${formatCurrency(campaign.metrics.cpc, 2)} CPC`}
        />
      ),
    },
    {
      key: "results",
      header: "Results",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={getActionValue(campaign, campaign.objectiveActionType)}
          label={campaign.objective}
        />
      ),
    },
    {
      key: "value",
      header: "Value",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent
          value={campaign.metrics.purchaseValue}
          isMonetary
          decimalPlaces={2}
          sublabel={campaign.metrics.costPerResult ? `${formatCurrency(campaign.metrics.costPerResult)}/result` : null}
        />
      ),
    },
    {
      key: "engagements",
      header: "Engagements",
      align: "center",
      sortable: true,
      render: (_, campaign) => (
        <MetricCellContent value={campaign.metrics.totalPostEngagements} />
      ),
    },
  ];

  if (loading) {
    return (
      <Card className={`h-full ${CARD_STYLES.base}`}>
        <DashboardSectionHeader
          title="Meta Ads Performance"
          loading={true}
          compact
          timeSelector={<div className="w-[130px]" />}
        />
        <CardHeader className="pt-0 pb-2">
          <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-4">
            {[...Array(12)].map((_, i) => (
              <DashboardStatCardSkeleton key={i} size="compact" />
            ))}
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <TableSkeleton rows={5} columns={9} variant="detailed" />
        </CardContent>
      </Card>
    );
  }

  if (error) {
    return (
      <Card className={`h-full ${CARD_STYLES.base}`}>
        <CardContent className="p-4">
          <DashboardErrorState
            title="Failed to load Meta Ads data"
            message={error}
          />
        </CardContent>
      </Card>
    );
  }

  return (
    <Card className={`h-full ${CARD_STYLES.base}`}>
      <DashboardSectionHeader
        title="Meta Ads Performance"
        compact
        timeSelector={
          <Select value={timeframe} onValueChange={setTimeframe}>
            <SelectTrigger className="w-[130px] bg-background">
              <SelectValue placeholder="Select range" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="today">Today</SelectItem>
              <SelectItem value="7">Last 7 days</SelectItem>
              <SelectItem value="14">Last 14 days</SelectItem>
              <SelectItem value="30">Last 30 days</SelectItem>
              <SelectItem value="90">Last 90 days</SelectItem>
            </SelectContent>
          </Select>
        }
      />
      <CardHeader className="pt-0 pb-2">
        <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-4 dashboard-stagger">
          <DashboardStatCard
            title="Active Campaigns"
            value={formatNumber(summaryMetrics?.totalCampaigns)}
            icon={Target}
            iconColor="purple"
            size="compact"
          />
          <DashboardStatCard
            title="Total Spend"
            value={formatCurrency(summaryMetrics?.totalSpend, 0)}
            icon={DollarSign}
            iconColor="green"
            size="compact"
          />
          <DashboardStatCard
            title="Total Reach"
            value={formatNumber(summaryMetrics?.totalReach)}
            icon={Users}
            iconColor="blue"
            size="compact"
          />
          <DashboardStatCard
            title="Total Impressions"
            value={formatNumber(summaryMetrics?.totalImpressions)}
            icon={Eye}
            iconColor="indigo"
            size="compact"
          />
          <DashboardStatCard
            title="Avg Frequency"
            value={formatNumber(summaryMetrics?.avgFrequency, 2)}
            icon={Repeat}
            iconColor="cyan"
            size="compact"
          />
          <DashboardStatCard
            title="Total Engagements"
            value={formatNumber(summaryMetrics?.totalPostEngagements)}
            icon={MessageCircle}
            iconColor="pink"
            size="compact"
          />
          <DashboardStatCard
            title="Avg CPM"
            value={formatCurrency(summaryMetrics?.avgCpm, 2)}
            icon={DollarSign}
            iconColor="emerald"
            size="compact"
          />
          <DashboardStatCard
            title="Avg CTR"
            value={formatPercent(summaryMetrics?.avgCtr, 2)}
            icon={BarChart}
            iconColor="orange"
            size="compact"
          />
          <DashboardStatCard
            title="Avg CPC"
            value={formatCurrency(summaryMetrics?.avgCpc, 2)}
            icon={MousePointer}
            iconColor="rose"
            size="compact"
          />
          <DashboardStatCard
            title="Total Link Clicks"
            value={formatNumber(summaryMetrics?.totalLinkClicks)}
            icon={MousePointer}
            iconColor="amber"
            size="compact"
          />
          <DashboardStatCard
            title="Total Purchases"
            value={formatNumber(summaryMetrics?.totalPurchases)}
            icon={ShoppingCart}
            iconColor="teal"
            size="compact"
          />
          <DashboardStatCard
            title="Purchase Value"
            value={formatCurrency(summaryMetrics?.totalPurchaseValue, 0)}
            icon={DollarSign}
            iconColor="lime"
            size="compact"
          />
        </div>
      </CardHeader>

      <CardContent className="pl-4 mb-4">
        <DashboardTable
          columns={columns}
          data={sortedCampaigns}
          getRowKey={(campaign) => campaign.id}
          sortConfig={sortConfig}
          onSort={handleSort}
          maxHeight="md"
          stickyHeader
          bordered
        />
      </CardContent>
    </Card>
  );
};

export default MetaCampaigns;
