"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { X } from "lucide-react";
import { useStickySidebar } from "@/lib/use-sticky-sidebar";
import { WeatherWidget } from "./WeatherWidget";
import { MarketsWidget } from "./MarketsWidget";
import { TrendingTopics } from "./RailWidgets";
import { TopFollowed } from "./TopFollowed";
import { RailFooter } from "./RailFooter";
import { NearbyWidget } from "./NearbyWidget";
import { FeedSearchBox } from "./FeedSearchBox";
import { FollowRequests } from "./FollowRequests";
import Link from "next/link";
import { Avatar } from "./Avatar";
import { useAuth } from "@/lib/auth-context";
import { slot } from "@/lib/theme-registry";
import { timeAgo } from "@/lib/utils";
import type { User } from "@/lib/types";

/** Which component each widget id draws. */
const WIDGETS: Record<string, () => React.ReactElement | null> = {
  weather: WeatherWidget,
  trending: TrendingTopics,
  topFollowed: TopFollowed,
  markets: MarketsWidget,
  nearby: NearbyWidget,
};

/** The order used when an admin hasn't arranged them. */
const DEFAULT_ORDER = [
  "weather",
  "trending",
  "topFollowed",
  "markets",
  "nearby",
];

export function RightRail() {
  /** Whether a theme has taken over the layout. */
  const themed = Boolean(slot("Shell", null as never));
  const [widgetOrder, setWidgetOrder] = useState<string[]>(DEFAULT_ORDER);

  useEffect(() => {
    fetch("/api/admin/widgets")
      .then((res) => (res.ok ? res.json() : null))
      .then((d) => {
        const order: string[] = d?.order ?? DEFAULT_ORDER;
        const hidden: string[] = d?.hidden ?? [];
        setWidgetOrder(order.filter((id) => !hidden.includes(id) && WIDGETS[id]));
      })
      .catch(() => {});
  }, []);

  const railRef = useStickySidebar<HTMLElement>();
  const router = useRouter();
  const { user: me, refresh: refreshAuth } = useAuth();
  const [suggestions, setSuggestions] = useState<User[]>([]);
  const [followingIds, setFollowingIds] = useState<Set<string>>(new Set());
  const [showPremiumCard, setShowPremiumCard] = useState(true);
  const [upgrading, setUpgrading] = useState(false);
  const [premiumError, setPremiumError] = useState<string | null>(null);

  useEffect(() => {
    // Guarded, like every other fetch in this file. Without the catch a
    // dropped request -- the dev server recompiling, a flaky connection --
    // became an unhandled rejection and threw a red error overlay over the
    // whole page, for a sidebar widget that simply has nothing to show.
    // The array check is for the same reason: a route answering with an
    // error object would break the .map() below rather than render empty.
    fetch("/api/users/suggested")
      .then((r) => (r.ok ? r.json() : []))
      .then((list) => setSuggestions(Array.isArray(list) ? list : []))
      .catch(() => {});
    setShowPremiumCard(localStorage.getItem("xrcoin-dismissed-premium-card") !== "true");
  }, []);

  function dismissPremiumCard() {
    setShowPremiumCard(false);
    localStorage.setItem("xrcoin-dismissed-premium-card", "true");
  }

  async function upgrade() {
    setUpgrading(true);
    setPremiumError(null);
    const res = await fetch("/api/premium", { method: "POST" }).catch(() => null);
    setUpgrading(false);
    if (!res || !res.ok) {
      const data = res ? await res.json().catch(() => ({})) : {};
      setPremiumError(data.error || "Couldn't complete that upgrade.");
      return;
    }
    refreshAuth();
  }

  async function follow(u: User) {
    setFollowingIds((prev) => new Set(prev).add(u.id));
    await fetch(`/api/users/${u.username}/follow`, { method: "POST" }).catch(() => {});
  }



  // A theme brings its own rails. Drawing this one as well gave every
  // page two sets of widgets — the theme's and the default site's.
  if (themed) return null;

  return (
    <aside ref={railRef}
      className="rr-rail hidden lg:flex lg:flex-col sticky self-start">
      {/* Pinned to the top so it lines up with the feed header while scrolling. */}
      <div className="rr-search sticky top-0 z-40">
        <FeedSearchBox />
      </div>

      {/* People who followed you and are waiting to be followed back. */}
      <FollowRequests />

      {/* In the order an admin arranged, with anything they hid left out. */}
      {widgetOrder.map((id) => {
        const Widget = WIDGETS[id];
        return Widget ? <Widget key={id} /> : null;
      })}


      {/* Pinned to the bottom of the column, like the sidebar's footer. */}
      {showPremiumCard && !me?.premium && (
        <div className="rr-card mt-auto rounded-2xl border border-neutral-200 dark:border-neutral-800">
          <div>
            <div className="flex items-start justify-between">
              <h3 className="font-semibold text-[15px]">Upgrade to Go Premium</h3>
              <button
                onClick={dismissPremiumCard}
                className="text-neutral-400 hover:text-neutral-700"
              >
                <X size={16} />
              </button>
            </div>
            <p className="text-sm text-neutral-500 mt-1 mb-3">
              Enjoy additional benefits, zero ads, and higher priority — 500.
            </p>
            {premiumError && <p className="text-xs text-red-500 mb-2">{premiumError}</p>}
            <button
              onClick={upgrade}
              disabled={upgrading}
              className="w-full border border-neutral-300 dark:border-neutral-700 rounded-full py-2.5 text-sm font-semibold hover:bg-neutral-50 dark:hover:bg-neutral-900 disabled:opacity-50"
            >
              {upgrading ? "Upgrading…" : "Upgrade to Go Premium"}
            </button>
            <Link
              href="/premium"
              className="block text-center text-xs text-neutral-500 hover:text-neutral-800 dark:hover:text-neutral-200 mt-2"
            >
              Compare Pro and Ultra
            </Link>
          </div>
        </div>
      )}

      {/* The very foot of the column, under everything else. */}
      <RailFooter />

    </aside>
  );
}
