import { EmptyState } from "@/components/ui/EmptyState";
import { audienceDemographicsUnavailableDescription } from "@/lib/audience-country";
import { cn } from "@/lib/cn";
import { formatCount } from "@/lib/format";
import type {
  SocialDataDemographicCategory,
  SocialDataDemographicItem,
  SocialDataDemographics,
} from "@/types/social-data";

function formatPercentage(value: number): string {
  const rounded = Math.round(value * 10) / 10;
  return Number.isInteger(rounded) ? `${rounded}%` : `${rounded.toFixed(1)}%`;
}

export function DemographicBar({ item }: { item: SocialDataDemographicItem }) {
  const width = Math.max(0, Math.min(100, item.percentage));
  const countLabel =
    item.audience_count !== null && item.audience_count !== undefined
      ? formatCount(item.audience_count)
      : null;

  return (
    <div className="group">
      <div className="flex items-center justify-between gap-3">
        <span className="min-w-0 truncate text-[0.86rem] text-primary">{item.label}</span>
        <span className="shrink-0 text-[0.82rem] font-semibold tabular-nums text-ink-60">
          {formatPercentage(item.percentage)}
          {countLabel ? <span className="ml-1.5 font-normal text-ink-40">({countLabel})</span> : null}
        </span>
      </div>
      <div className="mt-2 h-2 overflow-hidden rounded-full bg-line" aria-hidden="true">
        <div
          className="h-full rounded-full bg-accent transition-[width] duration-500 ease-out motion-reduce:transition-none"
          style={{ width: `${width}%` }}
        />
      </div>
    </div>
  );
}

function DemographicCategory({
  title,
  description,
  items,
  compact = false,
}: {
  title: string;
  description?: string;
  items: SocialDataDemographicItem[];
  compact?: boolean;
}) {
  return (
    <div className={cn(!compact && "rounded-pv border border-line bg-bg p-3")}>
      <h5 className="text-[0.8125rem] font-semibold text-primary">{title}</h5>
      {description ? (
        <p className="mt-0.5 text-[0.75rem] text-ink-60">{description}</p>
      ) : null}
      <div className={cn("space-y-2.5", compact ? "mt-2.5" : "mt-3")}>
        {items.map((item) => (
          <DemographicBar key={`${title}-${item.code ?? item.label}`} item={item} />
        ))}
      </div>
    </div>
  );
}

function OtherDemographicCategory({ category }: { category: SocialDataDemographicCategory }) {
  return <DemographicCategory title={category.category} items={category.items} />;
}

function normalizeCategoryTitle(category: string): string {
  const normalized = category.trim().toLowerCase();

  if (
    normalized.includes("country") ||
    normalized.includes("countries") ||
    normalized.includes("location") ||
    normalized.includes("region")
  ) {
    return "Audience location";
  }

  if (normalized.includes("age")) {
    return "Audience age";
  }

  if (normalized.includes("gender")) {
    return "Audience gender";
  }

  return category;
}

function DemographicsUnavailable({
  provider,
  followers,
}: {
  provider: string;
  followers?: number | null;
}) {
  return (
    <EmptyState
      variant="dashed"
      title="Audience demographics unavailable"
      description={audienceDemographicsUnavailableDescription(provider, followers)}
    />
  );
}

function sourceLabel(source: string | null | undefined, provider: string): string | null {
  if (!source) {
    return socialProviderDemographicsSource(provider);
  }

  if (source.includes("instagram")) {
    return "Instagram Insights";
  }

  if (source.includes("facebook")) {
    return "Facebook Page Insights";
  }

  return source;
}

function socialProviderDemographicsSource(provider: string): string | null {
  if (provider === "instagram") {
    return "Instagram Insights";
  }

  if (provider === "facebook") {
    return "Facebook Page Insights";
  }

  return null;
}

export function AudienceDemographicsSection({
  demographics,
  accountId,
  provider,
  followers = null,
  embedded = false,
}: {
  demographics: SocialDataDemographics | undefined;
  accountId: number;
  provider: string;
  followers?: number | null;
  /** When true, omit outer section chrome (used inside page-level panel). */
  embedded?: boolean;
}) {
  const hasAge = (demographics?.age_ranges?.length ?? 0) > 0;
  const hasGender = (demographics?.gender?.length ?? 0) > 0;
  const hasCountries = (demographics?.countries?.length ?? 0) > 0;
  const hasOther = (demographics?.other?.length ?? 0) > 0;
  const isAvailable =
    demographics?.available === true && (hasAge || hasGender || hasCountries || hasOther);
  const source = sourceLabel(demographics?.source, provider);

  return (
    <section
      className={cn(!embedded && "border-t border-line pt-4")}
      aria-labelledby={`audience-demographics-${accountId}`}
    >
      {!embedded ? (
        <div className="flex flex-wrap items-baseline justify-between gap-2">
          <div>
            <h4
              id={`audience-demographics-${accountId}`}
              className="text-[0.8125rem] font-semibold text-primary"
            >
              Audience demographics
            </h4>
            {isAvailable && source ? (
              <p className="mt-0.5 text-[0.75rem] text-ink-60">Source: {source}</p>
            ) : null}
          </div>
          {isAvailable && demographics?.captured_at ? (
            <p className="text-[0.75rem] text-ink-60">
              Updated{" "}
              {new Intl.DateTimeFormat(undefined, {
                dateStyle: "medium",
                timeStyle: "short",
              }).format(new Date(demographics.captured_at))}
            </p>
          ) : null}
        </div>
      ) : (
        <div className="flex flex-wrap items-baseline justify-between gap-2">
          <p id={`audience-demographics-${accountId}`} className="sr-only">
            Audience demographics
          </p>
          {isAvailable && source ? (
            <p className="text-[0.75rem] text-ink-60">Source: {source}</p>
          ) : (
            <span />
          )}
          {isAvailable && demographics?.captured_at ? (
            <p className="text-[0.75rem] text-ink-60">
              Updated{" "}
              {new Intl.DateTimeFormat(undefined, {
                dateStyle: "medium",
                timeStyle: "short",
              }).format(new Date(demographics.captured_at))}
            </p>
          ) : null}
        </div>
      )}

      <div
        className={cn(
          embedded ? "mt-2" : "mt-3",
          isAvailable ? "grid gap-4 sm:grid-cols-2 lg:grid-cols-3" : "",
        )}
      >
        {!isAvailable ? (
          <DemographicsUnavailable provider={provider} followers={followers} />
        ) : (
          <>
            {hasCountries && demographics?.countries ? (
              <DemographicCategory
                title="Top locations"
                items={demographics.countries}
                compact={embedded}
              />
            ) : null}
            {hasAge && demographics?.age_ranges ? (
              <DemographicCategory
                title="Age distribution"
                items={demographics.age_ranges}
                compact={embedded}
              />
            ) : null}
            {hasGender && demographics?.gender ? (
              <DemographicCategory title="Gender" items={demographics.gender} compact={embedded} />
            ) : null}
            {hasOther && demographics?.other
              ? demographics.other.map((category) => (
                  <OtherDemographicCategory
                    key={category.category}
                    category={{
                      ...category,
                      category: normalizeCategoryTitle(category.category),
                    }}
                  />
                ))
              : null}
          </>
        )}
      </div>

      {isAvailable ? (
        <p className="mt-3 text-[0.7rem] leading-snug text-ink-40">
          {demographics?.percentage_basis === "segment_counts"
            ? "Percentages are calculated by Postvertise from platform-provided audience counts. Privacy-safe aggregates from the platform Insights API."
            : "Privacy-safe aggregates from the platform Insights API when available."}
        </p>
      ) : null}
    </section>
  );
}

/**
 * Show the demographics section for every provider that syncs audience metrics.
 * Unavailable platforms render an explicit empty state instead of fake charts.
 */
export function showsAudienceDemographics(provider: string): boolean {
  return ["instagram", "facebook", "tiktok", "x"].includes(provider);
}
