import React, { useEffect, useMemo, useState } from "react";
import { InlineMessage, Typography } from "@komi-app/components";
import "./ReportPerformance.scss";
import { useCampaignAnalyticsQuery } from "../queries";
import { Campaign } from "types/campaigns";
import moment from "moment";
import { FLAGS, useFeatureIsOn } from "@komi-app/flags-sdk";

interface Props {
  campaignId: string;
  campaign: Campaign | undefined;
}

const CampaignReportPerformanceV2 = ({ campaignId, campaign }: Props) => {
  const { data: analytics, isLoading: isAnalyticsLoading } =
    useCampaignAnalyticsQuery(campaignId);
  const [isProcessingPeriod, setIsProcessingPeriod] = useState<boolean | null>(
    null,
  );

  const stats = useMemo(() => analytics?.stats, [analytics]);

  // Calculate the delivered count ourselves since we aren't receiving all delievered events
  const deliveredCount = useMemo(() => {
    if (!analytics?.stats) return undefined;

    return Math.max(
      analytics.stats.processed - analytics.stats.uniqueBounced,
      0,
    );
  }, [analytics]);

  useEffect(() => {
    if (campaign?.schedule.startTimestamp) {
      const processing = moment(campaign.schedule.startTimestamp).isAfter(
        moment().subtract(15, "minutes"),
      );
      setIsProcessingPeriod(processing);
    }
  }, [campaign]);

  const isLoading = useMemo(
    () => isAnalyticsLoading || isProcessingPeriod === null,
    [isAnalyticsLoading, isProcessingPeriod],
  );

  const calculateRate = (numerator: number, denominator: number) => {
    if (denominator === 0) return 0; // anything dividing by zero is zero, so we return zero instead of NaN
    return (numerator / denominator) * 100;
  };

  const rates = useMemo(() => {
    if (
      !stats ||
      isProcessingPeriod ||
      isLoading ||
      deliveredCount === undefined
    ) {
      return {
        openRate: undefined,
        clickThroughRate: undefined,
        bounceRate: undefined,
        unsubscribeRate: undefined,
      };
    }

    return {
      openRate: calculateRate(stats.uniqueOpened, deliveredCount),
      clickThroughRate: calculateRate(stats.uniqueClicked, deliveredCount),
      bounceRate: calculateRate(stats.uniqueBounced, stats.processed),
      unsubscribeRate: calculateRate(stats.unsubscribed, deliveredCount),
    };
  }, [stats, isProcessingPeriod, isLoading, deliveredCount]);

  return (
    <section className="performance-section-v2">
      <div className="performance-heading">
        <Typography.Body strong>Performance</Typography.Body>
      </div>
      {isProcessingPeriod && (
        <InlineMessage
          type="info"
          message="We’re still processing your data. You’ll be able to view campaign performance as soon as the processing is complete."
        />
      )}
      <div className="performance-tiles">
        <Tile label="Open rate" value={formatPercent(rates.openRate)} />
        <Tile
          label="Click-through rate"
          value={formatPercent(rates.clickThroughRate)}
        />
        <Tile label="Bounced" value={formatPercent(rates.bounceRate)} />
        <Tile
          label="Unsubscribed"
          value={formatPercent(rates.unsubscribeRate)}
        />
      </div>
    </section>
  );
};

export default CampaignReportPerformanceV2;

function formatPercent(value: number | undefined): string | undefined {
  return typeof value === "number"
    ? value.toLocaleString(undefined, { maximumFractionDigits: 2 }) + "%"
    : value;
}

function formatCount(value: number | undefined): string | undefined {
  if (value === undefined) {
    return undefined;
  }

  if (value < 1000) {
    return value.toString();
  }

  if (value < 10000) {
    return value.toLocaleString(); // 1,234 (comma)
  }

  if (value < 1000000) {
    return (value / 1000).toFixed(1) + "K"; // 12345 -> 12.3K 123456 -> 123.5K
  }

  return (value / 1000000).toFixed(1) + "M"; // 1234567 -> 1.2M 12345678 -> 12.3M
}

function Tile({ label, value }: { label: string; value: string | undefined }) {
  return (
    <div className="performance-tile">
      <div className="performance-tile-value">
        <Typography.Heading level={2}>
          {value === undefined ? "--" : value}
        </Typography.Heading>
      </div>
      <div className="performance-tile-label">
        <Typography.Body level={2} strong color="gray-700">
          {label}
        </Typography.Body>
      </div>
    </div>
  );
}
