"use client";

import { useState, type ReactNode } from "react";
import { Button } from "@/components/Button";
import { AnalyticsAccountTabs } from "@/components/dashboard/AnalyticsAccountTabs";
import { DemographicBar } from "@/components/dashboard/AudienceDemographicsSection";
import { FollowerTrendChart } from "@/components/dashboard/FollowerTrendChart";
import {
  EngagementPanel,
  FollowerGrowthPanel,
  HistoricalAnalyticsSkeleton,
  HistoricalWindowControls,
} from "@/components/dashboard/HistoricalAnalyticsSection";
import { SocialAccountAvatar } from "@/components/dashboard/SocialAccountUi";
import { SyncProgressPanel, SyncStatusBadge } from "@/components/dashboard/SocialSyncStatus";
import { useHistoricalAnalytics } from "@/components/dashboard/useHistoricalAnalytics";
import { EmptyState } from "@/components/ui/EmptyState";
import { ErrorState } from "@/components/ui/ErrorState";
import { StatusBadge } from "@/components/ui/StatusBadge";
import { socialAccountsApi } from "@/lib/api";
import { cn } from "@/lib/cn";
import {
  audienceDemographicsUnavailableDescription,
  providerSupportsAudienceDemographicPanels,
} from "@/lib/audience-country";
import {
  CONTENT_LIST_COLUMN_LABELS,
  audienceOverviewMetrics,
  contentItemMetric,
  contentItemTitle,
  contentPerformanceOverview,
  demographicDimensionStates,
  demographicsAreAvailable,
  platformInsightsAreAvailable,
  platformInsightsOverview,
  platformInsightsPeriodLabel,
  type PlatformAnalyticsGroup,
  resolveSelectedAccount,
  visibleContentListColumns,
} from "@/lib/platform-analytics";
import {
  HISTORICAL_TREND_UNAVAILABLE_MESSAGE,
  selectionLabel,
} from "@/lib/historical-analytics";
import {
  buildAnalyticsAccountHeaderViewModel,
  SOCIAL_ACCOUNT_CARD_METRIC_LABELS,
  cardMetricDisplay,
  type SocialAccountCardViewModel,
} from "@/lib/social-account-card-metrics";
import {
  analyticsAccountSyncControl,
  providerSupportsOAuthReconnect,
  reconnectActionLabel,
} from "@/lib/social-auth-failure";
import { formatRelativeSyncTime } from "@/lib/social-sync-progress";
import type { SocialAccount } from "@/types/social-account";
import type { SocialAccountData } from "@/types/social-data";

function Subsection({
  id,
  title,
  description,
  children,
}: {
  id: string;
  title: string;
  description?: string;
  children: ReactNode;
}) {
  return (
    <section aria-labelledby={id} className="space-y-3 border-t border-line pt-5">
      <div>
        <h3 id={id} className="text-[0.8125rem] font-semibold tracking-[-0.01em] text-primary">
          {title}
        </h3>
        {description ? (
          <p className="mt-0.5 max-w-[52ch] text-[0.75rem] leading-snug text-ink-60">
            {description}
          </p>
        ) : null}
      </div>
      {children}
    </section>
  );
}

function MetricTile({
  label,
  display,
  unavailable,
}: {
  label: string;
  display: string;
  unavailable: boolean;
}) {
  return (
    <div className="min-w-0 rounded-pv border border-line bg-bg px-3 py-2.5">
      <dt className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">{label}</dt>
      <dd
        className={cn(
          "mt-1 tabular-nums",
          unavailable
            ? "text-[0.8125rem] font-normal text-ink-40"
            : "text-[1.0625rem] font-semibold tracking-[-0.02em] text-primary",
        )}
      >
        {display}
      </dd>
    </div>
  );
}

function formatPublishedAt(value: string | null): string {
  if (!value) {
    return "—";
  }
  try {
    return new Intl.DateTimeFormat(undefined, {
      dateStyle: "medium",
    }).format(new Date(value));
  } catch {
    return "—";
  }
}

function demographicsSourceLabel(
  source: string | null | undefined,
  provider: string,
): string | null {
  if (source?.includes("instagram")) {
    return "Instagram Insights";
  }
  if (source?.includes("facebook")) {
    return "Facebook Page Insights";
  }
  if (source) {
    return source;
  }
  if (provider === "instagram") {
    return "Instagram Insights";
  }
  if (provider === "facebook") {
    return "Facebook Page Insights";
  }
  return null;
}

function AccountHeaderMetric({
  label,
  display,
  unavailable,
}: {
  label: string;
  display: string;
  unavailable: boolean;
}) {
  return (
    <div className="min-w-0">
      <dt className="text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">{label}</dt>
      <dd
        className={cn(
          "mt-1 tabular-nums tracking-[-0.02em]",
          unavailable
            ? "text-[0.8125rem] font-normal text-ink-40"
            : "text-[1.0625rem] font-semibold text-primary",
        )}
      >
        {display}
      </dd>
    </div>
  );
}

function PlatformAccountHeader({
  account,
  listAccounts,
  platformLabel,
  isSubmitting,
  onRefresh,
}: {
  account: SocialAccountData;
  listAccounts: readonly SocialAccount[];
  platformLabel: string;
  isSubmitting: boolean;
  onRefresh: (accountId: number) => void;
}) {
  const [reconnecting, setReconnecting] = useState(false);
  const metrics: SocialAccountCardViewModel = buildAnalyticsAccountHeaderViewModel(
    listAccounts,
    account,
  );
  const syncControl = analyticsAccountSyncControl(account.sync, {
    isSubmitting,
    provider: account.provider,
  });
  const canReconnect = providerSupportsOAuthReconnect(account.provider);
  const isPending = account.sync?.status === "pending";
  const isDisabled = isPending || isSubmitting || reconnecting || !syncControl.actionable;
  const lastSynced = formatRelativeSyncTime(account.sync?.last_succeeded_at);
  const avatarAccount: SocialAccount = {
    id: account.id,
    provider: account.provider,
    username: account.username,
    display_name: account.display_name,
    profile_image_url: metrics.profileImageUrl,
    profile_url: metrics.profileUrl,
    followers_count: metrics.followers.value,
    status: account.status,
    connected_at: account.connected_at,
  };

  return (
    <header className="space-y-4">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
        <div className="flex min-w-0 items-start gap-3">
          <SocialAccountAvatar account={avatarAccount} size="default" />
          <div className="min-w-0">
            <div className="flex flex-wrap items-center gap-2">
              <h2 className="truncate text-[1.0625rem] font-semibold tracking-[-0.02em] text-primary">
                {platformLabel}
              </h2>
              <SyncStatusBadge
                status={account.sync?.status}
                failureCode={account.sync?.failure_code}
              />
            </div>
            <div className="mt-1 flex flex-wrap items-center gap-2">
              <p className="truncate text-[0.875rem] font-medium text-primary">
                {metrics.usernameDisplay}
              </p>
              {metrics.isVerified ? (
                <StatusBadge variant="success">Verified</StatusBadge>
              ) : null}
            </div>
            {metrics.profileUrl ? (
              <a
                href={metrics.profileUrl}
                target="_blank"
                rel="noopener noreferrer"
                className="mt-1.5 inline-flex items-center gap-1 text-[0.8125rem] font-medium text-accent underline-offset-2 hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              >
                View Profile
                <span aria-hidden="true">↗</span>
              </a>
            ) : (
              <p className="mt-1.5 text-[0.8125rem] text-ink-40">Profile URL unavailable</p>
            )}
            {lastSynced ? (
              <p className="mt-1 text-[0.75rem] text-ink-40">Last synced {lastSynced}</p>
            ) : (
              <p className="mt-1 text-[0.75rem] text-ink-40">Not synced yet</p>
            )}
          </div>
        </div>

        <div className="flex shrink-0 flex-wrap gap-2">
          {syncControl.kind === "reconnect" && canReconnect ? (
            <Button
              type="button"
              size="sm"
              disabled={reconnecting}
              aria-busy={reconnecting}
              aria-label={reconnectActionLabel(account.provider)}
              onClick={() => {
                if (reconnecting) {
                  return;
                }
                setReconnecting(true);
                window.location.assign(socialAccountsApi.connectStartUrl(account.provider));
              }}
            >
              {reconnecting ? "Redirecting…" : reconnectActionLabel(account.provider)}
            </Button>
          ) : syncControl.kind === "reconnect" ? null : (
            <Button
              type="button"
              variant="secondary"
              size="sm"
              disabled={isDisabled}
              aria-busy={syncControl.kind === "syncing" || syncControl.kind === "loading"}
              aria-label={
                syncControl.kind === "refresh"
                  ? `Refresh ${platformLabel} data`
                  : syncControl.kind === "retry"
                    ? `Retry ${platformLabel} sync`
                    : `${platformLabel} sync ${syncControl.label}`
              }
              onClick={() => {
                if (!syncControl.actionable) {
                  return;
                }
                onRefresh(account.id);
              }}
            >
              {syncControl.label}
            </Button>
          )}
        </div>
      </div>

      <dl className="grid grid-cols-2 gap-x-4 gap-y-3 border-t border-line pt-4 sm:grid-cols-3 lg:grid-cols-4">
        {metrics.visibleMetrics.map((key) => {
          const metric = cardMetricDisplay(metrics, key);
          return (
            <AccountHeaderMetric
              key={key}
              label={SOCIAL_ACCOUNT_CARD_METRIC_LABELS[key]}
              display={metric.display}
              unavailable={metric.unavailable}
            />
          );
        })}
      </dl>
    </header>
  );
}

function AudienceOverview({ account }: { account: SocialAccountData }) {
  const metrics = audienceOverviewMetrics(account);

  return (
    <dl className="grid grid-cols-2 gap-2 sm:grid-cols-3">
      <MetricTile
        label="Followers"
        display={metrics.followers.display}
        unavailable={metrics.followers.unavailable}
      />
      <MetricTile
        label="Follower growth"
        display={metrics.followerGrowth.display}
        unavailable={metrics.followerGrowth.unavailable}
      />
      <MetricTile
        label="Following"
        display={metrics.following.display}
        unavailable={metrics.following.unavailable}
      />
    </dl>
  );
}

function PlatformInsightsOverview({ account }: { account: SocialAccountData }) {
  if (!platformInsightsAreAvailable(account)) {
    return (
      <EmptyState
        variant="dashed"
        title="Platform Insights unavailable"
        description="Account-level reach, views, and engagement appear here when the provider returns Insights for this account."
      />
    );
  }

  const metrics = platformInsightsOverview(account);
  const period = platformInsightsPeriodLabel(account);
  const capturedAt = account.analytics?.captured_at;

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-baseline justify-between gap-2">
        {period ? (
          <p className="text-[0.75rem] text-ink-60">Period: {period}</p>
        ) : (
          <span />
        )}
        {capturedAt ? (
          <p className="text-[0.75rem] text-ink-60">
            Updated{" "}
            {new Intl.DateTimeFormat(undefined, {
              dateStyle: "medium",
              timeStyle: "short",
            }).format(new Date(capturedAt))}
          </p>
        ) : null}
      </div>
      <dl className="grid grid-cols-2 gap-2 sm:grid-cols-3">
        {metrics.map((entry) => (
          <MetricTile
            key={entry.key}
            label={entry.label}
            display={entry.metric.display}
            unavailable={entry.metric.unavailable}
          />
        ))}
      </dl>
    </div>
  );
}

function ContentPerformanceOverview({ account }: { account: SocialAccountData }) {
  const metrics = contentPerformanceOverview(account);

  return (
    <dl className="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4">
      {metrics.map((entry) => (
        <MetricTile
          key={entry.key}
          label={entry.label}
          display={entry.metric.display}
          unavailable={entry.metric.unavailable}
        />
      ))}
    </dl>
  );
}

function RecentContentList({ account }: { account: SocialAccountData }) {
  const items = account.content?.recent_items ?? [];
  const columns = visibleContentListColumns(items);

  if (!account.capabilities.includes("content") || items.length === 0) {
    return (
      <EmptyState
        variant="dashed"
        title="No recent content"
        description="Synced posts appear here when the provider returns content metrics."
      />
    );
  }

  return (
    <div className="overflow-hidden rounded-pv border border-line">
      <div className="overflow-x-auto">
        <table className="min-w-full border-collapse text-left">
          <thead>
            <tr className="border-b border-line bg-bg">
              <th className="px-3 py-2.5 text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                Content
              </th>
              <th className="px-3 py-2.5 text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40">
                Published
              </th>
              {columns.map((column) => (
                <th
                  key={column}
                  className="px-3 py-2.5 text-[0.6875rem] font-medium uppercase tracking-[0.06em] text-ink-40"
                >
                  {CONTENT_LIST_COLUMN_LABELS[column]}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {items.map((item) => {
              const title = contentItemTitle(item);
              return (
                <tr
                  key={item.external_content_id}
                  className="border-b border-line last:border-b-0"
                >
                  <td className="max-w-[16rem] px-3 py-3 align-top">
                    <div className="flex items-start gap-2.5">
                      {item.thumbnail_url ? (
                        <img
                          src={item.thumbnail_url}
                          alt=""
                          className="size-10 shrink-0 rounded object-cover"
                        />
                      ) : (
                        <span className="flex size-10 shrink-0 items-center justify-center rounded bg-bg text-[0.625rem] font-medium uppercase text-ink-40">
                          Media
                        </span>
                      )}
                      <div className="min-w-0">
                        {item.permalink ? (
                          <a
                            href={item.permalink}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="text-[0.8125rem] font-medium text-primary underline-offset-2 hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
                          >
                            {title}
                          </a>
                        ) : (
                          <p className="text-[0.8125rem] font-medium text-primary">{title}</p>
                        )}
                        <p className="mt-0.5 text-[0.6875rem] text-ink-40">{item.content_type}</p>
                      </div>
                    </div>
                  </td>
                  <td className="whitespace-nowrap px-3 py-3 align-top text-[0.8125rem] text-ink-60">
                    {formatPublishedAt(item.published_at)}
                  </td>
                  {columns.map((column) => {
                    const metric = contentItemMetric(item, column);
                    return (
                      <td
                        key={column}
                        className={cn(
                          "px-3 py-3 align-top text-[0.8125rem] tabular-nums",
                          metric.unavailable ? "text-ink-40" : "font-medium text-primary",
                        )}
                      >
                        {metric.display}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      <p className="border-t border-line px-3 py-2 text-[0.6875rem] text-ink-40">
        Dash means unavailable · 0 means explicitly zero
      </p>
    </div>
  );
}

function PlatformDemographics({ account }: { account: SocialAccountData }) {
  const dimensions = demographicDimensionStates(account);
  const available = demographicsAreAvailable(account);
  const source = demographicsSourceLabel(account.demographics?.source, account.provider);
  const capturedAt = account.demographics?.captured_at;

  if (!available) {
    return (
      <EmptyState
        variant="dashed"
        title="Audience demographics unavailable"
        description={audienceDemographicsUnavailableDescription(
          account.provider,
          account.audience?.followers,
        )}
      />
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-baseline justify-between gap-2">
        {source ? <p className="text-[0.75rem] text-ink-60">Source: {source}</p> : <span />}
        {capturedAt ? (
          <p className="text-[0.75rem] text-ink-60">
            Updated{" "}
            {new Intl.DateTimeFormat(undefined, {
              dateStyle: "medium",
              timeStyle: "short",
            }).format(new Date(capturedAt))}
          </p>
        ) : null}
      </div>

      <div className="grid gap-4 sm:grid-cols-2">
        {dimensions.map((dimension) => (
          <div key={dimension.key} className="rounded-pv border border-line bg-bg p-3">
            <h4 className="text-[0.8125rem] font-semibold text-primary">{dimension.label}</h4>
            {dimension.available && dimension.items?.length ? (
              <div className="mt-3 space-y-2.5">
                {dimension.items.map((item) => (
                  <DemographicBar
                    key={`${dimension.key}-${item.label}`}
                    item={{
                      label: item.label,
                      percentage: item.percentage,
                      audience_count: item.audience_count,
                    }}
                  />
                ))}
              </div>
            ) : (
              <p className="mt-3 text-[0.8125rem] text-ink-40">Unavailable</p>
            )}
          </div>
        ))}
      </div>

      <p className="text-[0.7rem] leading-snug text-ink-40">
        {account.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>
    </div>
  );
}

function PlatformHistoricalBlocks({
  accountId,
  platformLabel,
}: {
  accountId: number;
  platformLabel: string;
}) {
  const historical = useHistoricalAnalytics(accountId);
  const {
    preset,
    customFrom,
    customTo,
    setCustomFrom,
    setCustomTo,
    appliedCustom,
    selectPreset,
    applyCustomRange,
    validationError,
    derived,
    history,
    historyFailed,
    isLoading,
    error,
    retry,
  } = historical;

  const truncated = history?.meta.truncated === true;
  const rangeLabel =
    preset !== "custom" || derived ? ` · ${selectionLabel(preset, appliedCustom)}` : "";

  return (
    <>
      <Subsection
        id={`growth-${accountId}`}
        title="Growth"
        description={`Follower growth for the selected date range${rangeLabel}. Missing days are not filled in.`}
      >
        <HistoricalWindowControls
          preset={preset}
          customFrom={customFrom}
          customTo={customTo}
          validationError={validationError}
          disabled={isLoading}
          onSelectPreset={selectPreset}
          onCustomFromChange={setCustomFrom}
          onCustomToChange={setCustomTo}
          onApplyCustom={applyCustomRange}
          platformLabel={platformLabel}
        />

        {isLoading ? <HistoricalAnalyticsSkeleton /> : null}

        {error ? (
          <ErrorState
            title="Unable to load growth analytics"
            message={error}
            onRetry={retry}
            className="!shadow-none"
          />
        ) : null}

        {!isLoading && !error && derived ? (
          <div className="space-y-3">
            <FollowerGrowthPanel data={derived} />
            {historyFailed ? (
              <ErrorState
                title={HISTORICAL_TREND_UNAVAILABLE_MESSAGE}
                message="Period growth metrics above are still available. Try again to load the follower trend."
                onRetry={retry}
                className="!shadow-none"
              />
            ) : (
              <>
                <FollowerTrendChart
                  points={history?.series.followers ?? []}
                  platformLabel={platformLabel}
                />
                {truncated ? (
                  <p className="text-[0.75rem] text-ink-40" role="status">
                    Showing the most recent available observations.
                  </p>
                ) : null}
              </>
            )}
          </div>
        ) : null}

        {!isLoading && !error && !derived && preset === "custom" ? (
          <p className="rounded-pv border border-dashed border-line bg-bg px-3 py-4 text-[0.8125rem] text-ink-60">
            Choose a custom date range and press Apply to load growth analytics.
          </p>
        ) : null}
      </Subsection>

      <Subsection
        id={`engagement-${accountId}`}
        title="Engagement"
        description="Historical engagement metrics for the selected period. Averages appear only when backed by API data."
      >
        {isLoading ? (
          <div className="space-y-3" aria-busy="true">
            <div className="h-32 animate-pulse rounded-pv bg-line/60" />
          </div>
        ) : null}

        {error ? (
          <ErrorState
            title="Unable to load engagement analytics"
            message={error}
            onRetry={retry}
            className="!shadow-none"
          />
        ) : null}

        {!isLoading && !error && derived ? <EngagementPanel data={derived} /> : null}

        {!isLoading && !error && !derived && preset === "custom" ? (
          <p className="rounded-pv border border-dashed border-line bg-bg px-3 py-4 text-[0.8125rem] text-ink-60">
            Apply a custom date range to load engagement analytics.
          </p>
        ) : null}

        {!isLoading && !error && !derived && preset !== "custom" ? (
          <EmptyState
            variant="dashed"
            title="Engagement unavailable"
            description="No historical engagement data is available for this period."
          />
        ) : null}
      </Subsection>
    </>
  );
}

export function PlatformAnalyticsSection({
  group,
  listAccounts,
  selectedAccountId,
  onSelectAccount,
  syncingId,
  onRefreshAccount,
}: {
  group: PlatformAnalyticsGroup;
  listAccounts: readonly SocialAccount[];
  selectedAccountId: number | null;
  onSelectAccount: (accountId: number) => void;
  syncingId: number | null;
  onRefreshAccount: (accountId: number) => void;
}) {
  const selected = resolveSelectedAccount(group.accounts, selectedAccountId);
  if (!selected) {
    return null;
  }

  const headingId = `${group.sectionId}-heading`;

  return (
    <section
      id={group.sectionId}
      aria-labelledby={headingId}
      className="scroll-mt-20 space-y-0 rounded-pv border border-line bg-surface px-4 py-5 sm:px-5"
    >
      <div className="space-y-4">
        <div className="sr-only" id={headingId}>
          {group.label} analytics
        </div>

        <PlatformAccountHeader
          account={selected}
          listAccounts={listAccounts}
          platformLabel={group.label}
          isSubmitting={syncingId === selected.id}
          onRefresh={onRefreshAccount}
        />

        {group.accounts.length > 1 ? (
          <AnalyticsAccountTabs
            accounts={group.accounts}
            selectedId={selected.id}
            onSelect={onSelectAccount}
            label={`${group.label} accounts`}
          />
        ) : null}

        <SyncProgressPanel
          account={selected}
          isRefreshing={syncingId === selected.id}
          onRefresh={() => onRefreshAccount(selected.id)}
        />
      </div>

      <Subsection
        id={`audience-${selected.id}`}
        title="Audience overview"
        description="Current audience metrics from the latest successful sync."
      >
        <AudienceOverview account={selected} />
      </Subsection>

      {selected.capabilities.includes("analytics") ? (
        <Subsection
          id={`platform-insights-${selected.id}`}
          title="Platform Insights"
          description="Account-level reach, views, and engagement from the provider — not summed from recent posts."
        >
          <PlatformInsightsOverview account={selected} />
        </Subsection>
      ) : null}

      <Subsection
        id={`content-performance-${selected.id}`}
        title="Content performance"
        description="Observed content totals and Postvertise engagement rate. Unavailable values stay blank."
      >
        <ContentPerformanceOverview account={selected} />
      </Subsection>

      <PlatformHistoricalBlocks accountId={selected.id} platformLabel={group.label} />

      <Subsection
        id={`content-${selected.id}`}
        title="Content"
        description="Recent content from synced observations. Explicit zeros are shown as 0."
      >
        <RecentContentList account={selected} />
      </Subsection>

      {providerSupportsAudienceDemographicPanels(selected.provider) ? (
        <Subsection
          id={`demographics-${selected.id}`}
          title="Audience demographics"
          description="Countries, cities, age ranges, and gender when the provider exposes them."
        >
          <PlatformDemographics account={selected} />
        </Subsection>
      ) : null}
    </section>
  );
}

export { PlatformAnalyticsNav } from "@/components/dashboard/PlatformAnalyticsNav";
