"use client";

import { useEffect, useId, useState, type ReactNode } from "react";
import { SocialProviderIcon } from "@/components/dashboard/SocialProviderIcon";
import { formatFollowerCount, formatMetricCount, formatMetricMoney, formatMetricPercent } from "@/lib/format";
import { cn } from "@/lib/cn";
import { accountDisplayName, socialProviderLabel } from "@/lib/social-providers";
import type { PublicSocialAccount } from "@/types/profile";

const PROVIDER_TAB_KEYS: Record<string, string> = {
  instagram: "ig",
  tiktok: "tt",
  x: "x",
  facebook: "fb",
};

function providerTabKey(provider: string): string {
  return PROVIDER_TAB_KEYS[provider] ?? provider.slice(0, 2);
}

function SocialTabIcon({ provider }: { provider: string }) {
  return <SocialProviderIcon provider={provider} className="size-[18px]" />;
}

function ShareIcon() {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" width="18" height="18" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.933-2.185 2.25 2.25 0 0 0-3.933 2.185Z" />
    </svg>
  );
}

function SaveIcon() {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" width="18" height="18" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
    </svg>
  );
}

function ReportIcon() {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" width="18" height="18" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" d="M3 3v1.5M3 21v-6m0 0 2.77-.693a9 9 0 0 1 6.208.682l.108.054a9 9 0 0 0 6.086.71l3.114-.732a48.524 48.524 0 0 1-.005-10.499l-3.11.732a9 9 0 0 1-6.085-.711l-.108-.054a9 9 0 0 0-6.208-.682L3 4.5M3 15V4.5" />
    </svg>
  );
}

function ToolButton({
  label,
  pressed,
  onClick,
  children,
}: {
  label: string;
  pressed?: boolean;
  onClick: () => void;
  children: ReactNode;
}) {
  return (
    <button
      type="button"
      aria-pressed={pressed}
      className={cn(
        "inline-flex items-center gap-1.5 rounded-pv border border-line bg-bg px-3 py-1.5 text-[0.8125rem] font-medium text-primary hover:border-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent transition-colors",
        pressed && "border-accent bg-accent/8 text-accent",
      )}
      onClick={onClick}
    >
      {children}
      <span>{label}</span>
    </button>
  );
}

export function ProfileTools({ profileKey }: { profileKey: string }) {
  const [saved, setSaved] = useState(false);
  const [share, setShare] = useState("Share");
  const [report, setReport] = useState("Report");
  const storageKey = `pv-saved:/profile:${profileKey}`;

  useEffect(() => {
    setSaved(localStorage.getItem(storageKey) === "1");
  }, [storageKey]);

  return (
    <div className="mb-4 flex shrink-0 flex-wrap items-start gap-2 sm:absolute sm:top-0 sm:right-0 sm:mb-0 sm:pt-1">
      <ToolButton
        label={share}
        onClick={() => {
          void (async () => {
            const url = window.location.href;
            if (navigator.share) {
              navigator.share({ title: document.title, url }).catch(() => {});
              return;
            }
            await navigator.clipboard.writeText(url);
            setShare("Copied");
            setTimeout(() => setShare("Share"), 1600);
          })();
        }}
      >
        <ShareIcon />
      </ToolButton>
      <ToolButton
        label={saved ? "Saved" : "Save"}
        pressed={saved}
        onClick={() => {
          const on = !saved;
          if (on) localStorage.setItem(storageKey, "1");
          else localStorage.removeItem(storageKey);
          setSaved(on);
        }}
      >
        <SaveIcon />
      </ToolButton>
      <ToolButton
        label={report}
        onClick={() => {
          if (report === "Sent") return;
          setReport("Sent");
          setTimeout(() => setReport("Report"), 1600);
        }}
      >
        <ReportIcon />
      </ToolButton>
    </div>
  );
}

function StarIcon({ filled }: { filled: boolean }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="17" height="17" aria-hidden="true" className={filled ? "text-amber-400" : "text-line"}>
      <path
        fillRule="evenodd"
        d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
        clipRule="evenodd"
      />
    </svg>
  );
}

export function ProfileStarRating({ rating }: { rating: number | null }) {
  if (typeof rating !== "number" || !Number.isFinite(rating)) {
    return null;
  }

  const rounded = Math.max(0, Math.min(5, rating));
  const fullStars = Math.round(rounded);

  return (
    <p className="mt-2 flex flex-wrap items-center gap-1.5 text-[0.9375rem]">
      <span className="inline-flex items-center gap-0.5" aria-hidden="true">
        {Array.from({ length: 5 }, (_, index) => (
          <StarIcon key={index} filled={index < fullStars} />
        ))}
      </span>
      <b className="font-semibold text-primary">{rounded.toFixed(1)}</b>
      <span className="sr-only">{rounded} out of 5 stars</span>
    </p>
  );
}

function MetricCell({
  label,
  value,
  accent = false,
}: {
  label: string;
  value: string;
  accent?: boolean;
}) {
  return (
    <div className="min-w-0">
      <p className="text-[0.6875rem] font-medium uppercase tracking-[0.08em] text-ink-40">{label}</p>
      <p className={cn("mt-1 text-[1.15rem] font-semibold tracking-[-0.02em]", accent ? "text-accent" : "text-primary")}>
        {value}
      </p>
    </div>
  );
}

function AnalyticsGrid({ account }: { account: PublicSocialAccount }) {
  const handle = accountDisplayName(account);
  const urlLabel = `${socialProviderLabel(account.provider)} URL`;

  const metrics: Array<{ label: string; value: string; accent?: boolean }> = [];

  if (account.price != null && Number.isFinite(account.price)) {
    metrics.push({ label: "Price", value: formatMetricMoney(account.price), accent: true });
  }
  if (account.followers_count != null && Number.isFinite(account.followers_count)) {
    metrics.push({ label: "Followers", value: formatMetricCount(account.followers_count) });
  }
  if (account.views != null && Number.isFinite(account.views)) {
    metrics.push({ label: "Views", value: formatMetricCount(account.views) });
  }
  if (account.cost_per_view != null && Number.isFinite(account.cost_per_view)) {
    metrics.push({ label: "Cost per view", value: formatMetricMoney(account.cost_per_view) });
  }
  if (account.engagement_rate != null && Number.isFinite(account.engagement_rate)) {
    metrics.push({
      label: "Engagement rate",
      value: formatMetricPercent(account.engagement_rate),
    });
  }
  if (account.reach != null && Number.isFinite(account.reach)) {
    metrics.push({ label: "Reach", value: formatMetricCount(account.reach) });
  }
  if (account.impressions != null && Number.isFinite(account.impressions)) {
    metrics.push({ label: "Impressions", value: formatMetricCount(account.impressions) });
  }
  if (account.reactions != null && Number.isFinite(account.reactions)) {
    metrics.push({ label: "Reactions", value: formatMetricCount(account.reactions) });
  }
  if (account.comments != null && Number.isFinite(account.comments)) {
    metrics.push({ label: "Comments", value: formatMetricCount(account.comments) });
  }
  if (account.shares != null && Number.isFinite(account.shares)) {
    metrics.push({ label: "Shares", value: formatMetricCount(account.shares) });
  }
  if (account.saves != null && Number.isFinite(account.saves)) {
    metrics.push({ label: "Saves", value: formatMetricCount(account.saves) });
  }
  if (account.follower_growth != null && Number.isFinite(account.follower_growth)) {
    metrics.push({
      label: "Follower growth",
      value: formatMetricPercent(account.follower_growth),
    });
  }
  if (account.ctr != null && Number.isFinite(account.ctr)) {
    metrics.push({ label: "CTR", value: formatMetricPercent(account.ctr) });
  }

  return (
    <div className="mt-7 grid grid-cols-2 items-start gap-x-8 gap-y-7 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
      {metrics.map((metric) => (
        <MetricCell
          key={metric.label}
          label={metric.label}
          value={metric.value}
          accent={metric.accent}
        />
      ))}
      {account.profile_url || handle ? (
        <div className="min-w-0">
          <p className="text-[0.6875rem] font-medium uppercase tracking-[0.08em] text-ink-40">{urlLabel}</p>
          {account.profile_url ? (
            <a
              href={account.profile_url}
              target="_blank"
              rel="noopener noreferrer"
              className="mt-1 inline-flex min-w-0 max-w-full items-center gap-1.5 text-[1.05rem] font-semibold tracking-[-0.02em] text-primary hover:text-accent"
            >
              <span className={cn("soc-ico", providerTabKey(account.provider))} aria-hidden="true">
                <SocialTabIcon provider={account.provider} />
              </span>
              <span className="truncate">{handle}</span>
            </a>
          ) : (
            <p className="mt-1 truncate text-[1.15rem] font-semibold tracking-[-0.02em] text-primary">
              {handle}
            </p>
          )}
        </div>
      ) : null}
    </div>
  );
}

export function ConnectedSocialTabs({ accounts }: { accounts: PublicSocialAccount[] }) {
  const baseId = useId();
  const [panel, setPanel] = useState(0);
  const active = accounts[panel] ?? accounts[0];

  useEffect(() => {
    setPanel(0);
  }, [accounts]);

  if (accounts.length === 0 || !active) {
    return null;
  }

  return (
    <>
      <ul className="socials" id={`${baseId}-analytics-tabs`} role="tablist" aria-label="Connected accounts">
        {accounts.map((account, index) => {
          const tabKey = providerTabKey(account.provider);
          const selected = panel === index;
          const followersLabel = formatFollowerCount(account.followers_count);

          return (
            <li key={`${account.provider}-${account.username ?? index}`}>
              <button
                type="button"
                role="tab"
                data-panel={tabKey}
                id={`${baseId}-tab-${tabKey}`}
                aria-controls={`${baseId}-panel-${tabKey}`}
                aria-pressed={selected}
                aria-selected={selected}
                tabIndex={selected ? 0 : -1}
                onClick={() => setPanel(index)}
                onKeyDown={(event) => {
                  if (event.key === "ArrowRight") {
                    event.preventDefault();
                    setPanel((index + 1) % accounts.length);
                  }
                  if (event.key === "ArrowLeft") {
                    event.preventDefault();
                    setPanel((index - 1 + accounts.length) % accounts.length);
                  }
                }}
              >
                <span className={cn("soc-ico", tabKey)} aria-hidden="true">
                  <SocialTabIcon provider={account.provider} />
                </span>
                <span className="soc-label">
                  <span>{socialProviderLabel(account.provider)}</span>
                  {followersLabel ? <b className="num">{followersLabel}</b> : null}
                </span>
              </button>
            </li>
          );
        })}
      </ul>
      <div
        id={`${baseId}-panel-${providerTabKey(active.provider)}`}
        role="tabpanel"
        aria-labelledby={`${baseId}-tab-${providerTabKey(active.provider)}`}
      >
        <AnalyticsGrid account={active} />
      </div>
    </>
  );
}
